You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by yo...@apache.org on 2025/04/27 03:56:44 UTC

(apisix-dashboard) branch dev/next updated: feat: init project structure, upstream (#2998)

This is an automated email from the ASF dual-hosted git repository.

young pushed a commit to branch dev/next
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git


The following commit(s) were added to refs/heads/dev/next by this push:
     new e86d9d117 feat: init project structure, upstream (#2998)
e86d9d117 is described below

commit e86d9d11721f885818494b653fc1f93aaeababc8
Author: SkyeYoung <is...@outlook.com>
AuthorDate: Sun Apr 27 11:56:39 2025 +0800

    feat: init project structure, upstream (#2998)
---
 .devcontainer/Dockerfile                           |    13 +
 .../apisix_conf.yml                                |    34 +-
 .devcontainer/devcontainer.json                    |    47 +
 .devcontainer/docker-compose.yml                   |    52 +
 .github/workflows/auto-build-rpm.yml               |    86 -
 .github/workflows/backend-cli-test.yml             |    58 -
 .github/workflows/backend-e2e-test.yml             |    96 -
 .github/workflows/backend-unit-test.yml            |    74 -
 .github/workflows/deploy-with-docker.yml           |    75 -
 .github/workflows/frontend-e2e-test.yml            |   108 -
 .github/workflows/go-lint.yml                      |    54 -
 .github/workflows/license-checker.yml              |    20 -
 .github/workflows/lint.yml                         |    55 -
 .github/workflows/make-build.yaml                  |    72 -
 .github/workflows/release-test.yml                 |    98 -
 .../test-frontend-multiple-node-build.yml          |    54 -
 .gitignore                                         |    89 +-
 .husky/pre-commit                                  |     2 +
 .vscode/settings.json                              |    39 +-
 Dockerfile                                         |    68 -
 Makefile                                           |   132 -
 README.md                                          |   157 +-
 api/README.md                                      |    48 -
 api/VERSION                                        |     1 -
 api/build.sh                                       |    51 -
 api/cmd/root.go                                    |   147 -
 api/cmd/version.go                                 |    33 -
 api/conf/conf.yaml                                 |   174 -
 api/conf/customize_schema.json                     |    33 -
 api/conf/schema.json                               | 11197 ------------
 api/entry.sh                                       |    21 -
 api/go.mod                                         |    92 -
 api/go.sum                                         |   987 -
 api/internal/conf/conf.go                          |   434 -
 api/internal/conf/conf_test.go                     |    63 -
 api/internal/core/entity/entity.go                 |   315 -
 api/internal/core/entity/format.go                 |   113 -
 api/internal/core/entity/format_test.go            |   424 -
 api/internal/core/entity/interface.go              |    45 -
 api/internal/core/migrate/conflict.go              |    48 -
 api/internal/core/migrate/dataset.go               |   127 -
 api/internal/core/migrate/migrate.go               |    99 -
 api/internal/core/server/http.go                   |    71 -
 api/internal/core/server/server.go                 |   122 -
 api/internal/core/server/store.go                  |    36 -
 api/internal/core/storage/etcd.go                  |   239 -
 api/internal/core/storage/storage.go               |    51 -
 api/internal/core/storage/storage_mock.go          |   130 -
 api/internal/core/store/store.go                   |   423 -
 api/internal/core/store/store_mock.go              |    80 -
 api/internal/core/store/store_test.go              |   812 -
 api/internal/core/store/storehub.go                |   248 -
 api/internal/core/store/test_case.json             |    19 -
 api/internal/core/store/validate.go                |   362 -
 api/internal/core/store/validate_mock.go           |    35 -
 api/internal/core/store/validate_test.go           |   530 -
 api/internal/filter/authentication.go              |    91 -
 api/internal/filter/authentication_test.go         |    74 -
 api/internal/filter/cors.go                        |    56 -
 api/internal/filter/invalid_request.go             |    38 -
 api/internal/filter/invalid_request_test.go        |    30 -
 api/internal/filter/ip_filter.go                   |   109 -
 api/internal/filter/ip_filter_test.go              |    77 -
 api/internal/filter/logging.go                     |    68 -
 api/internal/filter/logging_test.go                |    49 -
 api/internal/filter/oidc.go                        |   100 -
 api/internal/filter/recover.go                     |   121 -
 api/internal/filter/request_id.go                  |    43 -
 api/internal/filter/schema.go                      |   242 -
 .../handler/authentication/authentication.go       |   108 -
 .../handler/authentication/authentication_test.go  |    70 -
 api/internal/handler/consumer/consumer.go          |   192 -
 api/internal/handler/consumer/consumer_test.go     |   461 -
 api/internal/handler/data_loader/loader/loader.go  |    44 -
 .../handler/data_loader/loader/openapi3/export.go  |    24 -
 .../handler/data_loader/loader/openapi3/import.go  |   130 -
 .../data_loader/loader/openapi3/import_test.go     |   119 -
 .../data_loader/loader/openapi3/openapi3.go        |    41 -
 api/internal/handler/data_loader/route_export.go   |   511 -
 .../handler/data_loader/route_export_test.go       |  2405 ---
 api/internal/handler/data_loader/route_import.go   |   312 -
 .../handler/data_loader/route_import_test.go       |    65 -
 api/internal/handler/global_rule/global_rule.go    |   202 -
 .../handler/global_rule/global_rule_test.go        |   354 -
 api/internal/handler/handler.go                    |   149 -
 api/internal/handler/handler_test.go               |   145 -
 api/internal/handler/healthz/healthz.go            |    40 -
 api/internal/handler/label/label.go                |   270 -
 api/internal/handler/label/label_test.go           |   377 -
 api/internal/handler/migrate/migrate.go            |   133 -
 .../handler/plugin_config/plugin_config.go         |   267 -
 .../handler/plugin_config/plugin_config_test.go    |   715 -
 api/internal/handler/proto/proto.go                |   260 -
 api/internal/handler/proto/proto_test.go           |    47 -
 api/internal/handler/route/route.go                |   614 -
 api/internal/handler/route/route_test.go           |  1667 --
 .../route_online_debug/route_online_debug.go       |   172 -
 api/internal/handler/schema/plugin.go              |    79 -
 api/internal/handler/schema/plugin_test.go         |    66 -
 api/internal/handler/schema/schema.go              |    89 -
 api/internal/handler/schema/schema_test.go         |   118 -
 api/internal/handler/server_info/server_info.go    |    89 -
 .../handler/server_info/server_info_test.go        |   222 -
 api/internal/handler/service/service.go            |   315 -
 api/internal/handler/service/service_test.go       |   941 -
 api/internal/handler/ssl/ssl.go                    |   536 -
 api/internal/handler/ssl/ssl_test.go               |   855 -
 api/internal/handler/stream_route/stream_route.go  |   186 -
 .../handler/stream_route/stream_route_test.go      |   188 -
 .../handler/system_config/system_config.go         |   109 -
 .../handler/system_config/system_config_test.go    |   258 -
 api/internal/handler/tool/tool.go                  |    50 -
 api/internal/handler/tool/tool_test.go             |    40 -
 api/internal/handler/upstream/upstream.go          |   398 -
 api/internal/handler/upstream/upstream_test.go     |  1962 --
 api/internal/log/log.go                            |   115 -
 api/internal/log/zap.go                            |   123 -
 api/internal/route.go                              |   110 -
 api/internal/utils/closer.go                       |    39 -
 api/internal/utils/consts/api_error.go             |    48 -
 api/internal/utils/consts/api_error_test.go        |    29 -
 api/internal/utils/consts/error.go                 |    59 -
 api/internal/utils/json_patch.go                   |    75 -
 api/internal/utils/json_patch_test.go              |   211 -
 api/internal/utils/pid.go                          |    59 -
 api/internal/utils/runtime/runtime.go              |    59 -
 api/internal/utils/runtime/runtime_test.go         |    54 -
 api/internal/utils/utils.go                        |   224 -
 api/internal/utils/utils_test.go                   |   130 -
 api/internal/utils/version.go                      |    39 -
 api/logs/.gitkeep                                  |     0
 api/main.go                                        |    25 -
 api/main_test.go                                   |    56 -
 api/run.sh                                         |    24 -
 api/service/apisix-dashboard.service               |     8 -
 api/test/certs/apisix.crt                          |    27 -
 api/test/certs/apisix.key                          |    39 -
 api/test/certs/mtls_ca.pem                         |    25 -
 api/test/certs/mtls_client-key.pem                 |    27 -
 api/test/certs/mtls_client.pem                     |    25 -
 api/test/certs/mtls_server-key.pem                 |    27 -
 api/test/certs/mtls_server.pem                     |    25 -
 api/test/certs/test2.crt                           |    28 -
 api/test/certs/test2.key                           |    39 -
 api/test/docker-deploy/docker-compose.yaml         |    66 -
 api/test/docker/Dockerfile                         |    61 -
 api/test/docker/apisix_config.yaml                 |    59 -
 api/test/docker/docker-compose.yaml                |   136 -
 api/test/docker/manager-api-conf.yaml              |    42 -
 api/test/docker/setup.sh                           |   157 -
 api/test/docker/upstream.conf                      |   113 -
 api/test/e2e/auth/auth_suite_test.go               |    36 -
 api/test/e2e/auth/authentication_test.go           |    56 -
 api/test/e2e/balancer/balancer_suite_test.go       |    35 -
 api/test/e2e/balancer/balancer_test.go             |   210 -
 api/test/e2e/base/base.go                          |   351 -
 api/test/e2e/base/http.go                          |   150 -
 api/test/e2e/consumer/consumer_suite_test.go       |    37 -
 api/test/e2e/consumer/consumer_test.go             |   150 -
 api/test/e2e/consumer/consumer_with_labels_test.go |   103 -
 .../consumer/consumer_with_plugin_key_auth_test.go |   118 -
 api/test/e2e/data_loader/data_loader_suite_test.go |    38 -
 api/test/e2e/data_loader/openapi3_test.go          |   322 -
 api/test/e2e/global_rule/global_rule_suite_test.go |    37 -
 api/test/e2e/global_rule/global_rule_test.go       |   200 -
 api/test/e2e/go.mod                                |    21 -
 api/test/e2e/go.sum                                |   301 -
 api/test/e2e/healthz/healthz_suite_test.go         |    34 -
 api/test/e2e/healthz/healthz_test.go               |    38 -
 .../e2e/id_compatible/id_compatible_suite_test.go  |    37 -
 api/test/e2e/id_compatible/id_crossing_test.go     |   116 -
 api/test/e2e/id_compatible/id_not_in_body_test.go  |   164 -
 api/test/e2e/id_compatible/id_using_int_test.go    |   144 -
 api/test/e2e/id_compatible/id_using_string_test.go |    99 -
 api/test/e2e/label/label_suite_test.go             |    36 -
 api/test/e2e/label/label_test.go                   |   354 -
 api/test/e2e/middlewares/gzip_test.go              |    37 -
 api/test/e2e/middlewares/invalid_request_test.go   |    42 -
 api/test/e2e/middlewares/middlewares_suite_test.go |    36 -
 api/test/e2e/migrate/migrate_suite_test.go         |    38 -
 api/test/e2e/migrate/migrate_test.go               |   317 -
 api/test/e2e/oidc/oidc_suite_test.go               |    36 -
 api/test/e2e/oidc/oidc_test.go                     |   273 -
 .../e2e/plugin_config/plugin_config_suite_test.go  |    35 -
 api/test/e2e/plugin_config/plugin_config_test.go   |   242 -
 api/test/e2e/proto/proto_suite_test.go             |    37 -
 api/test/e2e/proto/proto_test.go                   |   263 -
 api/test/e2e/route/host_test.go                    |   389 -
 api/test/e2e/route/route_export_test.go            |  2543 ---
 api/test/e2e/route/route_service_upstream_test.go  |   424 -
 api/test/e2e/route/route_suite_test.go             |    38 -
 api/test/e2e/route/route_test.go                   |   336 -
 .../e2e/route/route_with_management_fields_test.go |   475 -
 api/test/e2e/route/route_with_methods_test.go      |   350 -
 api/test/e2e/route/route_with_plugin_cors_test.go  |   222 -
 .../route/route_with_plugin_http_logger_test.go    |   238 -
 api/test/e2e/route/route_with_plugin_jwt_test.go   |   330 -
 .../route/route_with_plugin_limit_count_test.go    |   418 -
 .../route/route_with_plugin_orchestration_test.go  |   171 -
 .../e2e/route/route_with_plugin_prometheus_test.go |   134 -
 .../route/route_with_plugin_proxy_rewrite_test.go  |   180 -
 .../route/route_with_plugin_uri_blocker_test.go    |   142 -
 api/test/e2e/route/route_with_priority_test.go     |   108 -
 api/test/e2e/route/route_with_remote_addr_test.go  |   280 -
 .../e2e/route/route_with_script_luacode_test.go    |   345 -
 api/test/e2e/route/route_with_uri_uris_test.go     |   126 -
 api/test/e2e/route/route_with_vars_test.go         |   368 -
 .../route_online_debug_suite_test.go               |    37 -
 .../route_online_debug/route_online_debug_test.go  |   876 -
 api/test/e2e/schema/plugin_test.go                 |    53 -
 api/test/e2e/schema/schema_suite_test.go           |    36 -
 api/test/e2e/schema/schema_test.go                 |    79 -
 api/test/e2e/server_info/server_info_suite_test.go |    37 -
 api/test/e2e/server_info/server_info_test.go       |   125 -
 api/test/e2e/service/service_suite_test.go         |    37 -
 api/test/e2e/service/service_test.go               |   740 -
 api/test/e2e/ssl/ssl_suite_test.go                 |    37 -
 api/test/e2e/ssl/ssl_test.go                       |   291 -
 .../e2e/stream_route/stream_route_suite_test.go    |    38 -
 api/test/e2e/stream_route/stream_route_test.go     |   290 -
 .../e2e/system_config/system_config_suite_test.go  |    36 -
 api/test/e2e/system_config/system_config_test.go   |   125 -
 .../e2e/upstream/upstream_chash_hash_on_test.go    |   579 -
 .../upstream_chash_query_string_arg_xxx_test.go    |   226 -
 .../e2e/upstream/upstream_keepalive_pool_test.go   |   149 -
 api/test/e2e/upstream/upstream_priority_test.go    |   174 -
 api/test/e2e/upstream/upstream_retry_test.go       |   132 -
 api/test/e2e/upstream/upstream_suite_test.go       |    37 -
 api/test/e2e/upstream/upstream_test.go             |  1025 --
 api/test/e2e/version/version_suite_test.go         |    36 -
 api/test/e2e/version/version_test.go               |    40 -
 api/test/shell/cli_test.sh                         |   606 -
 api/test/shell/manager_smoking.sh                  |    86 -
 api/test/shell/wait_for_services.sh                |    30 -
 api/test/testdata/dag-conf.json                    |   331 -
 api/test/testdata/import/Postman-API101.yaml       |   152 -
 api/test/testdata/import/default.json              |    40 -
 api/test/testdata/import/default.yaml              |    45 -
 api/test/testdata/import/httpbin.yaml              |    36 -
 api/test/testdata/import/multi-routes.yaml         |   231 -
 api/test/testdata/import/with-plugins.yaml         |    81 -
 api/test/testdata/import/with-service-id.yaml      |    39 -
 api/test/testdata/import/with-upstream-id.yaml     |    39 -
 api/test/testdata/invalid-dag-conf.json            |    56 -
 docs/assets/images/architecture.png                |   Bin 386018 -> 0 bytes
 docs/assets/images/manager-api.png                 |   Bin 44615 -> 0 bytes
 docs/assets/images/metrics-cn.png                  |   Bin 168247 -> 0 bytes
 docs/assets/images/modules/data_loader/intro.png   |   Bin 50006 -> 0 bytes
 .../images/modules/data_loader/openapi3-1.png      |   Bin 49160 -> 0 bytes
 .../images/modules/data_loader/openapi3-2.png      |   Bin 46095 -> 0 bytes
 .../images/modules/data_loader/openapi3-3.png      |   Bin 51394 -> 0 bytes
 .../images/modules/data_loader/openapi3-4.png      |   Bin 49945 -> 0 bytes
 .../images/modules/data_loader/openapi3-5.png      |   Bin 40339 -> 0 bytes
 .../images/modules/data_loader/openapi3-6.png      |   Bin 32652 -> 0 bytes
 .../images/modules/data_loader/openapi3-7.png      |   Bin 84460 -> 0 bytes
 .../images/modules/data_loader/openapi3-8.png      |   Bin 43830 -> 0 bytes
 .../images/modules/data_loader/openapi3-9.png      |   Bin 35521 -> 0 bytes
 docs/assets/images/route-create-done-list-cn.png   |   Bin 198788 -> 0 bytes
 docs/assets/images/route-create-done-list-en.png   |   Bin 194466 -> 0 bytes
 docs/assets/images/route-create-step1-cn.png       |   Bin 249406 -> 0 bytes
 docs/assets/images/route-create-step2-cn.png       |   Bin 240242 -> 0 bytes
 docs/assets/images/route-create-step3-cn.png       |   Bin 272421 -> 0 bytes
 docs/assets/images/route-create-step4-cn.png       |   Bin 249683 -> 0 bytes
 docs/assets/images/route-debug-basic-auth.png      |   Bin 329131 -> 0 bytes
 docs/assets/images/route-debug-body-params.png     |   Bin 313153 -> 0 bytes
 docs/assets/images/route-debug-header-params.png   |   Bin 320262 -> 0 bytes
 docs/assets/images/route-debug-published.png       |   Bin 285913 -> 0 bytes
 docs/assets/images/route-debug-query-params.png    |   Bin 253434 -> 0 bytes
 docs/assets/images/route-list-en.png               |   Bin 183974 -> 0 bytes
 docs/assets/images/setting-cn.png                  |   Bin 154318 -> 0 bytes
 docs/assets/images/ssl-list-cn.png                 |   Bin 175245 -> 0 bytes
 docs/assets/images/ssl-list-en.png                 |   Bin 177151 -> 0 bytes
 docs/en/latest/FAQ.md                              |   138 -
 docs/en/latest/I18N_USER_GUIDE.md                  |   136 -
 docs/en/latest/IMPORT_OPENAPI_USER_GUIDE.md        |   446 -
 docs/en/latest/USER_GUIDE.md                       |    56 -
 docs/en/latest/api/api.md                          |   428 -
 docs/en/latest/back-end-tests.md                   |   299 -
 docs/en/latest/config.json                         |    43 -
 docs/en/latest/deploy-with-docker.md               |    86 -
 docs/en/latest/develop.md                          |    94 -
 docs/en/latest/front-end-e2e.md                    |    52 -
 docs/en/latest/install.md                          |   170 -
 docs/en/latest/modules/data_loader.md              |    75 -
 docs/en/latest/modules/data_loader/openapi3.md     |   115 -
 eslint.config.js                                   |    71 +
 index.html                                         |    13 +
 licenses/LICENSE-ant-design-pro.txt                |    21 -
 licenses/LICENSE-antvis-x6.txt                     |    21 -
 licenses/LICENSE-json.lua.txt                      |    19 -
 package.json                                       |    75 +
 pnpm-lock.yaml                                     |  7076 ++++++++
 src/assets/apisix-logo.svg                         |    15 +
 src/components/Btn.tsx                             |    12 +
 src/components/Header/LanguageMenu.tsx             |    36 +
 src/components/Header/SettingModalBtn.tsx          |    34 +
 src/components/Header/index.tsx                    |    35 +
 src/components/Navbar.tsx                          |    46 +
 src/components/form-slice/FormPartBasic.tsx        |    41 +
 .../form-slice/FormPartUpstream/FormItemNodes.tsx  |   273 +
 .../FormPartUpstream/FormSectionChecks.tsx         |   210 +
 .../FormPartUpstream/FormSectionDiscovery.tsx      |    34 +
 .../form-slice/FormPartUpstream/config.ts          |     3 +
 .../form-slice/FormPartUpstream/index.tsx          |   228 +
 .../form-slice/FormPartUpstream/schema.ts          |     9 +
 src/components/form-slice/FormSection/index.tsx    |   112 +
 .../form-slice/FormSection/style.module.css        |     7 +
 src/components/form/Btn.tsx                        |     9 +
 src/components/form/JsonInput.tsx                  |    36 +
 src/components/form/Labels.tsx                     |    87 +
 src/components/form/NumberInput.tsx                |    34 +
 src/components/form/Select.tsx                     |    34 +
 src/components/form/Switch.tsx                     |    36 +
 src/components/form/TagInput.tsx                   |    34 +
 src/components/form/TextArray.tsx                  |    33 +
 src/components/form/TextInput.tsx                  |    32 +
 src/components/form/Textarea.tsx                   |    36 +
 src/components/form/util.ts                        |    23 +
 src/components/page/PageHeader.tsx                 |    29 +
 src/config/antdConfigProvider.tsx                  |    25 +
 src/config/constant.ts                             |    10 +
 src/config/global.ts                               |    10 +
 src/config/i18n.ts                                 |    25 +
 src/config/navRoutes.ts                            |    37 +
 src/config/req.ts                                  |    43 +
 src/locales/en/common.json                         |   175 +
 src/locales/zh/common.json                         |    11 +
 src/main.tsx                                       |    31 +
 src/routeTree.gen.ts                               |   352 +
 src/routes/__root.tsx                              |    45 +
 src/routes/consumer/index.tsx                      |     9 +
 src/routes/index.tsx                               |    10 +
 src/routes/plugin-global-rules/index.tsx           |     9 +
 src/routes/route/add.tsx                           |    58 +
 src/routes/route/index.tsx                         |    88 +
 src/routes/secret/index.tsx                        |     9 +
 src/routes/service/index.tsx                       |     9 +
 src/routes/ssl/index.tsx                           |     9 +
 src/routes/upstreams/add.tsx                       |    78 +
 src/routes/upstreams/detail.$upstreamId.tsx        |    79 +
 src/routes/upstreams/index.tsx                     |   184 +
 src/styles/global.css                              |     1 +
 src/types/i18next.d.ts                             |     8 +
 src/types/router.d.ts                              |     7 +
 src/types/schema/apisix/common.ts                  |    30 +
 src/types/schema/apisix/index.ts                   |     9 +
 src/types/schema/apisix/route.ts                   |    33 +
 src/types/schema/apisix/type.ts                    |    23 +
 src/types/schema/apisix/upstream.ts                |   182 +
 src/types/schema/pageSearch.ts                     |    18 +
 src/types/vite-env.d.ts                            |     1 +
 src/utils/form-producer.ts                         |    15 +
 src/utils/producer.ts                              |    45 +
 src/utils/usePagination.ts                         |   156 +
 src/utils/zod.ts                                   |    34 +
 tsconfig.app.json                                  |    35 +
 tsconfig.json                                      |     7 +
 tsconfig.node.json                                 |    27 +
 utils/version-check.sh                             |    79 -
 vite.config.ts                                     |    64 +
 web/.editorconfig                                  |    16 -
 web/.eslintignore                                  |     5 -
 web/.eslintrc.js                                   |    55 -
 web/.husky/.gitignore                              |     1 -
 web/.husky/pre-commit                              |     5 -
 web/.prettierignore                                |    21 -
 web/.prettierrc.js                                 |    21 -
 web/.stylelintrc.js                                |    35 -
 web/config/config.ts                               |    77 -
 web/config/defaultSettings.ts                      |    75 -
 web/config/proxy.ts                                |    29 -
 web/config/routes.ts                               |   137 -
 web/copy-folder.mjs                                |    16 -
 web/cypress.config.ts                              |    64 -
 ...ate-consumer-with-api-breaker-plugin-form.cy.js |   117 -
 ...eate-consumer-with-basic-auth-plugin-form.cy.js |   117 -
 ...ate-consumer-with-limit-count-plugin-form.cy.js |   163 -
 .../create-consumer-with-proxy-mirror-form.cy.js   |   116 -
 .../consumer/create-upstream-with-cors-form.cy.js  |   117 -
 .../create-upstream-with-limit-req-form.cy.js      |   110 -
 .../e2e/consumer/create-with-limit-conn-form.cy.js |   113 -
 .../create-with-referer-restriction-form.cy.js     |   102 -
 .../e2e/consumer/create_and_delete_consumer.cy.js  |   175 -
 .../consumer/table-auto-jump-when-no-data.cy.js    |    82 -
 .../plugin/create-delete-in-drawer-plugin.cy.js    |   361 -
 .../create-route-with-plugin-orchestration.cy.js   |   130 -
 web/cypress/e2e/plugin/plugin-schema.cy.js         |   143 -
 web/cypress/e2e/rest/dashboard-smoketest.cy.js     |    37 -
 web/cypress/e2e/rest/lang-switch-language.cy.js    |    47 -
 ...mplate-create-edit-delete-plugin-template.cy.js |   131 -
 ...emplate-create-plugin-template-with-route.cy.js |   145 -
 .../proto-create_and_edit_and_delete_proto.cy.js   |    91 -
 .../rest/proto-table-auto-jump-when-no-data.cy.js  |    68 -
 .../rest/rawDataEditor-test-rawDataEditor.cy.js    |   139 -
 .../rest/service-create-edit-delete-service.cy.js  |   188 -
 ...ervice-create-service-with-chash-upstream.cy.js |   105 -
 ...e-create-service-with-not-select-upstream.cy.js |    93 -
 ...e-service-with-service-discovery-upstream.cy.js |   126 -
 .../rest/service-edit-service-with-upstream.cy.js  |   126 -
 .../e2e/rest/service-save-paginator-status.cy.js   |   120 -
 .../service-table-auto-jump-when-no-data.cy.js     |    85 -
 web/cypress/e2e/rest/settings-smoketest.cy.js      |    77 -
 web/cypress/e2e/rest/ssl-smoketest.cy.js           |    75 -
 .../rest/upstream-create_and_delete_upstream.cy.js |   342 -
 ...e_and_edit_upstream_with_custom_chash_key.cy.js |   117 -
 ...am-create_and_edit_upstream_with_no_nodes.cy.js |    81 -
 .../upstream-table-auto-jump-when-no-data.cy.js    |    83 -
 web/cypress/e2e/rest/user-login.cy.js              |    71 -
 web/cypress/e2e/rest/user-logout.cy.js             |    34 -
 web/cypress/e2e/route/batch-delete-route.cy.js     |   151 -
 .../can-skip-upstream-when-select-service-id.cy.js |   210 -
 .../route/check-route-required-field-flag.cy.js    |    51 -
 .../route/create-edit-duplicate-delete-route.cy.js |   393 -
 .../create-edit-route-with-redirect-plugin.cy.js   |   173 -
 .../e2e/route/create-route-both-use-uri-uris.cy.js |   199 -
 .../create-route-when-not-select-upsteam-id.cy.js  |   122 -
 ...e-route-with-advanced-matching-conditions.cy.js |   206 -
 .../route/create-route-with-api-breaker-form.cy.js |   126 -
 .../route/create-route-with-chash-upstream.cy.js   |   124 -
 .../e2e/route/create-route-with-cors-form.cy.js    |   179 -
 ...create-route-with-limit-count-plugin-form.cy.js |   174 -
 .../route/create-route-with-limit-req-form.cy.js   |   129 -
 .../create-route-with-proxy-mirror-form.cy.js      |   134 -
 .../create-route-with-proxy-rewrite-plugin.cy.js   |   196 -
 ...reate-route-with-referer-restriction-form.cy.js |   179 -
 ...oute-with-search-service-and-set-priority.cy.js |   180 -
 ...ate-route-with-service-discovery-upstream.cy.js |   212 -
 .../e2e/route/create-route-with-upstream.cy.js     |   169 -
 web/cypress/e2e/route/data-loader-import.cy.js     |   182 -
 web/cypress/e2e/route/search-route.cy.js           |   205 -
 .../e2e/route/table-auto-jump-when-no-data.cy.js   |    94 -
 web/cypress/fixtures/certificate.json              |    11 -
 web/cypress/fixtures/data.json                     |    41 -
 web/cypress/fixtures/export-route-dataset.json     |   172 -
 web/cypress/fixtures/import-error.txt              |     1 -
 web/cypress/fixtures/plugin-dataset.json           |  1501 --
 web/cypress/fixtures/rawDataEditor-dataset.json    |    76 -
 web/cypress/fixtures/route-json-data.json          |    32 -
 web/cypress/fixtures/selector.json                 |    78 -
 web/cypress/support/commands.js                    |   139 -
 web/cypress/support/e2e.js                         |    35 -
 web/jest.config.js                                 |    25 -
 web/jsconfig.json                                  |    10 -
 web/mock/notices.ts                                |    25 -
 web/mock/route.ts                                  |    21 -
 web/mock/user.ts                                   |    20 -
 web/package.json                                   |   164 -
 web/public/empty.svg                               |     1 -
 web/public/favicon.png                             |   Bin 85376 -> 0 bytes
 web/public/static/default-plugin.png               |   Bin 2244 -> 0 bytes
 web/src/access.ts                                  |    22 -
 web/src/app.tsx                                    |   108 -
 web/src/assets/logo.svg                            |    21 -
 web/src/components/ActionBar/ActionBar.tsx         |    74 -
 web/src/components/ActionBar/index.ts              |    19 -
 web/src/components/ActionBar/locales/en-US.ts      |    20 -
 web/src/components/ActionBar/locales/tr-TR.ts      |    20 -
 web/src/components/ActionBar/locales/zh-CN.ts      |    20 -
 web/src/components/Footer/index.tsx                |    33 -
 web/src/components/HeaderDropdown/index.less       |    40 -
 web/src/components/HeaderDropdown/index.tsx        |    43 -
 web/src/components/IconFont/IconFont.tsx           |    33 -
 web/src/components/IconFont/index.ts               |    17 -
 web/src/components/LabelsfDrawer/LabelsDrawer.tsx  |   192 -
 web/src/components/LabelsfDrawer/index.ts          |    17 -
 web/src/components/NoticeIcon/NoticeList.less      |   140 -
 web/src/components/NoticeIcon/NoticeList.tsx       |   136 -
 web/src/components/NoticeIcon/index.less           |    56 -
 web/src/components/NoticeIcon/index.tsx            |   148 -
 web/src/components/PageLoading/index.tsx           |    28 -
 web/src/components/PanelSection/index.tsx          |    44 -
 web/src/components/Plugin/Models.ts                |   197 -
 web/src/components/Plugin/PluginDetail.tsx         |   510 -
 web/src/components/Plugin/PluginPage.tsx           |   347 -
 web/src/components/Plugin/UI/api-breaker.tsx       |   275 -
 web/src/components/Plugin/UI/basic-auth.tsx        |    60 -
 web/src/components/Plugin/UI/cors.tsx              |   243 -
 web/src/components/Plugin/UI/index.ts              |    17 -
 web/src/components/Plugin/UI/limit-conn.tsx        |   141 -
 web/src/components/Plugin/UI/limit-count.tsx       |   377 -
 web/src/components/Plugin/UI/limit-req.tsx         |   124 -
 web/src/components/Plugin/UI/plugin.tsx            |    81 -
 web/src/components/Plugin/UI/proxy-mirror.tsx      |    90 -
 .../components/Plugin/UI/referer-restriction.tsx   |   224 -
 web/src/components/Plugin/data.tsx                 |   334 -
 web/src/components/Plugin/index.ts                 |    18 -
 web/src/components/Plugin/locales/en-US.ts         |   167 -
 web/src/components/Plugin/locales/tr-TR.ts         |   164 -
 web/src/components/Plugin/locales/zh-CN.ts         |   156 -
 web/src/components/Plugin/modelCode.ts             |   316 -
 web/src/components/Plugin/service.ts               |    90 -
 web/src/components/Plugin/typing.d.ts              |    42 -
 web/src/components/PluginFlow/PluginFlow.tsx       |   226 -
 .../PluginFlow/components/FlowGraph/FlowGraph.ts   |   423 -
 .../PluginFlow/components/FlowGraph/index.ts       |    17 -
 .../PluginFlow/components/FlowGraph/shapes.ts      |   160 -
 .../PluginFlow/components/Toolbar/index.tsx        |   185 -
 web/src/components/PluginFlow/constants.ts         |   289 -
 web/src/components/PluginFlow/index.ts             |    17 -
 web/src/components/PluginFlow/locales/en-US.ts     |    45 -
 web/src/components/PluginFlow/locales/tr-TR.ts     |    44 -
 web/src/components/PluginFlow/locales/zh-CN.ts     |    41 -
 web/src/components/PluginFlow/style.less           |    42 -
 web/src/components/RawDataEditor/RawDataEditor.tsx |   246 -
 web/src/components/RawDataEditor/index.tsx         |    17 -
 web/src/components/RawDataEditor/locales/en-US.ts  |    19 -
 web/src/components/RawDataEditor/locales/tr-TR.ts  |    19 -
 web/src/components/RawDataEditor/locales/zh-CN.ts  |    19 -
 web/src/components/RightContent/AvatarDropdown.tsx |   129 -
 web/src/components/RightContent/index.less         |   116 -
 web/src/components/RightContent/index.tsx          |    73 -
 web/src/components/Upstream/UpstreamForm.tsx       |   339 -
 .../Upstream/components/KeepalivePool.tsx          |    89 -
 web/src/components/Upstream/components/Nodes.tsx   |   131 -
 .../components/Upstream/components/PassHost.tsx    |   109 -
 web/src/components/Upstream/components/Retries.tsx |    38 -
 .../Upstream/components/RetryTimeout.tsx           |    41 -
 web/src/components/Upstream/components/Scheme.tsx  |   101 -
 .../Upstream/components/ServiceDiscovery.tsx       |    92 -
 .../Upstream/components/ServiceDiscoveryArgs.tsx   |    54 -
 web/src/components/Upstream/components/TLS.tsx     |   103 -
 .../components/Upstream/components/TimeUnit.tsx    |    21 -
 web/src/components/Upstream/components/Timeout.tsx |    50 -
 web/src/components/Upstream/components/Type.tsx    |   112 -
 .../Upstream/components/UpstreamSelector.tsx       |    72 -
 .../Upstream/components/UpstreamType.tsx           |    63 -
 .../components/active-check/Concurrency.tsx        |    40 -
 .../active-check/Healthy/HttpStatuses.tsx          |    79 -
 .../components/active-check/Healthy/Interval.tsx   |    58 -
 .../components/active-check/Healthy/Successes.tsx  |    55 -
 .../components/active-check/Healthy/index.ts       |    25 -
 .../Upstream/components/active-check/Host.tsx      |    53 -
 .../Upstream/components/active-check/HttpPath.tsx  |    47 -
 .../active-check/HttpsVerifyCertificate.tsx        |    44 -
 .../Upstream/components/active-check/Port.tsx      |    43 -
 .../components/active-check/ReqHeaders.tsx         |    82 -
 .../Upstream/components/active-check/Timeout.tsx   |    43 -
 .../Upstream/components/active-check/Type.tsx      |    68 -
 .../active-check/Unhealthy/HttpFailures.tsx        |    57 -
 .../active-check/Unhealthy/HttpStatuses.tsx        |    77 -
 .../components/active-check/Unhealthy/Interval.tsx |    57 -
 .../active-check/Unhealthy/TCPFailures.tsx         |    57 -
 .../components/active-check/Unhealthy/Timeouts.tsx |    42 -
 .../components/active-check/Unhealthy/index.ts     |    29 -
 .../Upstream/components/active-check/index.ts      |    39 -
 .../passive-check/Healthy/HttpStatuses.tsx         |   101 -
 .../components/passive-check/Healthy/Successes.tsx |    54 -
 .../components/passive-check/Healthy/index.ts      |    23 -
 .../Upstream/components/passive-check/Type.tsx     |    68 -
 .../passive-check/Unhealthy/HttpFailures.tsx       |    57 -
 .../passive-check/Unhealthy/HttpStatuses.tsx       |    80 -
 .../passive-check/Unhealthy/TcpFailures.tsx        |    54 -
 .../passive-check/Unhealthy/Timeouts.tsx           |    42 -
 .../components/passive-check/Unhealthy/index.ts    |    27 -
 .../Upstream/components/passive-check/index.ts     |    25 -
 web/src/components/Upstream/constant.ts            |    62 -
 web/src/components/Upstream/index.ts               |    18 -
 web/src/components/Upstream/locales/en-US.ts       |   165 -
 web/src/components/Upstream/locales/tr-TR.ts       |   166 -
 web/src/components/Upstream/locales/zh-CN.ts       |   157 -
 web/src/components/Upstream/service.ts             |   193 -
 web/src/components/Upstream/typings.d.ts           |    72 -
 web/src/constants.ts                               |    37 -
 web/src/global.less                                |   107 -
 web/src/global.tsx                                 |   106 -
 web/src/helpers.tsx                                |   207 -
 web/src/hooks/useForceIntl.ts                      |    52 -
 web/src/hooks/usePagination.ts                     |    46 -
 web/src/libs/iconfont.js                           |    86 -
 web/src/locales/en-US.ts                           |    49 -
 web/src/locales/en-US/component.ts                 |    94 -
 web/src/locales/en-US/globalHeader.ts              |    33 -
 web/src/locales/en-US/menu.ts                      |    79 -
 web/src/locales/en-US/other.ts                     |    19 -
 web/src/locales/en-US/pwa.ts                       |    22 -
 web/src/locales/en-US/setting.ts                   |    17 -
 web/src/locales/en-US/settingDrawer.ts             |    47 -
 web/src/locales/tr-TR.ts                           |    49 -
 web/src/locales/tr-TR/component.ts                 |    94 -
 web/src/locales/tr-TR/globalHeader.ts              |    33 -
 web/src/locales/tr-TR/menu.ts                      |    79 -
 web/src/locales/tr-TR/other.ts                     |    19 -
 web/src/locales/tr-TR/pwa.ts                       |    22 -
 web/src/locales/tr-TR/setting.ts                   |    17 -
 web/src/locales/tr-TR/settingDrawer.ts             |    47 -
 web/src/locales/zh-CN.ts                           |    49 -
 web/src/locales/zh-CN/component.ts                 |    89 -
 web/src/locales/zh-CN/globalHeader.ts              |    33 -
 web/src/locales/zh-CN/menu.ts                      |    76 -
 web/src/locales/zh-CN/other.ts                     |    19 -
 web/src/locales/zh-CN/pwa.ts                       |    22 -
 web/src/locales/zh-CN/setting.ts                   |    17 -
 web/src/locales/zh-CN/settingDrawer.ts             |    47 -
 web/src/manifest.json                              |    22 -
 web/src/pages/404.tsx                              |    41 -
 web/src/pages/Consumer/Create.tsx                  |   116 -
 web/src/pages/Consumer/List.tsx                    |   173 -
 web/src/pages/Consumer/components/Preview.tsx      |    38 -
 web/src/pages/Consumer/components/Step1.tsx        |    67 -
 web/src/pages/Consumer/locales/en-US.ts            |    29 -
 web/src/pages/Consumer/locales/tr-TR.ts            |    31 -
 web/src/pages/Consumer/locales/zh-CN.ts            |    27 -
 web/src/pages/Consumer/service.ts                  |    46 -
 web/src/pages/Consumer/typing.d.ts                 |    28 -
 web/src/pages/Dashboard/Dashboard.tsx              |    81 -
 web/src/pages/Dashboard/index.ts                   |    17 -
 web/src/pages/Dashboard/locales/en-US.ts           |    21 -
 web/src/pages/Dashboard/locales/tr-TR.ts           |    22 -
 web/src/pages/Dashboard/locales/zh-CN.ts           |    21 -
 web/src/pages/Dashboard/service.ts                 |    20 -
 web/src/pages/Plugin/List.tsx                      |   176 -
 web/src/pages/Plugin/PluginMarket.tsx              |    70 -
 web/src/pages/Plugin/locales/en-US.ts              |    24 -
 web/src/pages/Plugin/locales/tr-TR.ts              |    24 -
 web/src/pages/Plugin/locales/zh-CN.ts              |    24 -
 web/src/pages/Plugin/service.ts                    |    54 -
 web/src/pages/Plugin/typing.d.ts                   |    29 -
 web/src/pages/PluginTemplate/Create.tsx            |   131 -
 web/src/pages/PluginTemplate/List.tsx              |   171 -
 .../pages/PluginTemplate/components/Preview.tsx    |    38 -
 web/src/pages/PluginTemplate/components/Step1.tsx  |   117 -
 web/src/pages/PluginTemplate/service.ts            |    57 -
 web/src/pages/PluginTemplate/typing.d.ts           |    29 -
 web/src/pages/Proto/List.tsx                       |   163 -
 .../pages/Proto/components/ProtoDrawer/index.less  |    31 -
 .../pages/Proto/components/ProtoDrawer/index.tsx   |   151 -
 web/src/pages/Proto/locales/en-US.ts               |    40 -
 web/src/pages/Proto/locales/tr-TR.ts               |    40 -
 web/src/pages/Proto/locales/zh-CN.ts               |    41 -
 web/src/pages/Proto/service.ts                     |    46 -
 web/src/pages/Proto/typing.d.ts                    |    42 -
 web/src/pages/Route/Create.less                    |   134 -
 web/src/pages/Route/Create.tsx                     |   327 -
 web/src/pages/Route/List.tsx                       |   570 -
 .../Route/components/CreateStep4/CreateStep4.tsx   |    81 -
 .../pages/Route/components/CreateStep4/index.ts    |    17 -
 .../pages/Route/components/DataLoader/Import.tsx   |   264 -
 .../components/DataLoader/loader/OpenAPI3.tsx      |    41 -
 .../components/DebugViews/AuthenticationView.tsx   |   130 -
 .../Route/components/DebugViews/DebugDrawView.tsx  |   538 -
 .../components/DebugViews/DebugFormDataView.tsx    |   133 -
 .../components/DebugViews/DebugParamsView.tsx      |   115 -
 .../pages/Route/components/DebugViews/index.less   |    51 -
 web/src/pages/Route/components/DebugViews/index.ts |    20 -
 .../Route/components/ResultView/ResultView.tsx     |    47 -
 web/src/pages/Route/components/ResultView/index.ts |    17 -
 .../Route/components/Step1/MatchingRulesView.tsx   |   367 -
 web/src/pages/Route/components/Step1/MetaView.tsx  |   437 -
 .../pages/Route/components/Step1/ProxyRewrite.tsx  |   392 -
 .../Route/components/Step1/RequestConfigView.tsx   |   301 -
 web/src/pages/Route/components/Step1/index.tsx     |    41 -
 .../Route/components/Step2/RequestRewriteView.tsx  |    45 -
 web/src/pages/Route/components/Step2/index.tsx     |    23 -
 web/src/pages/Route/components/Step3/index.tsx     |   138 -
 web/src/pages/Route/constants.ts                   |   192 -
 web/src/pages/Route/index.ts                       |    16 -
 web/src/pages/Route/locales/en-US.ts               |   219 -
 web/src/pages/Route/locales/tr-TR.ts               |   221 -
 web/src/pages/Route/locales/zh-CN.ts               |   213 -
 web/src/pages/Route/service.ts                     |   124 -
 web/src/pages/Route/transform.ts                   |   404 -
 web/src/pages/Route/typing.d.ts                    |   261 -
 web/src/pages/SSL/Create.less                      |   117 -
 web/src/pages/SSL/Create.tsx                       |   116 -
 web/src/pages/SSL/List.tsx                         |   136 -
 .../pages/SSL/components/CertificateForm/index.tsx |   111 -
 .../SSL/components/CertificateUploader/index.tsx   |   112 -
 web/src/pages/SSL/components/Step1/index.tsx       |   104 -
 web/src/pages/SSL/components/Step2/index.tsx       |    33 -
 web/src/pages/SSL/locales/en-US.ts                 |    47 -
 web/src/pages/SSL/locales/tr-TR.ts                 |    47 -
 web/src/pages/SSL/locales/zh-CN.ts                 |    44 -
 web/src/pages/SSL/service.ts                       |    55 -
 web/src/pages/SSL/style.less                       |   117 -
 web/src/pages/SSL/typing.d.ts                      |    58 -
 web/src/pages/ServerInfo/List.tsx                  |   152 -
 web/src/pages/ServerInfo/index.ts                  |    17 -
 web/src/pages/ServerInfo/locales/en-US.ts          |    24 -
 web/src/pages/ServerInfo/locales/tr-TR.ts          |    24 -
 web/src/pages/ServerInfo/locales/zh-CN.ts          |    24 -
 web/src/pages/ServerInfo/service.ts                |    27 -
 web/src/pages/ServerInfo/style.less                |    47 -
 web/src/pages/ServerInfo/typing.d.ts               |    32 -
 web/src/pages/Service/Create.tsx                   |   162 -
 web/src/pages/Service/List.tsx                     |   164 -
 web/src/pages/Service/components/Preview.tsx       |    40 -
 web/src/pages/Service/components/Step1.tsx         |   150 -
 web/src/pages/Service/locales/en-US.ts             |    29 -
 web/src/pages/Service/locales/tr-TR.ts             |    29 -
 web/src/pages/Service/locales/zh-CN.ts             |    29 -
 web/src/pages/Service/service.ts                   |    51 -
 web/src/pages/Service/transform.ts                 |    31 -
 web/src/pages/Service/typing.d.ts                  |    45 -
 web/src/pages/Setting/Setting.tsx                  |   122 -
 web/src/pages/Setting/index.ts                     |    18 -
 web/src/pages/Setting/locales/en-US.ts             |    25 -
 web/src/pages/Setting/locales/tr-TR.ts             |    25 -
 web/src/pages/Setting/locales/zh-CN.ts             |    23 -
 web/src/pages/Setting/service.ts                   |    21 -
 web/src/pages/Setting/style.less                   |   127 -
 web/src/pages/Setting/typingd.d.ts                 |    21 -
 web/src/pages/Upstream/Create.tsx                  |   118 -
 web/src/pages/Upstream/List.tsx                    |   170 -
 web/src/pages/Upstream/components/Step1.tsx        |    69 -
 web/src/pages/Upstream/constants.ts                |    43 -
 web/src/pages/Upstream/index.ts                    |    18 -
 web/src/pages/Upstream/locales/en-US.ts            |   120 -
 web/src/pages/Upstream/locales/tr-TR.ts            |   122 -
 web/src/pages/Upstream/locales/zh-CN.ts            |   118 -
 web/src/pages/Upstream/service.ts                  |    51 -
 web/src/pages/Upstream/typing.d.ts                 |   106 -
 web/src/pages/User/Login.less                      |   136 -
 web/src/pages/User/Login.tsx                       |   131 -
 web/src/pages/User/Logout.tsx                      |    44 -
 .../pages/User/components/LoginMethodPassword.tsx  |   146 -
 web/src/pages/User/index.ts                        |    19 -
 web/src/pages/User/locales/en-US.ts                |    31 -
 web/src/pages/User/locales/tr-TR.ts                |    32 -
 web/src/pages/User/locales/zh-CN.ts                |    31 -
 web/src/pages/User/typing.d.ts                     |    42 -
 web/src/pages/document.ejs                         |   217 -
 web/src/services/API.d.ts                          |    40 -
 web/src/services/user.ts                           |    26 -
 web/src/typings.d.ts                               |    84 -
 web/tsconfig.json                                  |    27 -
 web/yarn.lock                                      | 17887 -------------------
 726 files changed, 10989 insertions(+), 114482 deletions(-)

diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 000000000..8168ea846
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,13 @@
+ARG VARIANT=22
+FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:${VARIANT}
+
+# [Optional] Uncomment this section to install additional OS packages.
+# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
+#     && apt-get -y install --no-install-recommends <your-package-list-here>
+
+# [Optional] Uncomment if you want to install an additional version of node using nvm
+# ARG EXTRA_NODE_VERSION=10
+# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
+
+# [Optional] Uncomment if you want to install more global node modules
+# RUN su node -c "npm install -g <your-package-list-here>"
diff --git a/api/test/docker/apisix_config2.yaml b/.devcontainer/apisix_conf.yml
similarity index 57%
rename from api/test/docker/apisix_config2.yaml
rename to .devcontainer/apisix_conf.yml
index 3fcfee198..1220d8fb2 100644
--- a/api/test/docker/apisix_config2.yaml
+++ b/.devcontainer/apisix_conf.yml
@@ -14,27 +14,23 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# If you want to set the specified configuration value, you can set the new
-# in this file. For example if you want to specify the etcd address:
-#
+
+apisix:
+  node_listen: 9080 # APISIX listening port
+  enable_ipv6: false
 
 deployment:
   admin:
-    allow_admin:
-      - 0.0.0.0/0
-  etcd:
-    host:
-      - "http://etcd:2379"
-    resync_delay: 0
+    allow_admin: # https://nginx.org/en/docs/http/ngx_http_access_module.html#allow
+      - 0.0.0.0/0 # We need to restrict ip access rules for security. 0.0.0.0/0 is for test.
 
-apisix:
-  id: "apisix-server2"
-
-nginx_config:
-  error_log_level: "debug"
-  worker_processes: "1"
+    admin_key:
+      - name: "admin"
+        key: edd1c9f034335f136f87ad84b625c8f1
+        role: admin # admin: manage all configuration data
 
-plugin_attr:
-  server-info:
-    report_interval: 60
-    report_ttl: 3600
+  etcd:
+    host: # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
+      - "http://etcd:2379" # multiple etcd address
+    prefix: "/apisix" # apisix configurations prefix
+    timeout: 30 # 30 seconds
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 000000000..c3e38ed14
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,47 @@
+{
+  "$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.base.schema.json",
+  "name": "APISIX Dashboard Dev Environment",
+  "dockerComposeFile": [
+    "./docker-compose.yml"
+  ],
+  "service": "apisix-dashboard",
+  "workspaceFolder": "/workspace",
+  "shutdownAction": "stopCompose",
+  "postCreateCommand": "pnpm i && echo '\nUse `pnpm dev` to continue'",
+  "forwardPorts": [
+    9080,
+    9180,
+    5173,
+    5174,
+    4173
+  ],
+  "portsAttributes": {
+    "5173": {
+      "label": "APISIX Dashboard",
+      "onAutoForward": "ignore"
+    },
+    "5174": {
+      "label": "APISIX Dashboard HMR WS",
+      "onAutoForward": "silent"
+    },
+    "9180": {
+      "label": "APISIX Admin API Port",
+      "onAutoForward": "notify"
+    }
+  },
+  "customizations": {
+    "vscode": {
+      "extensions": [
+        "vunguyentuan.vscode-css-variables",
+        "dbaeumer.vscode-eslint",
+        "drKnoxy.eslint-disable-snippets",
+        "esbenp.prettier-vscode",
+        "christian-kohler.path-intellisense",
+        "lokalise.i18n-ally",
+        "formulahendry.auto-close-tag",
+        "formulahendry.auto-rename-tag",
+        "github.vscode-pull-request-github"
+      ]
+    }
+  }
+}
diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml
new file mode 100644
index 000000000..901bb2a67
--- /dev/null
+++ b/.devcontainer/docker-compose.yml
@@ -0,0 +1,52 @@
+services:
+  apisix-dashboard:
+    build:
+      context: ..
+      dockerfile: .devcontainer/Dockerfile
+    command: sleep infinity
+    volumes:
+      - ..:/workspace:cached
+    networks:
+      - apisix
+    ports:
+      - '5173:5173'
+      - '5174:5174'
+
+  apisix:
+    image: 'apache/apisix:3.12.0-debian'
+    restart: always
+    volumes:
+      - ./apisix_conf.yml:/usr/local/apisix/conf/config.yaml:ro
+    depends_on:
+      - etcd
+    ports:
+      - '9180:9180/tcp'
+      - '9080:9080/tcp'
+      - '9091:9091/tcp'
+      - '9443:9443/tcp'
+    networks:
+      - apisix
+
+  etcd:
+    image: bitnami/etcd:3.4.9
+    user: root
+    restart: always
+    volumes:
+      - etcd_data:/etcd_data
+    environment:
+      ETCD_DATA_DIR: /etcd_data
+      ETCD_ENABLE_V2: 'true'
+      ALLOW_NONE_AUTHENTICATION: 'yes'
+      ETCD_ADVERTISE_CLIENT_URLS: 'http://etcd:2379'
+      ETCD_LISTEN_CLIENT_URLS: 'http://0.0.0.0:2379'
+    ports:
+      - '2379:2379/tcp'
+    networks:
+      - apisix
+
+networks:
+  apisix:
+    driver: bridge
+
+volumes:
+  etcd_data:
diff --git a/.github/workflows/auto-build-rpm.yml b/.github/workflows/auto-build-rpm.yml
deleted file mode 100644
index 63ecc2e93..000000000
--- a/.github/workflows/auto-build-rpm.yml
+++ /dev/null
@@ -1,86 +0,0 @@
-name: Auto Build RPM
-
-on:
-  push:
-    branches: [master, 'release/**']
-    paths-ignore:
-      - 'docs/**'
-  pull_request:
-    branches: [master]
-    paths-ignore:
-      - 'docs/**'
-
-jobs:
-  auto_build_rpm:
-    name: Auto Build RPM package
-    runs-on: ubuntu-latest
-
-    services:
-      etcd:
-        image: bitnami/etcd:3.5.2
-        ports:
-          - 2379:2379
-          - 2380:2380
-        env:
-          ALLOW_NONE_AUTHENTICATION: yes
-          ETCD_ADVERTISE_CLIENT_URLS: http://0.0.0.0:2379
-
-    steps:
-      - name: Check out code
-        uses: actions/checkout@v3
-
-      - uses: docker/setup-buildx-action@v2
-
-      - uses: actions/cache@v3
-        with:
-          path: /tmp/.buildx-cache
-          key: ${{ runner.os }}-buildx-apisixdashboard-${{ github.sha }}
-          restore-keys: |
-            ${{ runner.os }}-buildx-apisixdashboard-
-            ${{ runner.os }}-buildx-
-
-      - name: Extract branch name
-        id: branch_env
-        shell: bash
-        run: |
-          echo "##[set-output name=version;]$(echo ${GITHUB_REF##*/})"
-
-      - name: Build rpm package
-        run: |
-          export VERSION=${{ steps.branch_env.outputs.version }}
-          sudo gem install --no-document fpm
-          git clone https://github.com/api7/apisix-build-tools.git
-
-          # move codes under build tool
-          mkdir ./apisix-build-tools/apisix-dashboard
-          for dir in `ls|grep -v "^apisix-build-tools$"`;do cp -r $dir ./apisix-build-tools/apisix-dashboard/;done
-
-          cd apisix-build-tools
-          export checkout=master
-          if [ "$VERSION" != "merge" && "$VERSION" != "master" ];then
-            export checkout=release/${VERSION}
-          fi
-          make package type=rpm app=dashboard version=${VERSION} checkout=${checkout} image_base=centos image_tag=7 local_code_path=./apisix-dashboard buildx=True
-
-      - name: Run centos7 docker and mapping apisix into container
-        run: |
-          docker run -itd -v $PWD:/apisix-dashboard --name centos7Instance --net="host" docker.io/centos:7 /bin/bash
-
-      - name: Install rpm package
-        run: |
-          export VERSION=${{ steps.branch_env.outputs.version }}
-          docker exec centos7Instance bash -c "cd apisix-dashboard && yum install -y ./apisix-build-tools/output/apisix-dashboard-${VERSION}-0.el7.x86_64.rpm"
-          docker logs centos7Instance
-          # Dependencies are attached with rpm, so revert `make deps`
-          docker exec centos7Instance bash -c "cd /usr/local/apisix/dashboard/ && nohup ./manager-api &"
-
-      - name: Run test cases
-        run: |
-          api/test/shell/manager_smoking.sh -s true
-
-      - name: Publish Artifact
-        if: ${{ startsWith(github.ref, 'refs/heads/release/') }}
-        uses: actions/upload-artifact@v3
-        with:
-          name: "rpm"
-          path: "./apisix-build-tools/output/apisix-dashboard-${{ steps.branch_env.outputs.version }}-0.el7.x86_64.rpm"
diff --git a/.github/workflows/backend-cli-test.yml b/.github/workflows/backend-cli-test.yml
deleted file mode 100644
index bde9502de..000000000
--- a/.github/workflows/backend-cli-test.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-name: Backend CLI Test
-
-on:
-  push:
-    branches:
-      - master
-    paths:
-      - 'api/**'
-  pull_request:
-    branches:
-      - master
-    paths:
-      - 'api/**'
-
-jobs:
-  run-test:
-    runs-on: ubuntu-latest
-    strategy:
-      matrix:
-        etcd: [3.4.20]
-
-    steps:
-      - uses: actions/checkout@v3
-        with:
-          submodules: recursive
-
-      - name: setup go
-        uses: actions/setup-go@v3
-        with:
-          go-version: '1.19'
-
-      - name: cache etcd
-        id: cache-etcd
-        uses: actions/cache@v3
-        with:
-          path: |
-            ${{ github.workspace }}/api/etcd-v${{ matrix.etcd }}-linux-amd64
-          key: etcd-v${{ matrix.etcd }}-linux-amd64
-
-      - name: download etcd
-        if: ${{ steps.cache-etcd.outputs.cache-hit != 'true' }}
-        working-directory: ./api
-        run: |
-          wget https://github.com/etcd-io/etcd/releases/download/v${{ matrix.etcd }}/etcd-v${{ matrix.etcd }}-linux-amd64.tar.gz
-          tar zxvf etcd-v${{ matrix.etcd }}-linux-amd64.tar.gz
-
-      - name: install bats
-        run: |
-          git clone https://github.com/sstephenson/bats.git && cd bats
-          sudo ./install.sh /usr/local
-
-      - name: run test
-        working-directory: ./api
-        run: chmod +x ./test/shell/cli_test.sh && sudo ./test/shell/cli_test.sh
-
-      - name: tmate debugger
-        if: ${{ failure() }}
-        uses: ./.github/actions/tmate-action
diff --git a/.github/workflows/backend-e2e-test.yml b/.github/workflows/backend-e2e-test.yml
deleted file mode 100644
index 85ec37d55..000000000
--- a/.github/workflows/backend-e2e-test.yml
+++ /dev/null
@@ -1,96 +0,0 @@
-name: Backend E2E Test
-
-on:
-  push:
-    branches:
-      - master
-    paths:
-      - 'api/**'
-  pull_request:
-    branches:
-      - master
-    paths:
-      - 'api/**'
-
-concurrency:
-  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_number || github.ref }}
-  cancel-in-progress: true
-
-jobs:
-  backend-e2e-test:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v3
-        with:
-          submodules: recursive
-
-      - name: setup go
-        uses: actions/setup-go@v3
-        with:
-          go-version: "1.19"
-
-      - uses: docker/setup-buildx-action@v2
-
-      - uses: actions/cache@v3
-        with:
-          path: /tmp/.buildx-cache
-          key: ${{ runner.os }}-buildx-apisixdashboard-${{ github.sha }}
-          restore-keys: |
-            ${{ runner.os }}-buildx-apisixdashboard-
-            ${{ runner.os }}-buildx-
-
-      - name: Modify conf.yaml Configure for use by the manage-api cluster
-        run: |
-          sed -i 's/127.0.0.1:2379/etcd:2379/' ./api/conf/conf.yaml
-          sed -i 's@127.0.0.1@0.0.0.0/0@' ./api/conf/conf.yaml
-          sed -i 's@0.0.0.0/0:9000@127.0.0.1:9000@' ./api/conf/conf.yaml
-          sed -i 's/enabled: false/enabled: true/' ./api/conf/conf.yaml
-
-      - name: build docker images
-        working-directory: ./api/test/docker
-        continue-on-error: true
-        run: |
-          docker buildx bake --load \
-          -f docker-compose.yaml \
-          --set *.cache-from=type=local,src=/tmp/.buildx-cache \
-          --set *.cache-to=type=local,dest=/tmp/.buildx-cache
-
-      - name: build and start grpc_server_example
-        working-directory: ./api/test/docker
-        run: |
-          wget https://github.com/api7/grpc_server_example/archive/refs/tags/20210819.tar.gz
-          tar -xzvf 20210819.tar.gz && cd grpc_server_example-20210819
-          docker build -t grpc_server_example:latest .
-
-      - name: run docker compose
-        working-directory: ./api/test/docker
-        run: |
-          docker-compose up -d
-          sleep 5
-          docker logs docker_managerapi_1
-
-      - name: install ginkgo cli
-        run: go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo@latest
-
-      - name: run test
-        working-directory: ./api/test/e2e
-        run: |
-          go mod download
-          ginkgo -r --flake-attempts=3 -v
-
-      - name: stop docker compose
-        working-directory: ./api/test/docker
-        run: |
-          docker-compose down
-          sleep 10
-
-      - name: output test coverage
-        working-directory: ./api/test/testdata
-        run: |
-          go tool cover -func=./integrationcover.out
-
-      - name: upload coverage profile
-        working-directory: ./api/test/testdata
-        run: |
-          bash <(curl -s https://codecov.io/bash) -f ./integrationcover.out -F backend-e2e-test-ginkgo
diff --git a/.github/workflows/backend-unit-test.yml b/.github/workflows/backend-unit-test.yml
deleted file mode 100644
index ef9bdede5..000000000
--- a/.github/workflows/backend-unit-test.yml
+++ /dev/null
@@ -1,74 +0,0 @@
-name: Backend Unit Test
-
-on:
-  push:
-    branches:
-      - master
-    paths:
-      - 'api/**'
-  pull_request:
-    branches:
-      - master
-    paths:
-      - 'api/**'
-
-jobs:
-  run-test:
-    runs-on: ubuntu-latest
-
-    services:
-      etcd:
-        image: bitnami/etcd:3.5.2
-        ports:
-          - 2379:2379
-          - 2380:2380
-        env:
-          ALLOW_NONE_AUTHENTICATION: yes
-
-    steps:
-      - uses: actions/checkout@v3
-
-      - name: setup go
-        uses: actions/setup-go@v3
-        with:
-          go-version: "1.18"
-
-      - uses: actions/cache@v3
-        with:
-          path: |
-            ~/.cache/go-build
-            ~/go/pkg/mod
-          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
-          restore-keys: |
-            ${{ runner.os }}-go-
-
-      - name: run test
-        run: |
-          make api-test
-
-      - name: upload coverage profile
-        working-directory: ./api
-        run: |
-          bash <(curl -s https://codecov.io/bash) -F backend-unit-test
-
-      - name: run with custom port
-        working-directory: ./api
-        run: |
-          export GO111MOUDULE=on
-          export APISIX_CONF_PATH=$PWD/conf
-          sed -i 's/9000/8088/' conf/conf.yaml
-          go build -o ./manager-api ./main.go
-          ./manager-api > ./api.log 2>&1 &
-          sleep 2
-          cat ./api.log
-          cat conf/conf.yaml
-
-      - name: run with custom port
-        working-directory: ./api
-        run: |
-          curl http://127.0.0.1:8088/apisix/admin/user/login -X POST -i -d '{"username":"admin", "password": "admin"}'
-          code=$(curl -k -i -m 20 -o /dev/null -s -w %{http_code} http://127.0.0.1:8088/apisix/admin/user/login -X POST -i -d '{"username":"admin", "password": "admin"}')
-          if [ ! $code -eq 200 ]; then
-              echo "failed: failed to custom port"
-              exit 1
-          fi
diff --git a/.github/workflows/deploy-with-docker.yml b/.github/workflows/deploy-with-docker.yml
deleted file mode 100644
index 5568ed37f..000000000
--- a/.github/workflows/deploy-with-docker.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-name: Test and Deploy with Docker
-
-on:
-  push:
-    branches:
-      - master
-    paths-ignore:
-      - 'docs/**'
-  pull_request:
-    branches:
-      - master
-    paths-ignore:
-      - 'docs/**'
-
-concurrency:
-  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_number || github.ref }}
-  cancel-in-progress: true
-
-jobs:
-  build:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v3
-        with:
-          submodules: recursive
-
-      - uses: docker/setup-buildx-action@v2
-
-      - uses: actions/cache@v3
-        with:
-          path: /tmp/.buildx-cache
-          key: ${{ runner.os }}-buildx-apisixdashboard-${{ github.sha }}
-          restore-keys: |
-            ${{ runner.os }}-buildx-apisixdashboard-
-            ${{ runner.os }}-buildx-
-
-      - name: Build Docker Image
-        uses: docker/build-push-action@v2
-        with:
-          load: true
-          tags: dashboard:ci
-          context: .
-          cache-from: |
-            type=local,src=/tmp/.buildx-cache
-          cache-to: |
-            type=local,dest=/tmp/.buildx-cache
-
-      - name: Modify Config
-        run: |
-          sed -i 's/127.0.0.1:2379/172.16.238.10:2379/' api/conf/conf.yaml
-          sed -i 's@127.0.0.1@0.0.0.0/0@' ./api/conf/conf.yaml
-
-          # At present, the docker CI is still running the code of the master branch
-          # So we need to configure `listen.host` so that it can be accessed outside docker
-          sed -i '/port: 9000/i\    host: 0.0.0.0' ./api/conf/conf.yaml
-
-      - name: build docker images
-        working-directory: ./api/test/docker-deploy
-        continue-on-error: true
-        run: |
-          docker buildx bake --load \
-          -f docker-compose.yaml \
-          --set *.cache-from=type=local,src=/tmp/.buildx-cache \
-          --set *.cache-to=type=local,dest=/tmp/.buildx-cache
-
-      - name: Run Docker Compose
-        working-directory: ./api/test/docker-deploy
-        run: |
-          docker-compose up -d
-          sleep 5
-          docker logs docker-deploy_managerapi_1
-
-      - name: Run Test
-        run: api/test/shell/manager_smoking.sh -s false
diff --git a/.github/workflows/frontend-e2e-test.yml b/.github/workflows/frontend-e2e-test.yml
deleted file mode 100644
index 3a9830f46..000000000
--- a/.github/workflows/frontend-e2e-test.yml
+++ /dev/null
@@ -1,108 +0,0 @@
-name: Frontend e2e test
-
-on:
-  push:
-    branches:
-      - master
-    paths-ignore:
-      - 'docs/**'
-  pull_request:
-    branches:
-      - master
-    paths-ignore:
-      - 'docs/**'
-
-concurrency:
-  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_number || github.ref }}
-  cancel-in-progress: true
-
-env:
-  CYPRESS_CACHE_FOLDER: cypress/cache
-defaults:
-  run:
-    working-directory: web
-
-jobs:
-  web-e2e:
-    name: Frontend e2e test
-    strategy:
-      fail-fast: false
-      matrix:
-        folderPrefix: ['consumer', 'route', 'plugin', 'rest']
-    runs-on: ubuntu-latest
-    services:
-      etcd:
-        image: bitnami/etcd:3.5.2
-        ports:
-          - 2379:2379
-          - 2380:2380
-        env:
-          ALLOW_NONE_AUTHENTICATION: yes
-
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v3
-        with:
-          submodules: recursive
-
-      - name: Setup Node.js environment
-        uses: actions/setup-node@v3
-        with:
-          node-version: 16.x
-          cache: 'yarn'
-          cache-dependency-path: web/yarn.lock
-
-      - name: Setup golang environment
-        uses: actions/setup-go@v3
-        with:
-          go-version: '1.18'
-
-      - uses: actions/cache@v3
-        with:
-          path: |
-            ~/.cache/go-build
-            ~/go/pkg/mod
-          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
-          restore-keys: |
-            ${{ runner.os }}-go-
-
-      - name: Start manager-api
-        working-directory: ./
-        run: |
-          make dag-lib
-          cd api
-          sed -i 's@# - dubbo-proxy@- dubbo-proxy@' ./conf/conf.yaml
-          nohup go run ./main.go &
-
-      - name: Cache Cypress binary
-        uses: actions/cache@v3
-        id: cypress-binary-cache
-        with:
-          path: '*/cypress/cache'
-          key: cypress-${{ runner.os }}-cypress-cache0-${{ hashFiles('**/package.json') }}
-          restore-keys: |
-            cypress-${{ runner.os }}-cypress-cache0
-
-      - name: Install dependencies
-        run: yarn
-
-      - name: Start frontend then test
-        run: |
-          yarn start-server-and-test 'cross-env SERVE_ENV=test UMI_UI=none MOCK=none SERVE_URL_TEST=http://localhost:9000 yarn start' http-get://localhost:8000 'cross-env CYPRESS_SERVE_ENV=test SERVE_URL_TEST=http://localhost:9000 yarn cypress run --spec "**/e2e/${{matrix.folderPrefix}}/**.cy.js"'
-
-      - name: Report e2e coverage
-        run: npx nyc report --reporter=text-summary
-
-      - name: Upload coverage to Codecov
-        run: |
-          bash <(curl -s https://codecov.io/bash) -f ./coverage/coverage-final.json -F frontend-e2e-test
-
-      - name: Archive code coverage results
-        uses: actions/upload-artifact@v3
-        if: always()
-        with:
-          name: cypress-report-${{matrix.folderPrefix}}
-          path: |
-            web/cypress/videos
-            web/cypress/screenshots
-          retention-days: 5
diff --git a/.github/workflows/go-lint.yml b/.github/workflows/go-lint.yml
deleted file mode 100644
index fd36206a2..000000000
--- a/.github/workflows/go-lint.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-name: go-lint
-on:
-  push:
-    branches:
-      - master
-    paths:
-      - 'api/**'
-  pull_request:
-    branches:
-      - master
-    paths:
-      - 'api/**'
-
-jobs:
-  golangci:
-    runs-on: ubuntu-latest
-    needs: go-filter
-    if: needs.go-filter.outputs.matches == 'true'
-    steps:
-      - uses: actions/checkout@v3
-
-      - name: golangci-lint
-        uses: golangci/golangci-lint-action@v3
-        with:
-          version: latest
-          working-directory: api
-          args: --tests=false
-          only-new-issues: true
-  gofmt:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v3
-      - name: setup go
-        uses: actions/setup-go@v3
-        with:
-          go-version: '1.18'
-
-      - uses: actions/cache@v3
-        with:
-          path: |
-            ~/.cache/go-build
-            ~/go/pkg/mod
-          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
-          restore-keys: |
-            ${{ runner.os }}-go-
-
-      - name: check gofmt
-        run: |
-          diffs=`gofmt -l ${{ needs.go-filter.outputs.files }}`
-          if [[ -n $diffs ]]; then
-              echo "Files are not formatted by gofmt:"
-              echo $diffs
-              exit 1
-          fi
diff --git a/.github/workflows/license-checker.yml b/.github/workflows/license-checker.yml
deleted file mode 100644
index 87e53281c..000000000
--- a/.github/workflows/license-checker.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: License checker
-
-on:
-  push:
-    branches:
-      - master
-  pull_request:
-    branches:
-      - master
-
-jobs:
-  check-license:
-    runs-on: ubuntu-latest
-
-    steps:
-      - uses: actions/checkout@v3
-
-      - name: run license check
-        run: |
-          make license-check
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
deleted file mode 100644
index 334a66626..000000000
--- a/.github/workflows/lint.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-name: ❄️ Lint
-
-on: [pull_request]
-
-jobs:
-  markdownlint:
-    name: 🍇 Markdown
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v3
-      - name: 🚀 Use Node.js
-        uses: actions/setup-node@v3
-        with:
-          node-version: '16.x'
-      - run: npm install -g markdownlint-cli@0.25.0
-      - run: markdownlint '**/*.md' --ignore node_modules
-  misspell:
-    name: runner/misspell
-    runs-on: ubuntu-latest
-    steps:
-      - name: Check out code.
-        uses: actions/checkout@v3
-      - name: Install
-        run: |
-          wget -O - -q https://git.io/misspell | sh -s -- -b .
-      - name: Misspell
-        run: |
-          find . -type f -maxdepth 1 | xargs ./misspell -error
-          find . -name "*.go" -type f | xargs ./misspell -error
-          find docs -type f | xargs ./misspell -error
-          find web/src web/cypress -type f | xargs ./misspell -error
-  yamllint:
-    name: 🍏 YAML
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v3
-      - uses: actions/setup-python@v4
-        with:
-          python-version: '3.x'  # Version range or exact version of a Python version to use, using SemVer's version range syntax
-          architecture: 'x64'  # optional x64 or x86. Defaults to x64 if not specified
-      - name: Install dependencies
-        run: |
-          python -m pip install --upgrade pip
-          pip install yamllint
-      - name: 🧹 YAML Lint
-        run: |
-          # return non-zero exit code on warnings
-          yamllint --strict .
-  trailing-whitespace:
-    name: Trailing whitespace
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v3
-      - name: Check for trailing whitespace
-        run: "! git grep -EIn $'[ \t]+$'"
diff --git a/.github/workflows/make-build.yaml b/.github/workflows/make-build.yaml
deleted file mode 100644
index 9ebce9467..000000000
--- a/.github/workflows/make-build.yaml
+++ /dev/null
@@ -1,72 +0,0 @@
-# Test make build command to see if ManagerAPI and Web are ok to build
-
-name: make build
-
-on:
-  push:
-    branches:
-      - master
-    paths-ignore:
-      - 'docs/**'
-  pull_request:
-    branches:
-      - master
-    paths-ignore:
-      - 'docs/**'
-
-concurrency:
-  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_number || github.ref }}
-  cancel-in-progress: true
-
-jobs:
-  make-build-test:
-    name: make build test
-    runs-on: ubuntu-latest
-
-    services:
-      etcd:
-        image: bitnami/etcd:3.5.2
-        ports:
-          - 2379:2379
-          - 2380:2380
-        env:
-          ALLOW_NONE_AUTHENTICATION: yes
-
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v3
-        with:
-          submodules: recursive
-
-      - name: Setup Node.js environment
-        uses: actions/setup-node@v3
-        with:
-          node-version: 16.x
-          cache: 'yarn'
-          cache-dependency-path: web/yarn.lock
-
-      - name: Setup golang environment
-        uses: actions/setup-go@v3
-        with:
-          go-version: '1.18'
-
-      - uses: actions/cache@v3
-        with:
-          path: |
-            ~/.cache/go-build
-            ~/go/pkg/mod
-          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
-          restore-keys: |
-            ${{ runner.os }}-go-
-
-      - name: make build
-        run: make build
-
-      - name: start dashboard
-        working-directory: ./output
-        run: |
-          ./manager-api > ./api.log 2>&1 &
-          sleep 5
-
-      - name: check
-        run: api/test/shell/manager_smoking.sh -s true
diff --git a/.github/workflows/release-test.yml b/.github/workflows/release-test.yml
deleted file mode 100644
index 0e11793e9..000000000
--- a/.github/workflows/release-test.yml
+++ /dev/null
@@ -1,98 +0,0 @@
-name: Release Test
-
-on:
-  push:
-    branches:
-      - master
-    paths-ignore:
-      - '.github/**'
-      - '.git/**'
-      - '.gitattributes'
-      - '.vscode/**'
-      - '.gitignore'
-      - 'docs/**'
-      - 'api/internal/core/store/validate_mock.go'
-      - 'api/internal/core/storage/storage_mock.go'
-  pull_request:
-    branches:
-      - master
-    paths-ignore:
-      - '.github/**'
-      - '.git/**'
-      - '.gitattributes'
-      - '.vscode/**'
-      - '.gitignore'
-      - 'docs/**'
-      - 'api/internal/core/store/validate_mock.go'
-      - 'api/internal/core/storage/storage_mock.go'
-
-jobs:
-  run-test:
-    runs-on: ubuntu-latest
-
-    services:
-      etcd:
-        image: bitnami/etcd:3.5.2
-        ports:
-          - 2379:2379
-          - 2380:2380
-        env:
-          ALLOW_NONE_AUTHENTICATION: yes
-
-    steps:
-      - uses: actions/checkout@v3
-
-      - name: setup go
-        uses: actions/setup-go@v3
-        with:
-          go-version: '1.19'
-
-      - uses: actions/cache@v3
-        with:
-          path: |
-            ~/.cache/go-build
-            ~/go/pkg/mod
-          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
-          restore-keys: |
-            ${{ runner.os }}-go-
-
-      - name: release and build
-        run: |
-          VERSION=$(cat ./api/VERSION)
-          mkdir release
-          git clean -Xdf
-          tar -zcvf release/apache-apisix-dashboard-${VERSION}-src.tgz \
-          --exclude .github \
-          --exclude .git \
-          --exclude .gitattributes \
-          --exclude .idea \
-          --exclude .vscode \
-          --exclude .gitignore \
-          --exclude .DS_Store \
-          --exclude docs \
-          --exclude release \
-          --exclude api/internal/core/store/validate_mock.go \
-          --exclude api/internal/core/storage/storage_mock.go \
-          .
-
-          cd release
-          tar -zxvf apache-apisix-dashboard-${VERSION}-src.tgz
-          ls -l
-          export GO111MOUDULE=on
-          api/build.sh
-          mkdir -p ./output/logs
-          cd output
-          ./manager-api > ./api.log 2>&1 &
-          sleep 3
-          cat ./api.log
-          cat ./logs/error.log
-          cat conf/conf.yaml
-
-      - name: run test
-        run: |
-          curl http://127.0.0.1:9000/apisix/admin/user/login -X POST -i -d '{"username":"admin", "password": "admin"}'
-          code=$(curl -k -i -m 20 -o /dev/null -s -w %{http_code} http://127.0.0.1:9000/apisix/admin/user/login -X POST -i -d '{"username":"admin", "password": "admin"}')
-          if [ ! $code -eq 200 ]; then
-              echo "failed: failed to custom port"
-              exit 1
-          fi
diff --git a/.github/workflows/test-frontend-multiple-node-build.yml b/.github/workflows/test-frontend-multiple-node-build.yml
deleted file mode 100644
index 61d1cf25c..000000000
--- a/.github/workflows/test-frontend-multiple-node-build.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-# This is a basic test to build the dashboard
-
-name: Test building web in multiple node version
-
-# Controls when the action will run. Triggers the workflow on push or pull request
-# events but only for the master branch
-on:
-  push:
-    branches:
-      - master
-  pull_request:
-    branches:
-      - master
-
-concurrency:
-  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_number || github.ref }}
-  cancel-in-progress: true
-
-# A workflow run is made up of one or more jobs that can run sequentially or in parallel
-jobs:
-  # This workflow contains a single job called "build"
-  build:
-    # The type of runner that the job will run on
-    runs-on: ubuntu-latest
-
-    strategy:
-      matrix:
-        node-version: [14.x, 16.x]
-
-    # Steps represent a sequence of tasks that will be executed as part of the job
-    steps:
-      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
-      - uses: actions/checkout@v3
-        with:
-          submodules: recursive
-      - name: Use Node.js ${{ matrix.node-version }}
-        uses: actions/setup-node@v3
-        with:
-          node-version: ${{ matrix.node-version }}
-          cache: 'yarn'
-          cache-dependency-path: web/yarn.lock
-
-      # Install dependencies
-      - name: Install dependencies
-        working-directory: web
-        run: CYPRESS_INSTALL_BINARY=0 yarn
-
-      - name: Lint
-        working-directory: web
-        run: yarn run lint:js && yarn run lint:style
-
-      - name: Build the Dashboard
-        working-directory: web
-        run: yarn build
diff --git a/.gitignore b/.gitignore
index 2a34cd128..15c6f2f74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,73 +1,26 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-**/node_modules
-# roadhog-api-doc ignore
-/src/utils/request-temp.js
-_roadhog-api-doc
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
 
-# production
+node_modules
 dist
+dist-ssr
+*.local
 
-# misc
-.DS_Store
-npm-debug.log*
-yarn-error.log
-
-/coverage
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
 .idea
-package-lock.json
-*bak
-
-# visual studio code
-.history
-*.log
-functions/*
-.temp/**
-
-# umi
-.umi
-.umi-production
-
-# screenshot
-screenshot
-.firebase
-.eslintcache
-
-build
-
-/compose/**/*.log
-/compose/**/nginx.pid
-/compose/etcd_data
-manager-api
-grpc-server-example/
-api/test/docker/*tar.gz*
-
-output
-apisix_logs
-default.etcd
-api/build-tools/apisix
-/*.zip
-.githash
-.backup.yaml
-Dockerfile-apisix
-
-# backend unit test output
-api/coverage.txt
-api/coverage.html
-api/dag-to-lua/
-
-# frontend e2e test output
-web/.nyc_output
-web/coverage
-web/cypress/screenshots/
-web/cypress/videos/
-web/cypress/downloads/
-web/public/monaco-editor/
-
-# vim
-*.swp
-*.swo
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
 
-# .env
-.env*
+/.pnpm-store
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 000000000..20c5a9a7a
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,2 @@
+pnpm lint-staged
+git update-index --again
diff --git a/.vscode/settings.json b/.vscode/settings.json
index e521849f2..47713122f 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,8 +1,37 @@
 {
   "eslint.validate": [
-    "javascript",
-    "javascriptreact",
-    { "language": "typescript", "autoFix": true },
-    { "language": "typescriptreact", "autoFix": true }
-  ]
+    "typescriptreact",
+    "typescript",
+  ],
+  "files.readonlyInclude": {
+    "**/routeTree.gen.ts": true
+  },
+  "files.watcherExclude": {
+    "**/routeTree.gen.ts": true
+  },
+  "search.exclude": {
+    "**/routeTree.gen.ts": true
+  },
+  "cssVariables.lookupFiles": [
+    "**/*.css",
+    "**/*.scss",
+    "**/*.sass",
+    "**/*.less",
+    "node_modules/@mantine/core/styles.css"
+  ],
+  "i18n-ally.sortKeys": true,
+  "i18n-ally.localesPaths": [
+    "src/locales",
+  ],
+  "i18n-ally.keystyle": "nested",
+  "i18n-ally.enabledFrameworks": [
+    "react-i18next"
+  ],
+  "i18n-ally.pathMatcher": "{locale}/{namespaces}.json",
+  "i18n-ally.editor.preferEditor": true,
+  "i18n-ally.translate.saveAsCandidates": true,
+  "typescript.tsdk": "node_modules/typescript/lib",
+  "editor.codeActionsOnSave": {
+    "source.fixAll.eslint": "always"
+  },
 }
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 0aed27d61..000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-FROM alpine:latest as pre-build
-
-COPY . /usr/local/apisix-dashboard
-
-RUN set -x \
-    && apk add --no-cache --virtual .builddeps git \
-    && cd /usr/local/apisix-dashboard && git clean -Xdf \
-    && rm -f ./.githash && git log --pretty=format:"%h" -1 > ./.githash
-
-FROM golang:1.19 as api-builder
-
-ARG ENABLE_PROXY=false
-
-WORKDIR /usr/local/apisix-dashboard
-
-COPY --from=pre-build /usr/local/apisix-dashboard .
-
-RUN if [ "$ENABLE_PROXY" = "true" ] ; then go env -w GOPROXY=https://goproxy.io,direct ; fi \
-    && go env -w GO111MODULE=on \
-    && CGO_ENABLED=0 ./api/build.sh
-
-FROM node:16-alpine as fe-builder
-
-ARG ENABLE_PROXY=false
-
-WORKDIR /usr/local/apisix-dashboard
-
-COPY --from=pre-build /usr/local/apisix-dashboard .
-
-WORKDIR /usr/local/apisix-dashboard/web
-
-RUN if [ "$ENABLE_PROXY" = "true" ] ; then yarn config set registry https://registry.npmmirror.com/ ; fi \
-    && yarn install \
-    && yarn build
-
-FROM alpine:latest as prod
-
-ARG ENABLE_PROXY=false
-
-RUN if [ "$ENABLE_PROXY" = "true" ] ; then sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories ; fi
-
-WORKDIR /usr/local/apisix-dashboard
-
-COPY --from=api-builder /usr/local/apisix-dashboard/output/ ./
-
-COPY --from=fe-builder /usr/local/apisix-dashboard/output/ ./
-
-RUN mkdir logs
-
-EXPOSE 9000
-
-CMD [ "/usr/local/apisix-dashboard/manager-api" ]
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 38462c83f..000000000
--- a/Makefile
+++ /dev/null
@@ -1,132 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-SHELL := /bin/bash -o pipefail
-UNAME ?= $(shell uname)
-YARN_EXEC ?= $(shell which yarn)
-GO_EXEC ?= $(shell which go)
-
-VERSION ?= latest
-RELEASE_SRC = apache-apisix-dashboard-${VERSION}-src
-
-export GO111MODULE=on
-
-### help:		Show Makefile rules
-.PHONY: help
-help:
-	@echo Makefile rules:
-	@echo
-	@grep -E '^### [-A-Za-z0-9_]+:' Makefile | sed 's/###/   /'
-
-
-### build:		Build the Apache APISIX Dashboard, including web and manager-api
-.PHONY: build
-build: web-default api-default
-	api/build.sh && cd ./web && export CYPRESS_INSTALL_BINARY=0  && yarn install --ignore-scripts && yarn build  && mkdir -p ../output/logs
-
-
-.PHONY: web-default
-web-default:
-ifeq ("$(wildcard $(YARN_EXEC))", "")
-	@echo "ERROR: Need to install yarn first"
-	exit 1
-endif
-
-
-.PHONY: api-default
-api-default:
-ifeq ("$(wildcard $(GO_EXEC))", "")
-	@echo "ERROR: Need to install golang 1.15+ first"
-	exit 1
-endif
-
-
-### dag-lib:            Download the dag-lib
-.PHONY: dag-lib
-dag-lib:
-ifeq ("$(wildcard api/dag-to-lua/dag-to-lua.lua)", "")
-	curl -Lso /tmp/v1.1.tar.gz https://github.com/api7/dag-to-lua/archive/v1.1.tar.gz
-	tar -zxvf /tmp/v1.1.tar.gz -C /tmp
-	mkdir ./api/dag-to-lua
-	cp -r /tmp/dag-to-lua-1.1/lib/* ./api/dag-to-lua
-endif
-
-
-### api-test:		Run the tests of manager-api
-.PHONY: api-test
-api-test: api-default dag-lib
-	cd api/ && APISIX_API_WORKDIR=$$PWD ENV=test go test -v -count=1 -race -cover -coverprofile=coverage.txt -covermode=atomic ./... && go tool cover -html=coverage.txt -o coverage.html
-
-
-### api-run:		Run the manager-api in develop mode
-.PHONY: api-run
-api-run: api-default
-	api/build.sh --dry-run
-
-
-### api-stop:		Stop the manager-api
-api-stop:
-	cd api && go run -ldflags "${GOLDFLAGS}" ./main.go stop
-
-### go-lint:		Lint Go source codes
-.PHONY: go-lint
-go-lint: ## Run the golangci-lint application (install if not found)
-	@#Brew - MacOS
-	@if [ "$(shell command -v golangci-lint)" = "" ] && [ "$(shell command -v brew)" != "" ] && [ "$(UNAME)" = "Darwin" ]; then brew install golangci-lint; fi;
-	@#has sudo
-	@if [ "$(shell command -v golangci-lint)" = "" ]; then curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.32.0 && sudo cp ./bin/golangci-lint $(go env GOPATH)/bin/; fi;
-	@echo "running golangci-lint..."
-	@cd api && golangci-lint run --tests=false ./...
-
-
-### license-check:	Check source codes for Apache License
-.PHONY: license-check
-license-check:
-ifeq ("$(wildcard .actions/openwhisk-utilities/scancode/scanCode.py)", "")
-	git clone https://github.com/apache/openwhisk-utilities.git .actions/openwhisk-utilities
-	cp .actions/ASF* .actions/openwhisk-utilities/scancode/
-endif
-	.actions/openwhisk-utilities/scancode/scanCode.py --config .actions/ASF-Release.cfg ./
-
-
-### release-src:        Package source codes for release
-.PHONY: release-src
-release-src:
-	./utils/version-check.sh ${VERSION}
-	git clean -Xdf
-	rm -f ./.githash && git log --pretty=format:"%h" -1 > ./.githash
-	tar -zcvf $(RELEASE_SRC).tgz \
-	--exclude .github \
-	--exclude .git \
-	--exclude .gitattributes \
-	--exclude .idea \
-	--exclude .vscode \
-	--exclude .gitignore \
-	--exclude .DS_Store \
-	--exclude docs \
-	--exclude release \
-	--exclude api/internal/core/store/validate_mock.go \
-	--exclude api/internal/core/storage/storage_mock.go \
-	.
-
-	gpg --batch --yes --armor --detach-sig $(RELEASE_SRC).tgz
-	shasum -a 512 $(RELEASE_SRC).tgz > $(RELEASE_SRC).tgz.sha512
-
-	mkdir -p release
-	mv $(RELEASE_SRC).tgz release/$(RELEASE_SRC).tgz
-	mv $(RELEASE_SRC).tgz.asc release/$(RELEASE_SRC).tgz.asc
-	mv $(RELEASE_SRC).tgz.sha512 release/$(RELEASE_SRC).tgz.sha512
diff --git a/README.md b/README.md
index e572a73bd..da9844432 100644
--- a/README.md
+++ b/README.md
@@ -1,109 +1,54 @@
-<!--
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
--->
-
-# Apache APISIX Dashboard
-
-[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/apache/apisix-dashboard/blob/master/LICENSE)
-[![Go Report Card](https://goreportcard.com/badge/github.com/apache/apisix-dashboard)](https://goreportcard.com/report/github.com/apache/apisix-dashboard)
-[![DockerHub](https://img.shields.io/docker/pulls/apache/apisix-dashboard.svg)](https://hub.docker.com/r/apache/apisix-dashboard)
-[![Cypress.io](https://img.shields.io/badge/tested%20with-Cypress-04C38E.svg)](https://www.cypress.io/)
-[![Slack](https://badgen.net/badge/Slack/Join%20Apache%20APISIX?icon=slack)](https://apisix.apache.org/slack)
-
-<p align="center">
-  <a href="https://apisix.apache.org/">Website</a> •
-  <a href="https://github.com/apache/apisix/tree/master/docs">Docs</a> •
-  <a href="https://twitter.com/apacheapisix">Twitter</a>
-</p>
-
-- The master version should be used with Apache APISIX master version.
-
-- The latest released version is [3.0.0](https://apisix.apache.org/downloads/) and is compatible with [Apache APISIX 3.0.x](https://apisix.apache.org/downloads/).
-
-## What's Apache APISIX Dashboard
-
-The Apache APISIX Dashboard is designed to make it as easy as possible for users to operate [Apache APISIX](https://github.com/apache/apisix) through a frontend interface.
-
-The Dashboard is the control plane and performs all parameter checks; Apache APISIX mixes data and control planes and will evolve to a pure data plane.
-
-Note: Currently the Dashboard does not have complete coverage of Apache APISIX features, [visit here](https://github.com/apache/apisix-dashboard/milestones) to view the milestones.
-
-![architecture](./docs/assets/images/architecture.png)
-
-## Demo
-
-[Online Playground](https://apisix-dashboard.apiseven.com/)
-
-```text
-Username: admin
-Password: admin
+# React + TypeScript + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+
+Currently, two official plugins are available:
+
+- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
+- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
+
+## Expanding the ESLint configuration
+
+If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
+
+```js
+export default tseslint.config({
+  extends: [
+    // Remove ...tseslint.configs.recommended and replace with this
+    ...tseslint.configs.recommendedTypeChecked,
+    // Alternatively, use this for stricter rules
+    ...tseslint.configs.strictTypeChecked,
+    // Optionally, add this for stylistic rules
+    ...tseslint.configs.stylisticTypeChecked,
+  ],
+  languageOptions: {
+    // other options...
+    parserOptions: {
+      project: ['./tsconfig.node.json', './tsconfig.app.json'],
+      tsconfigRootDir: import.meta.dirname,
+    },
+  },
+})
 ```
 
-## Works with APISIX Ingress Controller
-
-Currently, APISIX Ingress Controller automatically manipulates some APISIX resources, which is not very compatible with APISIX Dashboard. In addition, users should not modify resources labeled `managed-by: apisix-ingress-controllers` via APISIX Dashboard.
-
-## Project structure
-
-```text
-.
-├── CHANGELOG.md
-├── CODE_OF_CONDUCT.md
-├── CONTRIBUTING.md
-├── Dockerfile
-├── LICENSE
-├── Makefile
-├── NOTICE
-├── README.md
-├── api
-├── docs
-├── licenses
-└── web
+You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
+
+```js
+// eslint.config.js
+import reactX from 'eslint-plugin-react-x'
+import reactDom from 'eslint-plugin-react-dom'
+
+export default tseslint.config({
+  plugins: {
+    // Add the react-x and react-dom plugins
+    'react-x': reactX,
+    'react-dom': reactDom,
+  },
+  rules: {
+    // other rules...
+    // Enable its recommended typescript rules
+    ...reactX.configs['recommended-typescript'].rules,
+    ...reactDom.configs.recommended.rules,
+  },
+})
 ```
-
-1. The `api` directory is used to store the `Manager API` source codes, which is used to manage `etcd` and provide APIs to the frontend interface.
-2. The `web` directory is used to store the frontend source codes.
-
-## Build then launch
-
-Support the following ways currently.
-
-- [Docker, RPM, Source Codes](./docs/en/latest/install.md)
-- [Rebuild docker image](./docs/en/latest/deploy-with-docker.md)
-
-## Development
-
-Pull requests are encouraged and always welcome. [Pick an issue](https://github.com/apache/apisix-dashboard/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) and help us out!
-
-Please refer to the [Development Guide](./docs/en/latest/develop.md).
-
-## User Guide
-
-Please refer to the [User Guide](./docs/en/latest/USER_GUIDE.md).
-
-## Contributing
-
-Please refer to the [Contribution Guide](./CONTRIBUTING.md) for a more detailed information.
-
-## FAQ
-
-Please refer to the [FAQ](./docs/en/latest/FAQ.md) for more known issues.
-
-## License
-
-[Apache License 2.0](./LICENSE)
diff --git a/api/README.md b/api/README.md
deleted file mode 100644
index e574fe0f8..000000000
--- a/api/README.md
+++ /dev/null
@@ -1,48 +0,0 @@
-<!--
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
--->
-
-# manager-api
-
-This is a backend project which the dashboard depends on, implemented by Golang.
-
-## Installation
-
-[Please refer to the doc](../README.md)
-
-## Project structure
-
-```text
-├── README.md
-├── VERSION
-├── build-tools
-├── build.sh
-├── cmd
-├── conf
-├── entry.sh
-├── go.mod
-├── go.sum
-├── internal
-├── run.sh
-└── test
-```
-
-1. The `cmd` directory is the project entrance.
-2. The `internal` directory contains the main logic of manager-api.
-3. The `conf` directory contains the default configuration file.
-4. The `test` directory contains E2E test cases.
diff --git a/api/VERSION b/api/VERSION
deleted file mode 100644
index 4a36342fc..000000000
--- a/api/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-3.0.0
diff --git a/api/build.sh b/api/build.sh
deleted file mode 100755
index db74cb20c..000000000
--- a/api/build.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-set -e
-
-VERSION=$(cat ./api/VERSION)
-GITHASH=$(cat ./.githash 2> /dev/null || HASH="ref: HEAD"; while [[ $HASH == ref\:* ]]; do HASH="$(cat ".git/$(echo $HASH | cut -d \  -f 2)")"; done; echo ${HASH:0:7})
-
-GOLDFLAGS="-X github.com/apisix/manager-api/internal/utils.version=${VERSION} -X github.com/apisix/manager-api/internal/utils.gitHash=${GITHASH}"
-
-# Enter dry-run mode
-if [ "$1" == "--dry-run" ]; then
-    cd ./api && go run -ldflags "${GOLDFLAGS}" ./main.go
-    exit 0
-fi
-
-set -x
-export ENV=local
-pwd=$(pwd)
-
-rm -rf output && mkdir -p output/conf && mkdir -p output/dag-to-lua
-
-# get dag-to-lua lib
-if [[ ! -f "dag-to-lua-1.1/lib/dag-to-lua.lua" ]]; then
-    wget https://github.com/api7/dag-to-lua/archive/v1.1.tar.gz -P /tmp
-    tar -zxvf /tmp/v1.1.tar.gz -C /tmp
-    cp -r /tmp/dag-to-lua-1.1/lib/* ./output/dag-to-lua
-fi
-
-# build
-cd ./api && go build -o ../output/manager-api -ldflags "${GOLDFLAGS}" ./main.go && cd ..
-
-cp ./api/conf/schema.json ./output/conf/schema.json
-cp ./api/conf/customize_schema.json ./output/conf/customize_schema.json
-cp ./api/conf/conf*.yaml ./output/conf/
-
-echo "Build the Manager API successfully"
diff --git a/api/cmd/root.go b/api/cmd/root.go
deleted file mode 100644
index 4d3e03361..000000000
--- a/api/cmd/root.go
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package cmd
-
-import (
-	"context"
-	"fmt"
-	"os"
-	"os/signal"
-	"syscall"
-	"time"
-
-	"github.com/spf13/cobra"
-
-	"github.com/apisix/manager-api/internal/conf"
-	"github.com/apisix/manager-api/internal/core/server"
-	"github.com/apisix/manager-api/internal/core/storage"
-	"github.com/apisix/manager-api/internal/core/store"
-	"github.com/apisix/manager-api/internal/log"
-)
-
-var rootCmd = &cobra.Command{
-	Use:   "manager-api",
-	Short: "Apache APISIX Manager API",
-	RunE: func(cmd *cobra.Command, args []string) error {
-		err := manageAPI()
-		return err
-	},
-}
-
-func init() {
-	rootCmd.PersistentFlags().StringVarP(&conf.ConfigFile, "config", "c", "", "config file")
-	rootCmd.PersistentFlags().StringVarP(&conf.WorkDir, "work-dir", "p", ".", "current work directory")
-
-	rootCmd.AddCommand(
-		newVersionCommand(),
-	)
-}
-
-func Execute() {
-	if err := rootCmd.Execute(); err != nil {
-		_, _ = fmt.Fprintln(os.Stderr, err)
-	}
-}
-
-func manageAPI() error {
-	conf.InitConf()
-	log.InitLogger()
-
-	s, err := server.NewServer(&server.Options{})
-	if err != nil {
-		return err
-	}
-
-	// start Manager API server
-	errSig := make(chan error, 5)
-	s.Start(errSig)
-
-	// start etcd connection checker
-	stopEtcdConnectionChecker := etcdConnectionChecker()
-
-	// Signal received to the process externally.
-	quit := make(chan os.Signal, 1)
-	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
-
-	select {
-	case sig := <-quit:
-		log.Infof("The Manager API server receive %s and start shutting down", sig.String())
-		stopEtcdConnectionChecker()
-		s.Stop()
-		log.Infof("See you next time!")
-	case err := <-errSig:
-		log.Errorf("The Manager API server start failed: %s", err.Error())
-		return err
-	}
-	return nil
-}
-
-func etcdConnectionChecker() context.CancelFunc {
-	ctx, cancel := context.WithCancel(context.TODO())
-	unavailableTimes := 0
-
-	go func() {
-		etcdClient := storage.GenEtcdStorage().GetClient()
-		for {
-			select {
-			case <-time.Tick(10 * time.Second):
-				sCtx, sCancel := context.WithTimeout(ctx, 5*time.Second)
-				err := etcdClient.Sync(sCtx)
-				sCancel()
-				if err != nil {
-					unavailableTimes++
-					log.Errorf("etcd connection loss detected, times: %d", unavailableTimes)
-					continue
-				}
-
-				// After multiple failures, the connection is restored
-				if unavailableTimes >= 1 {
-					log.Warnf("etcd connection recovered, but after several connection losses, reinitializing stores, times: %d", unavailableTimes)
-					unavailableTimes = 0
-
-					// When this happens, force a full re-initialization of the store
-					store.RangeStore(func(key store.HubKey, store *store.GenericStore) bool {
-						log.Warnf("etcd store reinitializing: resource: %s", key)
-						if err := store.Init(); err != nil {
-							log.Errorf("etcd store reinitialize failed: resource: %s, error: %s", key, err)
-						}
-						return true
-					})
-				} else {
-					log.Info("etcd connection is fine")
-				}
-			case <-ctx.Done():
-				return
-			}
-		}
-	}()
-
-	// Timed re-initialization when etcd watch actively exits
-	go func() {
-		for {
-			select {
-			case <-time.Tick(2 * time.Minute):
-				err := store.ReInit()
-				if err != nil {
-					log.Errorf("resource re-initialize failed, err: %v", err)
-				}
-			}
-		}
-	}()
-
-	return cancel
-}
diff --git a/api/cmd/version.go b/api/cmd/version.go
deleted file mode 100644
index c064502bd..000000000
--- a/api/cmd/version.go
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package cmd
-
-import (
-	"github.com/spf13/cobra"
-
-	"github.com/apisix/manager-api/internal/utils"
-)
-
-func newVersionCommand() *cobra.Command {
-	return &cobra.Command{
-		Use:   "version",
-		Short: "show manager-api version",
-		Run: func(cmd *cobra.Command, args []string) {
-			utils.PrintVersion()
-		},
-	}
-}
diff --git a/api/conf/conf.yaml b/api/conf/conf.yaml
deleted file mode 100644
index a74986de7..000000000
--- a/api/conf/conf.yaml
+++ /dev/null
@@ -1,174 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# yamllint disable rule:comments-indentation
-conf:
-  listen:
-    # host: 127.0.0.1     # the address on which the `Manager API` should listen.
-                          # The default value is 0.0.0.0, if want to specify, please enable it.
-                          # This value accepts IPv4, IPv6, and hostname.
-    port: 9000            # The port on which the `Manager API` should listen.
-
-  # ssl:
-  #   host: 127.0.0.1     # the address on which the `Manager API` should listen for HTTPS.
-                          # The default value is 0.0.0.0, if want to specify, please enable it.
-  #   port: 9001            # The port on which the `Manager API` should listen for HTTPS.
-  #   cert: "/tmp/cert/example.crt" # Path of your SSL cert.
-  #   key:  "/tmp/cert/example.key"  # Path of your SSL key.
-
-  allow_list:             # If we don't set any IP list, then any IP access is allowed by default.
-    - 127.0.0.1           # The rules are checked in sequence until the first match is found.
-    - ::1                 # In this example, access is allowed only for IPv4 network 127.0.0.1, and for IPv6 network ::1.
-                          # It also support CIDR like 192.168.1.0/24 and 2001:0db8::/32
-  etcd:
-    endpoints:            # supports defining multiple etcd host addresses for an etcd cluster
-      - 127.0.0.1:2379
-                          # yamllint disable rule:comments-indentation
-                          # etcd basic auth info
-    # username: "root"    # ignore etcd username if not enable etcd auth
-    # password: "123456"  # ignore etcd password if not enable etcd auth
-    mtls:
-      key_file: ""          # Path of your self-signed client side key
-      cert_file: ""         # Path of your self-signed client side cert
-      ca_file: ""           # Path of your self-signed ca cert, the CA is used to sign callers' certificates
-    # prefix: /apisix       # apisix config's prefix in etcd, /apisix by default
-  log:
-    error_log:
-      level: warn       # supports levels, lower to higher: debug, info, warn, error, panic, fatal
-      file_path:
-        logs/error.log  # supports relative path, absolute path, standard output
-                        # such as: logs/error.log, /tmp/logs/error.log, /dev/stdout, /dev/stderr
-                        # such as absolute path on Windows: winfile:///C:\error.log
-    access_log:
-      file_path:
-        logs/access.log  # supports relative path, absolute path, standard output
-                         # such as: logs/access.log, /tmp/logs/access.log, /dev/stdout, /dev/stderr
-                         # such as absolute path on Windows: winfile:///C:\access.log
-                         # log example: 2020-12-09T16:38:09.039+0800	INFO	filter/logging.go:46	/apisix/admin/routes/r1	{"status": 401, "host": "127.0.0.1:9000", "query": "asdfsafd=adf&a=a", "requestId": "3d50ecb8-758c-46d1-af5b-cd9d1c820156", "latency": 0, "remoteIP": "127.0.0.1", "method": "PUT", "errs": []}
-  max_cpu: 0             # supports tweaking with the number of OS threads are going to be used for parallelism. Default value: 0 [will use max number of available cpu cores considering hyperthreading (if any)]. If the value is negative, is will not touch the existing parallelism profile.
-  # security:
-  #   access_control_allow_origin: "http://httpbin.org"
-  #   access_control_allow_credentials: true          # support using custom cors configration
-  #   access_control_allow_headers: "Authorization"
-  #   access_control-allow_methods: "*"
-  #   x_frame_options: "deny"
-  #   content_security_policy: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src xx.xx.xx.xx:3000"  # You can set frame-src to provide content for your grafana panel.
-
-authentication:
-  secret:
-    secret              # secret for jwt token generation.
-                        # NOTE: Highly recommended to modify this value to protect `manager api`.
-                        # if it's default value, when `manager api` start, it will generate a random string to replace it.
-  expire_time: 3600     # jwt token expire time, in second
-  users:                # yamllint enable rule:comments-indentation
-    - username: admin   # username and password for login `manager api`
-      password: admin
-    - username: user
-      password: user
-
-oidc:
-  enabled: false
-  expire_time: 3600
-  client_id: dashboard
-  client_secret: dashboard
-  auth_url: http://172.17.0.1:8080/auth/realms/master/protocol/openid-connect/auth
-  token_url: http://172.17.0.1:8080/auth/realms/master/protocol/openid-connect/token
-  user_info_url: http://172.17.0.1:8080/auth/realms/master/protocol/openid-connect/userinfo
-  redirect_url: http://127.0.0.1:9000/apisix/admin/oidc/callback
-  scope: openid
-
-plugins:
-  - api-breaker
-  - authz-casbin
-  - authz-casdoor
-  - authz-keycloak
-  - aws-lambda
-  - azure-functions
-  - basic-auth
-  # - batch-requests
-  - clickhouse-logger
-  - client-control
-  - consumer-restriction
-  - cors
-  - csrf
-  - datadog
-  # - dubbo-proxy
-  - echo
-  - error-log-logger
-  # - example-plugin
-  - ext-plugin-post-req
-  - ext-plugin-post-resp
-  - ext-plugin-pre-req
-  - fault-injection
-  - file-logger
-  - forward-auth
-  - google-cloud-logging
-  - grpc-transcode
-  - grpc-web
-  - gzip
-  - hmac-auth
-  - http-logger
-  - ip-restriction
-  - jwt-auth
-  - kafka-logger
-  - kafka-proxy
-  - key-auth
-  - ldap-auth
-  - limit-conn
-  - limit-count
-  - limit-req
-  - loggly
-  # - log-rotate
-  - mocking
-  # - node-status
-  - opa
-  - openid-connect
-  - opentelemetry
-  - openwhisk
-  - prometheus
-  - proxy-cache
-  - proxy-control
-  - proxy-mirror
-  - proxy-rewrite
-  - public-api
-  - real-ip
-  - redirect
-  - referer-restriction
-  - request-id
-  - request-validation
-  - response-rewrite
-  - rocketmq-logger
-  - server-info
-  - serverless-post-function
-  - serverless-pre-function
-  - skywalking
-  - skywalking-logger
-  - sls-logger
-  - splunk-hec-logging
-  - syslog
-  - tcp-logger
-  - traffic-split
-  - ua-restriction
-  - udp-logger
-  - uri-blocker
-  - wolf-rbac
-  - zipkin
-  - elasticsearch-logge
-  - openfunction
-  - tencent-cloud-cls
-  - ai
-  - cas-auth
diff --git a/api/conf/customize_schema.json b/api/conf/customize_schema.json
deleted file mode 100644
index bde256318..000000000
--- a/api/conf/customize_schema.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-    "main": {
-        "system_config": {
-            "properties": {
-                "config_name": {
-                    "maxLength":100,
-                    "minLength":1,
-                    "pattern":"^[a-zA-Z0-9_]+$",
-                    "type":"string"
-                },
-                "desc": {
-                    "maxLength":256,
-                    "type":"string"
-                },
-                "payload": {
-                    "type":"object",
-                    "minProperties":1
-                },
-                "create_time": {
-                    "type":"integer"
-                },
-                "update_time": {
-                    "type":"integer"
-                }
-            },
-            "required": [
-                "config_name",
-                "payload"
-            ],
-            "type":"object"
-        }
-   }
-}
diff --git a/api/conf/schema.json b/api/conf/schema.json
deleted file mode 100644
index 0d24afed3..000000000
--- a/api/conf/schema.json
+++ /dev/null
@@ -1,11197 +0,0 @@
-{
-	"main": {
-		"consumer": {
-			"properties": {
-				"create_time": {
-					"type": "integer"
-				},
-				"desc": {
-					"maxLength": 256,
-					"type": "string"
-				},
-				"group_id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"labels": {
-					"description": "key/value pairs to specify attributes",
-					"patternProperties": {
-						".*": {
-							"description": "value of label",
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^\\S+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"plugins": {
-					"type": "object"
-				},
-				"update_time": {
-					"type": "integer"
-				},
-				"username": {
-					"maxLength": 100,
-					"minLength": 1,
-					"pattern": "^[a-zA-Z0-9_]+$",
-					"type": "string"
-				}
-			},
-			"required": [
-				"username"
-			],
-			"type": "object"
-		},
-		"global_rule": {
-			"properties": {
-				"create_time": {
-					"type": "integer"
-				},
-				"id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"plugins": {
-					"type": "object"
-				},
-				"update_time": {
-					"type": "integer"
-				}
-			},
-			"required": [
-				"plugins"
-			],
-			"type": "object"
-		},
-		"plugin_config": {
-			"properties": {
-				"create_time": {
-					"type": "integer"
-				},
-				"desc": {
-					"maxLength": 256,
-					"type": "string"
-				},
-				"id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"labels": {
-					"description": "key/value pairs to specify attributes",
-					"patternProperties": {
-						".*": {
-							"description": "value of label",
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^\\S+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"plugins": {
-					"type": "object"
-				},
-				"update_time": {
-					"type": "integer"
-				}
-			},
-			"required": [
-				"id",
-				"plugins"
-			],
-			"type": "object"
-		},
-		"plugins": {
-			"items": {
-				"properties": {
-					"name": {
-						"minLength": 1,
-						"type": "string"
-					},
-					"stream": {
-						"type": "boolean"
-					}
-				},
-				"required": [
-					"name"
-				],
-				"type": "object"
-			},
-			"type": "array"
-		},
-		"proto": {
-			"properties": {
-				"content": {
-					"maxLength": 1048576,
-					"minLength": 1,
-					"type": "string"
-				},
-				"create_time": {
-					"type": "integer"
-				},
-				"desc": {
-					"maxLength": 256,
-					"type": "string"
-				},
-				"id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"update_time": {
-					"type": "integer"
-				}
-			},
-			"required": [
-				"content"
-			],
-			"type": "object"
-		},
-		"route": {
-			"allOf": [
-				{
-					"oneOf": [
-						{
-							"required": [
-								"uri"
-							]
-						},
-						{
-							"required": [
-								"uris"
-							]
-						}
-					]
-				},
-				{
-					"oneOf": [
-						{
-							"not": {
-								"anyOf": [
-									{
-										"required": [
-											"host"
-										]
-									},
-									{
-										"required": [
-											"hosts"
-										]
-									}
-								]
-							}
-						},
-						{
-							"required": [
-								"host"
-							]
-						},
-						{
-							"required": [
-								"hosts"
-							]
-						}
-					]
-				},
-				{
-					"oneOf": [
-						{
-							"not": {
-								"anyOf": [
-									{
-										"required": [
-											"remote_addr"
-										]
-									},
-									{
-										"required": [
-											"remote_addrs"
-										]
-									}
-								]
-							}
-						},
-						{
-							"required": [
-								"remote_addr"
-							]
-						},
-						{
-							"required": [
-								"remote_addrs"
-							]
-						}
-					]
-				}
-			],
-			"anyOf": [
-				{
-					"required": [
-						"plugins",
-						"uri"
-					]
-				},
-				{
-					"required": [
-						"upstream",
-						"uri"
-					]
-				},
-				{
-					"required": [
-						"upstream_id",
-						"uri"
-					]
-				},
-				{
-					"required": [
-						"service_id",
-						"uri"
-					]
-				},
-				{
-					"required": [
-						"plugins",
-						"uris"
-					]
-				},
-				{
-					"required": [
-						"upstream",
-						"uris"
-					]
-				},
-				{
-					"required": [
-						"upstream_id",
-						"uris"
-					]
-				},
-				{
-					"required": [
-						"service_id",
-						"uris"
-					]
-				},
-				{
-					"required": [
-						"script",
-						"uri"
-					]
-				},
-				{
-					"required": [
-						"script",
-						"uris"
-					]
-				}
-			],
-			"not": {
-				"anyOf": [
-					{
-						"required": [
-							"plugins",
-							"script"
-						]
-					},
-					{
-						"required": [
-							"plugin_config_id",
-							"script"
-						]
-					}
-				]
-			},
-			"properties": {
-				"create_time": {
-					"type": "integer"
-				},
-				"desc": {
-					"maxLength": 256,
-					"type": "string"
-				},
-				"enable_websocket": {
-					"description": "enable websocket for request",
-					"type": "boolean"
-				},
-				"filter_func": {
-					"minLength": 10,
-					"pattern": "^function",
-					"type": "string"
-				},
-				"host": {
-					"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-					"type": "string"
-				},
-				"hosts": {
-					"items": {
-						"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-						"type": "string"
-					},
-					"minItems": 1,
-					"type": "array",
-					"uniqueItems": true
-				},
-				"id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"labels": {
-					"description": "key/value pairs to specify attributes",
-					"patternProperties": {
-						".*": {
-							"description": "value of label",
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^\\S+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"methods": {
-					"items": {
-						"description": "HTTP method",
-						"enum": [
-							"CONNECT",
-							"DELETE",
-							"GET",
-							"HEAD",
-							"OPTIONS",
-							"PATCH",
-							"POST",
-							"PURGE",
-							"PUT",
-							"TRACE"
-						],
-						"type": "string"
-					},
-					"type": "array",
-					"uniqueItems": true
-				},
-				"name": {
-					"maxLength": 100,
-					"minLength": 1,
-					"type": "string"
-				},
-				"plugin_config_id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"plugins": {
-					"type": "object"
-				},
-				"priority": {
-					"default": 0,
-					"type": "integer"
-				},
-				"remote_addr": {
-					"anyOf": [
-						{
-							"format": "ipv4",
-							"title": "IPv4",
-							"type": "string"
-						},
-						{
-							"pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$",
-							"title": "IPv4/CIDR",
-							"type": "string"
-						},
-						{
-							"format": "ipv6",
-							"title": "IPv6",
-							"type": "string"
-						},
-						{
-							"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
-							"title": "IPv6/CIDR",
-							"type": "string"
-						}
-					],
-					"description": "client IP",
-					"type": "string"
-				},
-				"remote_addrs": {
-					"items": {
-						"anyOf": [
-							{
-								"format": "ipv4",
-								"title": "IPv4",
-								"type": "string"
-							},
-							{
-								"pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$",
-								"title": "IPv4/CIDR",
-								"type": "string"
-							},
-							{
-								"format": "ipv6",
-								"title": "IPv6",
-								"type": "string"
-							},
-							{
-								"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
-								"title": "IPv6/CIDR",
-								"type": "string"
-							}
-						],
-						"description": "client IP",
-						"type": "string"
-					},
-					"minItems": 1,
-					"type": "array",
-					"uniqueItems": true
-				},
-				"script": {
-					"maxLength": 102400,
-					"minLength": 10,
-					"type": "string"
-				},
-				"script_id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"service_id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"status": {
-					"default": 1,
-					"description": "route status, 1 to enable, 0 to disable",
-					"enum": [
-						0,
-						1
-					],
-					"type": "integer"
-				},
-				"timeout": {
-					"properties": {
-						"connect": {
-							"exclusiveMinimum": 0,
-							"type": "number"
-						},
-						"read": {
-							"exclusiveMinimum": 0,
-							"type": "number"
-						},
-						"send": {
-							"exclusiveMinimum": 0,
-							"type": "number"
-						}
-					},
-					"required": [
-						"connect",
-						"read",
-						"send"
-					],
-					"type": "object"
-				},
-				"update_time": {
-					"type": "integer"
-				},
-				"upstream": {
-					"oneOf": [
-						{
-							"required": [
-								"nodes",
-								"type"
-							]
-						},
-						{
-							"required": [
-								"discovery_type",
-								"service_name",
-								"type"
-							]
-						}
-					],
-					"properties": {
-						"checks": {
-							"anyOf": [
-								{
-									"required": [
-										"active"
-									]
-								},
-								{
-									"required": [
-										"active",
-										"passive"
-									]
-								}
-							],
-							"properties": {
-								"active": {
-									"properties": {
-										"concurrency": {
-											"default": 10,
-											"type": "integer"
-										},
-										"healthy": {
-											"properties": {
-												"http_statuses": {
-													"default": [
-														200,
-														302
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"interval": {
-													"default": 1,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"successes": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										},
-										"host": {
-											"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-											"type": "string"
-										},
-										"http_path": {
-											"default": "/",
-											"type": "string"
-										},
-										"https_verify_certificate": {
-											"default": true,
-											"type": "boolean"
-										},
-										"port": {
-											"maximum": 65535,
-											"minimum": 1,
-											"type": "integer"
-										},
-										"req_headers": {
-											"items": {
-												"type": "string",
-												"uniqueItems": true
-											},
-											"minItems": 1,
-											"type": "array"
-										},
-										"timeout": {
-											"default": 1,
-											"type": "number"
-										},
-										"type": {
-											"default": "http",
-											"enum": [
-												"http",
-												"https",
-												"tcp"
-											],
-											"type": "string"
-										},
-										"unhealthy": {
-											"properties": {
-												"http_failures": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"http_statuses": {
-													"default": [
-														404,
-														429,
-														500,
-														501,
-														502,
-														503,
-														504,
-														505
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"interval": {
-													"default": 1,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"tcp_failures": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"timeouts": {
-													"default": 3,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										}
-									},
-									"type": "object"
-								},
-								"passive": {
-									"properties": {
-										"healthy": {
-											"properties": {
-												"http_statuses": {
-													"default": [
-														200,
-														201,
-														202,
-														203,
-														204,
-														205,
-														206,
-														207,
-														208,
-														226,
-														300,
-														301,
-														302,
-														303,
-														304,
-														305,
-														306,
-														307,
-														308
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"successes": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										},
-										"type": {
-											"default": "http",
-											"enum": [
-												"http",
-												"https",
-												"tcp"
-											],
-											"type": "string"
-										},
-										"unhealthy": {
-											"properties": {
-												"http_failures": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												},
-												"http_statuses": {
-													"default": [
-														429,
-														500,
-														503
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"tcp_failures": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												},
-												"timeouts": {
-													"default": 7,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										}
-									},
-									"type": "object"
-								}
-							},
-							"type": "object"
-						},
-						"create_time": {
-							"type": "integer"
-						},
-						"desc": {
-							"maxLength": 256,
-							"type": "string"
-						},
-						"discovery_args": {
-							"properties": {
-								"group_name": {
-									"description": "group name",
-									"type": "string"
-								},
-								"namespace_id": {
-									"description": "namespace id",
-									"type": "string"
-								}
-							},
-							"type": "object"
-						},
-						"discovery_type": {
-							"description": "discovery type",
-							"type": "string"
-						},
-						"hash_on": {
-							"default": "vars",
-							"enum": [
-								"consumer",
-								"cookie",
-								"header",
-								"vars",
-								"vars_combinations"
-							],
-							"type": "string"
-						},
-						"id": {
-							"anyOf": [
-								{
-									"maxLength": 64,
-									"minLength": 1,
-									"pattern": "^[a-zA-Z0-9-_.]+$",
-									"type": "string"
-								},
-								{
-									"minimum": 1,
-									"type": "integer"
-								}
-							]
-						},
-						"keepalive_pool": {
-							"properties": {
-								"idle_timeout": {
-									"default": 60,
-									"minimum": 0,
-									"type": "number"
-								},
-								"requests": {
-									"default": 1000,
-									"minimum": 1,
-									"type": "integer"
-								},
-								"size": {
-									"default": 320,
-									"minimum": 1,
-									"type": "integer"
-								}
-							},
-							"type": "object"
-						},
-						"key": {
-							"description": "the key of chash for dynamic load balancing",
-							"type": "string"
-						},
-						"labels": {
-							"description": "key/value pairs to specify attributes",
-							"patternProperties": {
-								".*": {
-									"description": "value of label",
-									"maxLength": 64,
-									"minLength": 1,
-									"pattern": "^\\S+$",
-									"type": "string"
-								}
-							},
-							"type": "object"
-						},
-						"name": {
-							"maxLength": 100,
-							"minLength": 1,
-							"type": "string"
-						},
-						"nodes": {
-							"anyOf": [
-								{
-									"patternProperties": {
-										".*": {
-											"description": "weight of node",
-											"minimum": 0,
-											"type": "integer"
-										}
-									},
-									"type": "object"
-								},
-								{
-									"items": {
-										"properties": {
-											"host": {
-												"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-												"type": "string"
-											},
-											"metadata": {
-												"description": "metadata of node",
-												"type": "object"
-											},
-											"port": {
-												"description": "port of node",
-												"minimum": 1,
-												"type": "integer"
-											},
-											"priority": {
-												"default": 0,
-												"description": "priority of node",
-												"type": "integer"
-											},
-											"weight": {
-												"description": "weight of node",
-												"minimum": 0,
-												"type": "integer"
-											}
-										},
-										"required": [
-											"host",
-											"port",
-											"weight"
-										],
-										"type": "object"
-									},
-									"type": "array"
-								}
-							]
-						},
-						"pass_host": {
-							"default": "pass",
-							"description": "mod of host passing",
-							"enum": [
-								"node",
-								"pass",
-								"rewrite"
-							],
-							"type": "string"
-						},
-						"retries": {
-							"minimum": 0,
-							"type": "integer"
-						},
-						"retry_timeout": {
-							"minimum": 0,
-							"type": "number"
-						},
-						"scheme": {
-							"default": "http",
-							"description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.",
-							"enum": [
-								"grpc",
-								"grpcs",
-								"http",
-								"https",
-								"kafka",
-								"tcp",
-								"tls",
-								"udp"
-							]
-						},
-						"service_name": {
-							"maxLength": 256,
-							"minLength": 1,
-							"type": "string"
-						},
-						"timeout": {
-							"properties": {
-								"connect": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								},
-								"read": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								},
-								"send": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								}
-							},
-							"required": [
-								"connect",
-								"read",
-								"send"
-							],
-							"type": "object"
-						},
-						"tls": {
-							"dependencies": {
-								"client_cert": {
-									"not": {
-										"required": [
-											"client_cert_id"
-										]
-									},
-									"required": [
-										"client_key"
-									]
-								},
-								"client_cert_id": {
-									"not": {
-										"required": [
-											"client_client",
-											"client_key"
-										]
-									}
-								},
-								"client_key": {
-									"not": {
-										"required": [
-											"client_cert_id"
-										]
-									},
-									"required": [
-										"client_cert"
-									]
-								}
-							},
-							"properties": {
-								"client_cert": {
-									"maxLength": 65536,
-									"minLength": 128,
-									"type": "string"
-								},
-								"client_cert_id": {
-									"anyOf": [
-										{
-											"maxLength": 64,
-											"minLength": 1,
-											"pattern": "^[a-zA-Z0-9-_.]+$",
-											"type": "string"
-										},
-										{
-											"minimum": 1,
-											"type": "integer"
-										}
-									]
-								},
-								"client_key": {
-									"maxLength": 65536,
-									"minLength": 128,
-									"type": "string"
-								},
-								"verify": {
-									"default": false,
-									"description": "Turn on server certificate verification, currently only kafka upstream is supported",
-									"type": "boolean"
-								}
-							},
-							"type": "object"
-						},
-						"type": {
-							"description": "algorithms of load balancing",
-							"type": "string"
-						},
-						"update_time": {
-							"type": "integer"
-						},
-						"upstream_host": {
-							"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"upstream_id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"uri": {
-					"maxLength": 4096,
-					"minLength": 1,
-					"type": "string"
-				},
-				"uris": {
-					"items": {
-						"description": "HTTP uri",
-						"type": "string"
-					},
-					"minItems": 1,
-					"type": "array",
-					"uniqueItems": true
-				},
-				"vars": {
-					"type": "array"
-				}
-			},
-			"type": "object"
-		},
-		"service": {
-			"properties": {
-				"create_time": {
-					"type": "integer"
-				},
-				"desc": {
-					"maxLength": 256,
-					"type": "string"
-				},
-				"enable_websocket": {
-					"description": "enable websocket for request",
-					"type": "boolean"
-				},
-				"hosts": {
-					"items": {
-						"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-						"type": "string"
-					},
-					"minItems": 1,
-					"type": "array",
-					"uniqueItems": true
-				},
-				"id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"labels": {
-					"description": "key/value pairs to specify attributes",
-					"patternProperties": {
-						".*": {
-							"description": "value of label",
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^\\S+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"name": {
-					"maxLength": 100,
-					"minLength": 1,
-					"type": "string"
-				},
-				"plugins": {
-					"type": "object"
-				},
-				"script": {
-					"maxLength": 102400,
-					"minLength": 10,
-					"type": "string"
-				},
-				"update_time": {
-					"type": "integer"
-				},
-				"upstream": {
-					"oneOf": [
-						{
-							"required": [
-								"nodes",
-								"type"
-							]
-						},
-						{
-							"required": [
-								"discovery_type",
-								"service_name",
-								"type"
-							]
-						}
-					],
-					"properties": {
-						"checks": {
-							"anyOf": [
-								{
-									"required": [
-										"active"
-									]
-								},
-								{
-									"required": [
-										"active",
-										"passive"
-									]
-								}
-							],
-							"properties": {
-								"active": {
-									"properties": {
-										"concurrency": {
-											"default": 10,
-											"type": "integer"
-										},
-										"healthy": {
-											"properties": {
-												"http_statuses": {
-													"default": [
-														200,
-														302
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"interval": {
-													"default": 1,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"successes": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										},
-										"host": {
-											"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-											"type": "string"
-										},
-										"http_path": {
-											"default": "/",
-											"type": "string"
-										},
-										"https_verify_certificate": {
-											"default": true,
-											"type": "boolean"
-										},
-										"port": {
-											"maximum": 65535,
-											"minimum": 1,
-											"type": "integer"
-										},
-										"req_headers": {
-											"items": {
-												"type": "string",
-												"uniqueItems": true
-											},
-											"minItems": 1,
-											"type": "array"
-										},
-										"timeout": {
-											"default": 1,
-											"type": "number"
-										},
-										"type": {
-											"default": "http",
-											"enum": [
-												"http",
-												"https",
-												"tcp"
-											],
-											"type": "string"
-										},
-										"unhealthy": {
-											"properties": {
-												"http_failures": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"http_statuses": {
-													"default": [
-														404,
-														429,
-														500,
-														501,
-														502,
-														503,
-														504,
-														505
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"interval": {
-													"default": 1,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"tcp_failures": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"timeouts": {
-													"default": 3,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										}
-									},
-									"type": "object"
-								},
-								"passive": {
-									"properties": {
-										"healthy": {
-											"properties": {
-												"http_statuses": {
-													"default": [
-														200,
-														201,
-														202,
-														203,
-														204,
-														205,
-														206,
-														207,
-														208,
-														226,
-														300,
-														301,
-														302,
-														303,
-														304,
-														305,
-														306,
-														307,
-														308
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"successes": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										},
-										"type": {
-											"default": "http",
-											"enum": [
-												"http",
-												"https",
-												"tcp"
-											],
-											"type": "string"
-										},
-										"unhealthy": {
-											"properties": {
-												"http_failures": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												},
-												"http_statuses": {
-													"default": [
-														429,
-														500,
-														503
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"tcp_failures": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												},
-												"timeouts": {
-													"default": 7,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										}
-									},
-									"type": "object"
-								}
-							},
-							"type": "object"
-						},
-						"create_time": {
-							"type": "integer"
-						},
-						"desc": {
-							"maxLength": 256,
-							"type": "string"
-						},
-						"discovery_args": {
-							"properties": {
-								"group_name": {
-									"description": "group name",
-									"type": "string"
-								},
-								"namespace_id": {
-									"description": "namespace id",
-									"type": "string"
-								}
-							},
-							"type": "object"
-						},
-						"discovery_type": {
-							"description": "discovery type",
-							"type": "string"
-						},
-						"hash_on": {
-							"default": "vars",
-							"enum": [
-								"consumer",
-								"cookie",
-								"header",
-								"vars",
-								"vars_combinations"
-							],
-							"type": "string"
-						},
-						"id": {
-							"anyOf": [
-								{
-									"maxLength": 64,
-									"minLength": 1,
-									"pattern": "^[a-zA-Z0-9-_.]+$",
-									"type": "string"
-								},
-								{
-									"minimum": 1,
-									"type": "integer"
-								}
-							]
-						},
-						"keepalive_pool": {
-							"properties": {
-								"idle_timeout": {
-									"default": 60,
-									"minimum": 0,
-									"type": "number"
-								},
-								"requests": {
-									"default": 1000,
-									"minimum": 1,
-									"type": "integer"
-								},
-								"size": {
-									"default": 320,
-									"minimum": 1,
-									"type": "integer"
-								}
-							},
-							"type": "object"
-						},
-						"key": {
-							"description": "the key of chash for dynamic load balancing",
-							"type": "string"
-						},
-						"labels": {
-							"description": "key/value pairs to specify attributes",
-							"patternProperties": {
-								".*": {
-									"description": "value of label",
-									"maxLength": 64,
-									"minLength": 1,
-									"pattern": "^\\S+$",
-									"type": "string"
-								}
-							},
-							"type": "object"
-						},
-						"name": {
-							"maxLength": 100,
-							"minLength": 1,
-							"type": "string"
-						},
-						"nodes": {
-							"anyOf": [
-								{
-									"patternProperties": {
-										".*": {
-											"description": "weight of node",
-											"minimum": 0,
-											"type": "integer"
-										}
-									},
-									"type": "object"
-								},
-								{
-									"items": {
-										"properties": {
-											"host": {
-												"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-												"type": "string"
-											},
-											"metadata": {
-												"description": "metadata of node",
-												"type": "object"
-											},
-											"port": {
-												"description": "port of node",
-												"minimum": 1,
-												"type": "integer"
-											},
-											"priority": {
-												"default": 0,
-												"description": "priority of node",
-												"type": "integer"
-											},
-											"weight": {
-												"description": "weight of node",
-												"minimum": 0,
-												"type": "integer"
-											}
-										},
-										"required": [
-											"host",
-											"port",
-											"weight"
-										],
-										"type": "object"
-									},
-									"type": "array"
-								}
-							]
-						},
-						"pass_host": {
-							"default": "pass",
-							"description": "mod of host passing",
-							"enum": [
-								"node",
-								"pass",
-								"rewrite"
-							],
-							"type": "string"
-						},
-						"retries": {
-							"minimum": 0,
-							"type": "integer"
-						},
-						"retry_timeout": {
-							"minimum": 0,
-							"type": "number"
-						},
-						"scheme": {
-							"default": "http",
-							"description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.",
-							"enum": [
-								"grpc",
-								"grpcs",
-								"http",
-								"https",
-								"kafka",
-								"tcp",
-								"tls",
-								"udp"
-							]
-						},
-						"service_name": {
-							"maxLength": 256,
-							"minLength": 1,
-							"type": "string"
-						},
-						"timeout": {
-							"properties": {
-								"connect": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								},
-								"read": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								},
-								"send": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								}
-							},
-							"required": [
-								"connect",
-								"read",
-								"send"
-							],
-							"type": "object"
-						},
-						"tls": {
-							"dependencies": {
-								"client_cert": {
-									"not": {
-										"required": [
-											"client_cert_id"
-										]
-									},
-									"required": [
-										"client_key"
-									]
-								},
-								"client_cert_id": {
-									"not": {
-										"required": [
-											"client_client",
-											"client_key"
-										]
-									}
-								},
-								"client_key": {
-									"not": {
-										"required": [
-											"client_cert_id"
-										]
-									},
-									"required": [
-										"client_cert"
-									]
-								}
-							},
-							"properties": {
-								"client_cert": {
-									"maxLength": 65536,
-									"minLength": 128,
-									"type": "string"
-								},
-								"client_cert_id": {
-									"anyOf": [
-										{
-											"maxLength": 64,
-											"minLength": 1,
-											"pattern": "^[a-zA-Z0-9-_.]+$",
-											"type": "string"
-										},
-										{
-											"minimum": 1,
-											"type": "integer"
-										}
-									]
-								},
-								"client_key": {
-									"maxLength": 65536,
-									"minLength": 128,
-									"type": "string"
-								},
-								"verify": {
-									"default": false,
-									"description": "Turn on server certificate verification, currently only kafka upstream is supported",
-									"type": "boolean"
-								}
-							},
-							"type": "object"
-						},
-						"type": {
-							"description": "algorithms of load balancing",
-							"type": "string"
-						},
-						"update_time": {
-							"type": "integer"
-						},
-						"upstream_host": {
-							"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"upstream_id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				}
-			},
-			"type": "object"
-		},
-		"ssl": {
-			"properties": {
-				"cert": {
-					"maxLength": 65536,
-					"minLength": 128,
-					"type": "string"
-				},
-				"certs": {
-					"items": {
-						"maxLength": 65536,
-						"minLength": 128,
-						"type": "string"
-					},
-					"type": "array"
-				},
-				"client": {
-					"properties": {
-						"ca": {
-							"maxLength": 65536,
-							"minLength": 128,
-							"type": "string"
-						},
-						"depth": {
-							"default": 1,
-							"minimum": 0,
-							"type": "integer"
-						}
-					},
-					"required": [
-						"ca"
-					],
-					"type": "object"
-				},
-				"create_time": {
-					"type": "integer"
-				},
-				"exptime": {
-					"minimum": 1588262400,
-					"type": "integer"
-				},
-				"id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"key": {
-					"maxLength": 65536,
-					"minLength": 128,
-					"type": "string"
-				},
-				"keys": {
-					"items": {
-						"maxLength": 65536,
-						"minLength": 128,
-						"type": "string"
-					},
-					"type": "array"
-				},
-				"labels": {
-					"description": "key/value pairs to specify attributes",
-					"patternProperties": {
-						".*": {
-							"description": "value of label",
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^\\S+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"sni": {
-					"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-					"type": "string"
-				},
-				"snis": {
-					"items": {
-						"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-						"type": "string"
-					},
-					"minItems": 1,
-					"type": "array"
-				},
-				"status": {
-					"default": 1,
-					"description": "ssl status, 1 to enable, 0 to disable",
-					"enum": [
-						0,
-						1
-					],
-					"type": "integer"
-				},
-				"type": {
-					"default": "server",
-					"description": "ssl certificate type, server to server certificate, client to client certificate for upstream",
-					"enum": [
-						"client",
-						"server"
-					],
-					"type": "string"
-				},
-				"update_time": {
-					"type": "integer"
-				},
-				"validity_end": {
-					"type": "integer"
-				},
-				"validity_start": {
-					"type": "integer"
-				}
-			},
-			"if": {
-				"properties": {
-					"type": {
-						"enum": [
-							"server"
-						]
-					}
-				}
-			},
-			"else": {
-				"required": [
-					"cert",
-					"key"
-				]
-			},
-			"then": {
-				"oneOf": [
-					{
-						"required": [
-							"cert",
-							"key",
-							"sni"
-						]
-					},
-					{
-						"required": [
-							"cert",
-							"key",
-							"snis"
-						]
-					}
-				]
-			},
-			"type": "object"
-		},
-		"stream_route": {
-			"properties": {
-				"create_time": {
-					"type": "integer"
-				},
-				"desc": {
-					"maxLength": 256,
-					"type": "string"
-				},
-				"id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"plugins": {
-					"type": "object"
-				},
-				"protocol": {
-					"properties": {
-						"conf": {
-							"description": "protocol-specific configuration",
-							"type": "object"
-						},
-						"logger": {
-							"items": {
-								"dependencies": {
-									"name": [
-										"conf"
-									]
-								},
-								"properties": {
-									"conf": {
-										"description": "logger plugin configuration",
-										"type": "object"
-									},
-									"filter": {
-										"description": "logger filter rules",
-										"type": "array"
-									},
-									"name": {
-										"type": "string"
-									}
-								}
-							},
-							"type": "array"
-						},
-						"name": {
-							"type": "string"
-						},
-						"superior_id": {
-							"anyOf": [
-								{
-									"maxLength": 64,
-									"minLength": 1,
-									"pattern": "^[a-zA-Z0-9-_.]+$",
-									"type": "string"
-								},
-								{
-									"minimum": 1,
-									"type": "integer"
-								}
-							]
-						}
-					},
-					"required": [
-						"name"
-					],
-					"type": "object"
-				},
-				"remote_addr": {
-					"anyOf": [
-						{
-							"format": "ipv4",
-							"title": "IPv4",
-							"type": "string"
-						},
-						{
-							"pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$",
-							"title": "IPv4/CIDR",
-							"type": "string"
-						},
-						{
-							"format": "ipv6",
-							"title": "IPv6",
-							"type": "string"
-						},
-						{
-							"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
-							"title": "IPv6/CIDR",
-							"type": "string"
-						}
-					],
-					"description": "client IP",
-					"type": "string"
-				},
-				"server_addr": {
-					"anyOf": [
-						{
-							"format": "ipv4",
-							"title": "IPv4",
-							"type": "string"
-						},
-						{
-							"pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$",
-							"title": "IPv4/CIDR",
-							"type": "string"
-						},
-						{
-							"format": "ipv6",
-							"title": "IPv6",
-							"type": "string"
-						},
-						{
-							"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
-							"title": "IPv6/CIDR",
-							"type": "string"
-						}
-					],
-					"description": "server IP",
-					"type": "string"
-				},
-				"server_port": {
-					"description": "server port",
-					"type": "integer"
-				},
-				"sni": {
-					"description": "server name indication",
-					"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-					"type": "string"
-				},
-				"update_time": {
-					"type": "integer"
-				},
-				"upstream": {
-					"oneOf": [
-						{
-							"required": [
-								"nodes",
-								"type"
-							]
-						},
-						{
-							"required": [
-								"discovery_type",
-								"service_name",
-								"type"
-							]
-						}
-					],
-					"properties": {
-						"checks": {
-							"anyOf": [
-								{
-									"required": [
-										"active"
-									]
-								},
-								{
-									"required": [
-										"active",
-										"passive"
-									]
-								}
-							],
-							"properties": {
-								"active": {
-									"properties": {
-										"concurrency": {
-											"default": 10,
-											"type": "integer"
-										},
-										"healthy": {
-											"properties": {
-												"http_statuses": {
-													"default": [
-														200,
-														302
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"interval": {
-													"default": 1,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"successes": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										},
-										"host": {
-											"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-											"type": "string"
-										},
-										"http_path": {
-											"default": "/",
-											"type": "string"
-										},
-										"https_verify_certificate": {
-											"default": true,
-											"type": "boolean"
-										},
-										"port": {
-											"maximum": 65535,
-											"minimum": 1,
-											"type": "integer"
-										},
-										"req_headers": {
-											"items": {
-												"type": "string",
-												"uniqueItems": true
-											},
-											"minItems": 1,
-											"type": "array"
-										},
-										"timeout": {
-											"default": 1,
-											"type": "number"
-										},
-										"type": {
-											"default": "http",
-											"enum": [
-												"http",
-												"https",
-												"tcp"
-											],
-											"type": "string"
-										},
-										"unhealthy": {
-											"properties": {
-												"http_failures": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"http_statuses": {
-													"default": [
-														404,
-														429,
-														500,
-														501,
-														502,
-														503,
-														504,
-														505
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"interval": {
-													"default": 1,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"tcp_failures": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												},
-												"timeouts": {
-													"default": 3,
-													"maximum": 254,
-													"minimum": 1,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										}
-									},
-									"type": "object"
-								},
-								"passive": {
-									"properties": {
-										"healthy": {
-											"properties": {
-												"http_statuses": {
-													"default": [
-														200,
-														201,
-														202,
-														203,
-														204,
-														205,
-														206,
-														207,
-														208,
-														226,
-														300,
-														301,
-														302,
-														303,
-														304,
-														305,
-														306,
-														307,
-														308
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"successes": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										},
-										"type": {
-											"default": "http",
-											"enum": [
-												"http",
-												"https",
-												"tcp"
-											],
-											"type": "string"
-										},
-										"unhealthy": {
-											"properties": {
-												"http_failures": {
-													"default": 5,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												},
-												"http_statuses": {
-													"default": [
-														429,
-														500,
-														503
-													],
-													"items": {
-														"maximum": 599,
-														"minimum": 200,
-														"type": "integer"
-													},
-													"minItems": 1,
-													"type": "array",
-													"uniqueItems": true
-												},
-												"tcp_failures": {
-													"default": 2,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												},
-												"timeouts": {
-													"default": 7,
-													"maximum": 254,
-													"minimum": 0,
-													"type": "integer"
-												}
-											},
-											"type": "object"
-										}
-									},
-									"type": "object"
-								}
-							},
-							"type": "object"
-						},
-						"create_time": {
-							"type": "integer"
-						},
-						"desc": {
-							"maxLength": 256,
-							"type": "string"
-						},
-						"discovery_args": {
-							"properties": {
-								"group_name": {
-									"description": "group name",
-									"type": "string"
-								},
-								"namespace_id": {
-									"description": "namespace id",
-									"type": "string"
-								}
-							},
-							"type": "object"
-						},
-						"discovery_type": {
-							"description": "discovery type",
-							"type": "string"
-						},
-						"hash_on": {
-							"default": "vars",
-							"enum": [
-								"consumer",
-								"cookie",
-								"header",
-								"vars",
-								"vars_combinations"
-							],
-							"type": "string"
-						},
-						"id": {
-							"anyOf": [
-								{
-									"maxLength": 64,
-									"minLength": 1,
-									"pattern": "^[a-zA-Z0-9-_.]+$",
-									"type": "string"
-								},
-								{
-									"minimum": 1,
-									"type": "integer"
-								}
-							]
-						},
-						"keepalive_pool": {
-							"properties": {
-								"idle_timeout": {
-									"default": 60,
-									"minimum": 0,
-									"type": "number"
-								},
-								"requests": {
-									"default": 1000,
-									"minimum": 1,
-									"type": "integer"
-								},
-								"size": {
-									"default": 320,
-									"minimum": 1,
-									"type": "integer"
-								}
-							},
-							"type": "object"
-						},
-						"key": {
-							"description": "the key of chash for dynamic load balancing",
-							"type": "string"
-						},
-						"labels": {
-							"description": "key/value pairs to specify attributes",
-							"patternProperties": {
-								".*": {
-									"description": "value of label",
-									"maxLength": 64,
-									"minLength": 1,
-									"pattern": "^\\S+$",
-									"type": "string"
-								}
-							},
-							"type": "object"
-						},
-						"name": {
-							"maxLength": 100,
-							"minLength": 1,
-							"type": "string"
-						},
-						"nodes": {
-							"anyOf": [
-								{
-									"patternProperties": {
-										".*": {
-											"description": "weight of node",
-											"minimum": 0,
-											"type": "integer"
-										}
-									},
-									"type": "object"
-								},
-								{
-									"items": {
-										"properties": {
-											"host": {
-												"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-												"type": "string"
-											},
-											"metadata": {
-												"description": "metadata of node",
-												"type": "object"
-											},
-											"port": {
-												"description": "port of node",
-												"minimum": 1,
-												"type": "integer"
-											},
-											"priority": {
-												"default": 0,
-												"description": "priority of node",
-												"type": "integer"
-											},
-											"weight": {
-												"description": "weight of node",
-												"minimum": 0,
-												"type": "integer"
-											}
-										},
-										"required": [
-											"host",
-											"port",
-											"weight"
-										],
-										"type": "object"
-									},
-									"type": "array"
-								}
-							]
-						},
-						"pass_host": {
-							"default": "pass",
-							"description": "mod of host passing",
-							"enum": [
-								"node",
-								"pass",
-								"rewrite"
-							],
-							"type": "string"
-						},
-						"retries": {
-							"minimum": 0,
-							"type": "integer"
-						},
-						"retry_timeout": {
-							"minimum": 0,
-							"type": "number"
-						},
-						"scheme": {
-							"default": "http",
-							"description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.",
-							"enum": [
-								"grpc",
-								"grpcs",
-								"http",
-								"https",
-								"kafka",
-								"tcp",
-								"tls",
-								"udp"
-							]
-						},
-						"service_name": {
-							"maxLength": 256,
-							"minLength": 1,
-							"type": "string"
-						},
-						"timeout": {
-							"properties": {
-								"connect": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								},
-								"read": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								},
-								"send": {
-									"exclusiveMinimum": 0,
-									"type": "number"
-								}
-							},
-							"required": [
-								"connect",
-								"read",
-								"send"
-							],
-							"type": "object"
-						},
-						"tls": {
-							"dependencies": {
-								"client_cert": {
-									"not": {
-										"required": [
-											"client_cert_id"
-										]
-									},
-									"required": [
-										"client_key"
-									]
-								},
-								"client_cert_id": {
-									"not": {
-										"required": [
-											"client_client",
-											"client_key"
-										]
-									}
-								},
-								"client_key": {
-									"not": {
-										"required": [
-											"client_cert_id"
-										]
-									},
-									"required": [
-										"client_cert"
-									]
-								}
-							},
-							"properties": {
-								"client_cert": {
-									"maxLength": 65536,
-									"minLength": 128,
-									"type": "string"
-								},
-								"client_cert_id": {
-									"anyOf": [
-										{
-											"maxLength": 64,
-											"minLength": 1,
-											"pattern": "^[a-zA-Z0-9-_.]+$",
-											"type": "string"
-										},
-										{
-											"minimum": 1,
-											"type": "integer"
-										}
-									]
-								},
-								"client_key": {
-									"maxLength": 65536,
-									"minLength": 128,
-									"type": "string"
-								},
-								"verify": {
-									"default": false,
-									"description": "Turn on server certificate verification, currently only kafka upstream is supported",
-									"type": "boolean"
-								}
-							},
-							"type": "object"
-						},
-						"type": {
-							"description": "algorithms of load balancing",
-							"type": "string"
-						},
-						"update_time": {
-							"type": "integer"
-						},
-						"upstream_host": {
-							"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"upstream_id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				}
-			},
-			"type": "object"
-		},
-		"upstream": {
-			"oneOf": [
-				{
-					"required": [
-						"nodes",
-						"type"
-					]
-				},
-				{
-					"required": [
-						"discovery_type",
-						"service_name",
-						"type"
-					]
-				}
-			],
-			"properties": {
-				"checks": {
-					"anyOf": [
-						{
-							"required": [
-								"active"
-							]
-						},
-						{
-							"required": [
-								"active",
-								"passive"
-							]
-						}
-					],
-					"properties": {
-						"active": {
-							"properties": {
-								"concurrency": {
-									"default": 10,
-									"type": "integer"
-								},
-								"healthy": {
-									"properties": {
-										"http_statuses": {
-											"default": [
-												200,
-												302
-											],
-											"items": {
-												"maximum": 599,
-												"minimum": 200,
-												"type": "integer"
-											},
-											"minItems": 1,
-											"type": "array",
-											"uniqueItems": true
-										},
-										"interval": {
-											"default": 1,
-											"minimum": 1,
-											"type": "integer"
-										},
-										"successes": {
-											"default": 2,
-											"maximum": 254,
-											"minimum": 1,
-											"type": "integer"
-										}
-									},
-									"type": "object"
-								},
-								"host": {
-									"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-									"type": "string"
-								},
-								"http_path": {
-									"default": "/",
-									"type": "string"
-								},
-								"https_verify_certificate": {
-									"default": true,
-									"type": "boolean"
-								},
-								"port": {
-									"maximum": 65535,
-									"minimum": 1,
-									"type": "integer"
-								},
-								"req_headers": {
-									"items": {
-										"type": "string",
-										"uniqueItems": true
-									},
-									"minItems": 1,
-									"type": "array"
-								},
-								"timeout": {
-									"default": 1,
-									"type": "number"
-								},
-								"type": {
-									"default": "http",
-									"enum": [
-										"http",
-										"https",
-										"tcp"
-									],
-									"type": "string"
-								},
-								"unhealthy": {
-									"properties": {
-										"http_failures": {
-											"default": 5,
-											"maximum": 254,
-											"minimum": 1,
-											"type": "integer"
-										},
-										"http_statuses": {
-											"default": [
-												404,
-												429,
-												500,
-												501,
-												502,
-												503,
-												504,
-												505
-											],
-											"items": {
-												"maximum": 599,
-												"minimum": 200,
-												"type": "integer"
-											},
-											"minItems": 1,
-											"type": "array",
-											"uniqueItems": true
-										},
-										"interval": {
-											"default": 1,
-											"minimum": 1,
-											"type": "integer"
-										},
-										"tcp_failures": {
-											"default": 2,
-											"maximum": 254,
-											"minimum": 1,
-											"type": "integer"
-										},
-										"timeouts": {
-											"default": 3,
-											"maximum": 254,
-											"minimum": 1,
-											"type": "integer"
-										}
-									},
-									"type": "object"
-								}
-							},
-							"type": "object"
-						},
-						"passive": {
-							"properties": {
-								"healthy": {
-									"properties": {
-										"http_statuses": {
-											"default": [
-												200,
-												201,
-												202,
-												203,
-												204,
-												205,
-												206,
-												207,
-												208,
-												226,
-												300,
-												301,
-												302,
-												303,
-												304,
-												305,
-												306,
-												307,
-												308
-											],
-											"items": {
-												"maximum": 599,
-												"minimum": 200,
-												"type": "integer"
-											},
-											"minItems": 1,
-											"type": "array",
-											"uniqueItems": true
-										},
-										"successes": {
-											"default": 5,
-											"maximum": 254,
-											"minimum": 0,
-											"type": "integer"
-										}
-									},
-									"type": "object"
-								},
-								"type": {
-									"default": "http",
-									"enum": [
-										"http",
-										"https",
-										"tcp"
-									],
-									"type": "string"
-								},
-								"unhealthy": {
-									"properties": {
-										"http_failures": {
-											"default": 5,
-											"maximum": 254,
-											"minimum": 0,
-											"type": "integer"
-										},
-										"http_statuses": {
-											"default": [
-												429,
-												500,
-												503
-											],
-											"items": {
-												"maximum": 599,
-												"minimum": 200,
-												"type": "integer"
-											},
-											"minItems": 1,
-											"type": "array",
-											"uniqueItems": true
-										},
-										"tcp_failures": {
-											"default": 2,
-											"maximum": 254,
-											"minimum": 0,
-											"type": "integer"
-										},
-										"timeouts": {
-											"default": 7,
-											"maximum": 254,
-											"minimum": 0,
-											"type": "integer"
-										}
-									},
-									"type": "object"
-								}
-							},
-							"type": "object"
-						}
-					},
-					"type": "object"
-				},
-				"create_time": {
-					"type": "integer"
-				},
-				"desc": {
-					"maxLength": 256,
-					"type": "string"
-				},
-				"discovery_args": {
-					"properties": {
-						"group_name": {
-							"description": "group name",
-							"type": "string"
-						},
-						"namespace_id": {
-							"description": "namespace id",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"discovery_type": {
-					"description": "discovery type",
-					"type": "string"
-				},
-				"hash_on": {
-					"default": "vars",
-					"enum": [
-						"consumer",
-						"cookie",
-						"header",
-						"vars",
-						"vars_combinations"
-					],
-					"type": "string"
-				},
-				"id": {
-					"anyOf": [
-						{
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^[a-zA-Z0-9-_.]+$",
-							"type": "string"
-						},
-						{
-							"minimum": 1,
-							"type": "integer"
-						}
-					]
-				},
-				"keepalive_pool": {
-					"properties": {
-						"idle_timeout": {
-							"default": 60,
-							"minimum": 0,
-							"type": "number"
-						},
-						"requests": {
-							"default": 1000,
-							"minimum": 1,
-							"type": "integer"
-						},
-						"size": {
-							"default": 320,
-							"minimum": 1,
-							"type": "integer"
-						}
-					},
-					"type": "object"
-				},
-				"key": {
-					"description": "the key of chash for dynamic load balancing",
-					"type": "string"
-				},
-				"labels": {
-					"description": "key/value pairs to specify attributes",
-					"patternProperties": {
-						".*": {
-							"description": "value of label",
-							"maxLength": 64,
-							"minLength": 1,
-							"pattern": "^\\S+$",
-							"type": "string"
-						}
-					},
-					"type": "object"
-				},
-				"name": {
-					"maxLength": 100,
-					"minLength": 1,
-					"type": "string"
-				},
-				"nodes": {
-					"anyOf": [
-						{
-							"patternProperties": {
-								".*": {
-									"description": "weight of node",
-									"minimum": 0,
-									"type": "integer"
-								}
-							},
-							"type": "object"
-						},
-						{
-							"items": {
-								"properties": {
-									"host": {
-										"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-										"type": "string"
-									},
-									"metadata": {
-										"description": "metadata of node",
-										"type": "object"
-									},
-									"port": {
-										"description": "port of node",
-										"minimum": 1,
-										"type": "integer"
-									},
-									"priority": {
-										"default": 0,
-										"description": "priority of node",
-										"type": "integer"
-									},
-									"weight": {
-										"description": "weight of node",
-										"minimum": 0,
-										"type": "integer"
-									}
-								},
-								"required": [
-									"host",
-									"port",
-									"weight"
-								],
-								"type": "object"
-							},
-							"type": "array"
-						}
-					]
-				},
-				"pass_host": {
-					"default": "pass",
-					"description": "mod of host passing",
-					"enum": [
-						"node",
-						"pass",
-						"rewrite"
-					],
-					"type": "string"
-				},
-				"retries": {
-					"minimum": 0,
-					"type": "integer"
-				},
-				"retry_timeout": {
-					"minimum": 0,
-					"type": "number"
-				},
-				"scheme": {
-					"default": "http",
-					"description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.",
-					"enum": [
-						"grpc",
-						"grpcs",
-						"http",
-						"https",
-						"kafka",
-						"tcp",
-						"tls",
-						"udp"
-					]
-				},
-				"service_name": {
-					"maxLength": 256,
-					"minLength": 1,
-					"type": "string"
-				},
-				"timeout": {
-					"properties": {
-						"connect": {
-							"exclusiveMinimum": 0,
-							"type": "number"
-						},
-						"read": {
-							"exclusiveMinimum": 0,
-							"type": "number"
-						},
-						"send": {
-							"exclusiveMinimum": 0,
-							"type": "number"
-						}
-					},
-					"required": [
-						"connect",
-						"read",
-						"send"
-					],
-					"type": "object"
-				},
-				"tls": {
-					"dependencies": {
-						"client_cert": {
-							"not": {
-								"required": [
-									"client_cert_id"
-								]
-							},
-							"required": [
-								"client_key"
-							]
-						},
-						"client_cert_id": {
-							"not": {
-								"required": [
-									"client_client",
-									"client_key"
-								]
-							}
-						},
-						"client_key": {
-							"not": {
-								"required": [
-									"client_cert_id"
-								]
-							},
-							"required": [
-								"client_cert"
-							]
-						}
-					},
-					"properties": {
-						"client_cert": {
-							"maxLength": 65536,
-							"minLength": 128,
-							"type": "string"
-						},
-						"client_cert_id": {
-							"anyOf": [
-								{
-									"maxLength": 64,
-									"minLength": 1,
-									"pattern": "^[a-zA-Z0-9-_.]+$",
-									"type": "string"
-								},
-								{
-									"minimum": 1,
-									"type": "integer"
-								}
-							]
-						},
-						"client_key": {
-							"maxLength": 65536,
-							"minLength": 128,
-							"type": "string"
-						},
-						"verify": {
-							"default": false,
-							"description": "Turn on server certificate verification, currently only kafka upstream is supported",
-							"type": "boolean"
-						}
-					},
-					"type": "object"
-				},
-				"type": {
-					"description": "algorithms of load balancing",
-					"type": "string"
-				},
-				"update_time": {
-					"type": "integer"
-				},
-				"upstream_host": {
-					"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-					"type": "string"
-				}
-			},
-			"type": "object"
-		},
-		"upstream_hash_header_schema": {
-			"pattern": "^[a-zA-Z0-9-_]+$",
-			"type": "string"
-		},
-		"upstream_hash_vars_schema": {
-			"pattern": "^((uri|server_name|server_addr|request_uri|remote_port|remote_addr|query_string|host|hostname)|arg_[0-9a-zA-z_-]+)$",
-			"type": "string"
-		}
-	},
-	"plugins": {
-		"ai": {
-			"priority": 22900,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					}
-				}
-			},
-			"scope": "global",
-			"version": 0.1
-		},
-		"api-breaker": {
-			"priority": 1005,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"break_response_body": {
-						"type": "string"
-					},
-					"break_response_code": {
-						"maximum": 599,
-						"minimum": 200,
-						"type": "integer"
-					},
-					"break_response_headers": {
-						"items": {
-							"properties": {
-								"key": {
-									"minLength": 1,
-									"type": "string"
-								},
-								"value": {
-									"minLength": 1,
-									"type": "string"
-								}
-							},
-							"required": [
-								"key",
-								"value"
-							],
-							"type": "object"
-						},
-						"type": "array"
-					},
-					"healthy": {
-						"default": {
-							"http_statuses": [
-								200
-							],
-							"successes": 3
-						},
-						"properties": {
-							"http_statuses": {
-								"default": [
-									200
-								],
-								"items": {
-									"maximum": 499,
-									"minimum": 200,
-									"type": "integer"
-								},
-								"minItems": 1,
-								"type": "array",
-								"uniqueItems": true
-							},
-							"successes": {
-								"default": 3,
-								"minimum": 1,
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"max_breaker_sec": {
-						"default": 300,
-						"minimum": 3,
-						"type": "integer"
-					},
-					"unhealthy": {
-						"default": {
-							"failures": 3,
-							"http_statuses": [
-								500
-							]
-						},
-						"properties": {
-							"failures": {
-								"default": 3,
-								"minimum": 1,
-								"type": "integer"
-							},
-							"http_statuses": {
-								"default": [
-									500
-								],
-								"items": {
-									"maximum": 599,
-									"minimum": 500,
-									"type": "integer"
-								},
-								"minItems": 1,
-								"type": "array",
-								"uniqueItems": true
-							}
-						},
-						"type": "object"
-					}
-				},
-				"required": [
-					"break_response_code"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"authz-casbin": {
-			"metadata_schema": {
-				"properties": {
-					"model": {
-						"type": "string"
-					},
-					"policy": {
-						"type": "string"
-					}
-				},
-				"required": [
-					"model",
-					"policy"
-				],
-				"type": "object"
-			},
-			"priority": 2560,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"oneOf": [
-					{
-						"required": [
-							"model_path",
-							"policy_path",
-							"username"
-						]
-					},
-					{
-						"required": [
-							"model",
-							"policy",
-							"username"
-						]
-					}
-				],
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"model": {
-						"type": "string"
-					},
-					"model_path": {
-						"type": "string"
-					},
-					"policy": {
-						"type": "string"
-					},
-					"policy_path": {
-						"type": "string"
-					},
-					"username": {
-						"type": "string"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"authz-casdoor": {
-			"priority": 2559,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"callback_url": {
-						"pattern": "^[^%?]+[^/]$",
-						"type": "string"
-					},
-					"client_id": {
-						"type": "string"
-					},
-					"client_secret": {
-						"type": "string"
-					},
-					"endpoint_addr": {
-						"pattern": "^[^%?]+[^/]$",
-						"type": "string"
-					}
-				},
-				"required": [
-					"callback_url",
-					"client_id",
-					"client_secret",
-					"endpoint_addr"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"authz-keycloak": {
-			"priority": 2000,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"allOf": [
-					{
-						"anyOf": [
-							{
-								"required": [
-									"discovery"
-								]
-							},
-							{
-								"required": [
-									"token_endpoint"
-								]
-							}
-						]
-					},
-					{
-						"anyOf": [
-							{
-								"properties": {
-									"lazy_load_paths": {
-										"enum": [
-											false
-										]
-									}
-								}
-							},
-							{
-								"anyOf": [
-									{
-										"required": [
-											"discovery"
-										]
-									},
-									{
-										"required": [
-											"resource_registration_endpoint"
-										]
-									}
-								],
-								"properties": {
-									"lazy_load_paths": {
-										"enum": [
-											true
-										]
-									}
-								}
-							}
-						]
-					}
-				],
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"access_denied_redirect_uri": {
-						"maxLength": 2048,
-						"minLength": 1,
-						"type": "string"
-					},
-					"access_token_expires_in": {
-						"default": 300,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"access_token_expires_leeway": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"cache_ttl_seconds": {
-						"default": 86400,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"client_id": {
-						"maxLength": 100,
-						"minLength": 1,
-						"type": "string"
-					},
-					"client_secret": {
-						"maxLength": 100,
-						"minLength": 1,
-						"type": "string"
-					},
-					"discovery": {
-						"maxLength": 4096,
-						"minLength": 1,
-						"type": "string"
-					},
-					"grant_type": {
-						"default": "urn:ietf:params:oauth:grant-type:uma-ticket",
-						"enum": [
-							"urn:ietf:params:oauth:grant-type:uma-ticket"
-						],
-						"maxLength": 100,
-						"minLength": 1,
-						"type": "string"
-					},
-					"http_method_as_scope": {
-						"default": false,
-						"type": "boolean"
-					},
-					"keepalive": {
-						"default": true,
-						"type": "boolean"
-					},
-					"keepalive_pool": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"keepalive_timeout": {
-						"default": 60000,
-						"minimum": 1000,
-						"type": "integer"
-					},
-					"lazy_load_paths": {
-						"default": false,
-						"type": "boolean"
-					},
-					"password_grant_token_generation_incoming_uri": {
-						"maxLength": 4096,
-						"minLength": 1,
-						"type": "string"
-					},
-					"permissions": {
-						"default": {},
-						"items": {
-							"maxLength": 100,
-							"minLength": 1,
-							"type": "string"
-						},
-						"type": "array",
-						"uniqueItems": true
-					},
-					"policy_enforcement_mode": {
-						"default": "ENFORCING",
-						"enum": [
-							"ENFORCING",
-							"PERMISSIVE"
-						],
-						"type": "string"
-					},
-					"refresh_token_expires_in": {
-						"default": 3600,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"refresh_token_expires_leeway": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"resource_registration_endpoint": {
-						"maxLength": 4096,
-						"minLength": 1,
-						"type": "string"
-					},
-					"ssl_verify": {
-						"default": true,
-						"type": "boolean"
-					},
-					"timeout": {
-						"default": 3000,
-						"minimum": 1000,
-						"type": "integer"
-					},
-					"token_endpoint": {
-						"maxLength": 4096,
-						"minLength": 1,
-						"type": "string"
-					}
-				},
-				"required": [
-					"client_id"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"aws-lambda": {
-			"priority": -1899,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"authorization": {
-						"properties": {
-							"apikey": {
-								"type": "string"
-							},
-							"iam": {
-								"properties": {
-									"accesskey": {
-										"description": "access key id from from aws iam console",
-										"type": "string"
-									},
-									"aws_region": {
-										"default": "us-east-1",
-										"description": "the aws region that is receiving the request",
-										"type": "string"
-									},
-									"secretkey": {
-										"description": "secret access key from from aws iam console",
-										"type": "string"
-									},
-									"service": {
-										"default": "execute-api",
-										"description": "the service that is receiving the request",
-										"type": "string"
-									}
-								},
-								"required": [
-									"accesskey",
-									"secretkey"
-								],
-								"type": "object"
-							}
-						},
-						"type": "object"
-					},
-					"function_uri": {
-						"type": "string"
-					},
-					"keepalive": {
-						"default": true,
-						"type": "boolean"
-					},
-					"keepalive_pool": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"keepalive_timeout": {
-						"default": 60000,
-						"minimum": 1000,
-						"type": "integer"
-					},
-					"ssl_verify": {
-						"default": true,
-						"type": "boolean"
-					},
-					"timeout": {
-						"default": 3000,
-						"minimum": 100,
-						"type": "integer"
-					}
-				},
-				"required": [
-					"function_uri"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"azure-functions": {
-			"metadata_schema": {
-				"properties": {
-					"master_apikey": {
-						"default": "",
-						"type": "string"
-					},
-					"master_clientid": {
-						"default": "",
-						"type": "string"
-					}
-				},
-				"type": "object"
-			},
-			"priority": -1900,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"authorization": {
-						"properties": {
-							"apikey": {
-								"type": "string"
-							},
-							"clientid": {
-								"type": "string"
-							}
-						},
-						"type": "object"
-					},
-					"function_uri": {
-						"type": "string"
-					},
-					"keepalive": {
-						"default": true,
-						"type": "boolean"
-					},
-					"keepalive_pool": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"keepalive_timeout": {
-						"default": 60000,
-						"minimum": 1000,
-						"type": "integer"
-					},
-					"ssl_verify": {
-						"default": true,
-						"type": "boolean"
-					},
-					"timeout": {
-						"default": 3000,
-						"minimum": 100,
-						"type": "integer"
-					}
-				},
-				"required": [
-					"function_uri"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"basic-auth": {
-			"consumer_schema": {
-				"properties": {
-					"password": {
-						"type": "string"
-					},
-					"username": {
-						"type": "string"
-					}
-				},
-				"required": [
-					"password",
-					"username"
-				],
-				"title": "work with consumer object",
-				"type": "object"
-			},
-			"priority": 2520,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"hide_credentials": {
-						"default": false,
-						"type": "boolean"
-					}
-				},
-				"title": "work with route or service object",
-				"type": "object"
-			},
-			"type": "auth",
-			"version": 0.1
-		},
-		"batch-requests": {
-			"metadata_schema": {
-				"properties": {
-					"max_body_size": {
-						"default": 1048576,
-						"description": "max pipeline body size in bytes",
-						"exclusiveMinimum": 0,
-						"type": "integer"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 4010,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"scope": "global",
-			"version": 0.1
-		},
-		"cas-auth": {
-			"priority": 2597,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"cas_callback_uri": {
-						"type": "string"
-					},
-					"idp_uri": {
-						"type": "string"
-					},
-					"logout_uri": {
-						"type": "string"
-					}
-				},
-				"required": [
-					"cas_callback_uri",
-					"idp_uri",
-					"logout_uri"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"clickhouse-logger": {
-			"metadata_schema": {
-				"properties": {
-					"log_format": {
-						"default": {
-							"@timestamp": "$time_iso8601",
-							"client_ip": "$remote_addr",
-							"host": "$host"
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 398,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"oneOf": [
-					{
-						"required": [
-							"database",
-							"endpoint_addr",
-							"logtable",
-							"password",
-							"user"
-						]
-					},
-					{
-						"required": [
-							"database",
-							"endpoint_addrs",
-							"logtable",
-							"password",
-							"user"
-						]
-					}
-				],
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"batch_max_size": {
-						"default": 1000,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"buffer_duration": {
-						"default": 60,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"database": {
-						"default": "",
-						"type": "string"
-					},
-					"endpoint_addr": {
-						"pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?",
-						"type": "string"
-					},
-					"endpoint_addrs": {
-						"items": {
-							"pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?",
-							"type": "string"
-						},
-						"minItems": 1,
-						"type": "array"
-					},
-					"inactive_timeout": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"logtable": {
-						"default": "",
-						"type": "string"
-					},
-					"max_retry_count": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"name": {
-						"default": "clickhouse-logger",
-						"type": "string"
-					},
-					"password": {
-						"default": "",
-						"type": "string"
-					},
-					"retry_delay": {
-						"default": 1,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"ssl_verify": {
-						"default": true,
-						"type": "boolean"
-					},
-					"timeout": {
-						"default": 3,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"user": {
-						"default": "",
-						"type": "string"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"client-control": {
-			"priority": 22000,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"max_body_size": {
-						"minimum": 0,
-						"type": "integer"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"consumer-restriction": {
-			"priority": 2400,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"anyOf": [
-					{
-						"required": [
-							"blacklist"
-						]
-					},
-					{
-						"required": [
-							"whitelist"
-						]
-					},
-					{
-						"required": [
-							"allowed_by_methods"
-						]
-					}
-				],
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"allowed_by_methods": {
-						"items": {
-							"properties": {
-								"methods": {
-									"items": {
-										"description": "HTTP method",
-										"enum": [
-											"CONNECT",
-											"DELETE",
-											"GET",
-											"HEAD",
-											"OPTIONS",
-											"PATCH",
-											"POST",
-											"PURGE",
-											"PUT",
-											"TRACE"
-										],
-										"type": "string"
-									},
-									"minItems": 1,
-									"type": "array"
-								},
-								"user": {
-									"type": "string"
-								}
-							},
-							"type": "object"
-						},
-						"type": "array"
-					},
-					"blacklist": {
-						"items": {
-							"type": "string"
-						},
-						"minItems": 1,
-						"type": "array"
-					},
-					"rejected_code": {
-						"default": 403,
-						"minimum": 200,
-						"type": "integer"
-					},
-					"rejected_msg": {
-						"type": "string"
-					},
-					"type": {
-						"default": "consumer_name",
-						"enum": [
-							"consumer_name",
-							"route_id",
-							"service_id"
-						],
-						"type": "string"
-					},
-					"whitelist": {
-						"items": {
-							"type": "string"
-						},
-						"minItems": 1,
-						"type": "array"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"cors": {
-			"metadata_schema": {
-				"properties": {
-					"allow_origins": {
-						"additionalProperties": {
-							"pattern": "^(\\*|\\*\\*|null|\\w+://[^,]+(,\\w+://[^,]+)*)$",
-							"type": "string"
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 4000,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"allow_credential": {
-						"default": false,
-						"description": "allow client append credential. according to CORS specification,if you set this option to 'true', you can not use '*' for other options.",
-						"type": "boolean"
-					},
-					"allow_headers": {
-						"default": "*",
-						"description": "you can use '*' to allow all header when no credentials,'**' to allow forcefully(it will bring some security risks, be carefully),multiple header use ',' to split. default: *.",
-						"type": "string"
-					},
-					"allow_methods": {
-						"default": "*",
-						"description": "you can use '*' to allow all methods when no credentials,'**' to allow forcefully(it will bring some security risks, be carefully),multiple method use ',' to split. default: *.",
-						"type": "string"
-					},
-					"allow_origins": {
-						"default": "*",
-						"description": "you can use '*' to allow all origins when no credentials,'**' to allow forcefully(it will bring some security risks, be carefully),multiple origin use ',' to split. default: *.",
-						"pattern": "^(\\*|\\*\\*|null|\\w+://[^,]+(,\\w+://[^,]+)*)$",
-						"type": "string"
-					},
-					"allow_origins_by_metadata": {
-						"description": "set allowed origins by referencing origins in plugin metadata",
-						"items": {
-							"maxLength": 4096,
-							"minLength": 1,
-							"type": "string"
-						},
-						"minItems": 1,
-						"type": "array",
-						"uniqueItems": true
-					},
-					"allow_origins_by_regex": {
-						"description": "you can use regex to allow specific origins when no credentials,for example use [.*\\.test.com] to allow a.test.com and b.test.com",
-						"items": {
-							"maxLength": 4096,
-							"minLength": 1,
-							"type": "string"
-						},
-						"minItems": 1,
-						"type": "array",
-						"uniqueItems": true
-					},
-					"expose_headers": {
-						"default": "*",
-						"description": "you can use '*' to expose all header when no credentials,'**' to allow forcefully(it will bring some security risks, be carefully),multiple header use ',' to split. default: *.",
-						"type": "string"
-					},
-					"max_age": {
-						"default": 5,
-						"description": "maximum number of seconds the results can be cached.-1 means no cached, the max value is depend on browser,more details plz check MDN. default: 5.",
-						"type": "integer"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"csrf": {
-			"priority": 2980,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"expires": {
-						"default": 7200,
-						"description": "expires time(s) for csrf token",
-						"type": "integer"
-					},
-					"key": {
-						"description": "use to generate csrf token",
-						"type": "string"
-					},
-					"name": {
-						"default": "apisix-csrf-token",
-						"description": "the csrf token name",
-						"type": "string"
-					}
-				},
-				"required": [
-					"key"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"datadog": {
-			"metadata_schema": {
-				"properties": {
-					"constant_tags": {
-						"default": [
-							"source:apisix"
-						],
-						"items": {
-							"type": "string"
-						},
-						"type": "array"
-					},
-					"host": {
-						"default": "127.0.0.1",
-						"type": "string"
-					},
-					"namespace": {
-						"default": "apisix",
-						"type": "string"
-					},
-					"port": {
-						"default": 8125,
-						"minimum": 0,
-						"type": "integer"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 495,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"batch_max_size": {
-						"default": 1000,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"buffer_duration": {
-						"default": 60,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"inactive_timeout": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"max_retry_count": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"name": {
-						"default": "datadog",
-						"type": "string"
-					},
-					"prefer_name": {
-						"default": true,
-						"type": "boolean"
-					},
-					"retry_delay": {
-						"default": 1,
-						"minimum": 0,
-						"type": "integer"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"dubbo-proxy": {
-			"priority": 507,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"method": {
-						"minLength": 1,
-						"type": "string"
-					},
-					"service_name": {
-						"minLength": 1,
-						"type": "string"
-					},
-					"service_version": {
-						"pattern": "^\\d+\\.\\d+\\.\\d+",
-						"type": "string"
-					}
-				},
-				"required": [
-					"service_name",
-					"service_version"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"echo": {
-			"priority": 412,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"anyOf": [
-					{
-						"required": [
-							"before_body"
-						]
-					},
-					{
-						"required": [
-							"body"
-						]
-					},
-					{
-						"required": [
-							"after_body"
-						]
-					}
-				],
-				"minProperties": 1,
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"after_body": {
-						"description": "body after the modification of filter phase.",
-						"type": "string"
-					},
-					"before_body": {
-						"description": "body before the filter phase.",
-						"type": "string"
-					},
-					"body": {
-						"description": "body to replace upstream response.",
-						"type": "string"
-					},
-					"headers": {
-						"description": "new headers for response",
-						"minProperties": 1,
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"elasticsearch-logger": {
-			"metadata_schema": {
-				"properties": {
-					"log_format": {
-						"default": {
-							"@timestamp": "$time_iso8601",
-							"client_ip": "$remote_addr",
-							"host": "$host"
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 413,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"auth": {
-						"properties": {
-							"password": {
-								"minLength": 1,
-								"type": "string"
-							},
-							"username": {
-								"minLength": 1,
-								"type": "string"
-							}
-						},
-						"required": [
-							"password",
-							"username"
-						],
-						"type": "object"
-					},
-					"batch_max_size": {
-						"default": 1000,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"buffer_duration": {
-						"default": 60,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"endpoint_addr": {
-						"pattern": "[^/]$",
-						"type": "string"
-					},
-					"field": {
-						"properties": {
-							"index": {
-								"type": "string"
-							},
-							"type": {
-								"type": "string"
-							}
-						},
-						"required": [
-							"index"
-						],
-						"type": "object"
-					},
-					"inactive_timeout": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"max_retry_count": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"name": {
-						"default": "elasticsearch-logger",
-						"type": "string"
-					},
-					"retry_delay": {
-						"default": 1,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"ssl_verify": {
-						"default": true,
-						"type": "boolean"
-					},
-					"timeout": {
-						"default": 10,
-						"minimum": 1,
-						"type": "integer"
-					}
-				},
-				"required": [
-					"endpoint_addr",
-					"field"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"error-log-logger": {
-			"metadata_schema": {
-				"oneOf": [
-					{
-						"required": [
-							"skywalking"
-						]
-					},
-					{
-						"required": [
-							"tcp"
-						]
-					},
-					{
-						"required": [
-							"clickhouse"
-						]
-					},
-					{
-						"required": [
-							"host",
-							"port"
-						]
-					}
-				],
-				"properties": {
-					"batch_max_size": {
-						"default": 1000,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"buffer_duration": {
-						"default": 60,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"clickhouse": {
-						"properties": {
-							"database": {
-								"default": "",
-								"type": "string"
-							},
-							"endpoint_addr": {
-								"1": {
-									"pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?",
-									"type": "string"
-								},
-								"default": "http://127.0.0.1:8123"
-							},
-							"logtable": {
-								"default": "",
-								"type": "string"
-							},
-							"password": {
-								"default": "",
-								"type": "string"
-							},
-							"user": {
-								"default": "default",
-								"type": "string"
-							}
-						},
-						"required": [
-							"database",
-							"endpoint_addr",
-							"logtable",
-							"password",
-							"user"
-						],
-						"type": "object"
-					},
-					"inactive_timeout": {
-						"default": 3,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"keepalive": {
-						"default": 30,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"level": {
-						"default": "WARN",
-						"enum": [
-							"ALERT",
-							"CRIT",
-							"DEBUG",
-							"EMERG",
-							"ERR",
-							"ERROR",
-							"INFO",
-							"NOTICE",
-							"STDERR",
-							"WARN"
-						],
-						"type": "string"
-					},
-					"max_retry_count": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"name": {
-						"default": "error-log-logger",
-						"type": "string"
-					},
-					"retry_delay": {
-						"default": 1,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"skywalking": {
-						"properties": {
-							"endpoint_addr": {
-								"default": "http://127.0.0.1:12900/v3/logs"
-							},
-							"service_instance_name": {
-								"default": "APISIX Service Instance",
-								"type": "string"
-							},
-							"service_name": {
-								"default": "APISIX",
-								"type": "string"
-							}
-						},
-						"type": "object"
-					},
-					"tcp": {
-						"properties": {
-							"host": {
-								"pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$",
-								"type": "string"
-							},
-							"port": {
-								"minimum": 0,
-								"type": "integer"
-							},
-							"tls": {
-								"default": false,
-								"type": "boolean"
-							},
-							"tls_server_name": {
-								"type": "string"
-							}
-						},
-						"required": [
-							"host",
-							"port"
-						],
-						"type": "object"
-					},
-					"timeout": {
-						"default": 3,
-						"minimum": 1,
-						"type": "integer"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 1091,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"scope": "global",
-			"version": 0.1
-		},
-		"example-plugin": {
-			"metadata_schema": {
-				"properties": {
-					"ikey": {
-						"minimum": 0,
-						"type": "number"
-					},
-					"skey": {
-						"type": "string"
-					}
-				},
-				"required": [
-					"ikey",
-					"skey"
-				],
-				"type": "object"
-			},
-			"priority": 0,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"i": {
-						"minimum": 0,
-						"type": "number"
-					},
-					"ip": {
-						"type": "string"
-					},
-					"port": {
-						"type": "integer"
-					},
-					"s": {
-						"type": "string"
-					},
-					"t": {
-						"minItems": 1,
-						"type": "array"
-					}
-				},
-				"required": [
-					"i"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"ext-plugin-post-req": {
-			"priority": -3000,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"allow_degradation": {
-						"default": false,
-						"type": "boolean"
-					},
-					"conf": {
-						"items": {
-							"properties": {
-								"name": {
-									"maxLength": 128,
-									"minLength": 1,
-									"type": "string"
-								},
-								"value": {
-									"type": "string"
-								}
-							},
-							"required": [
-								"name",
-								"value"
-							],
-							"type": "object"
-						},
-						"minItems": 1,
-						"type": "array"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"ext-plugin-post-resp": {
-			"priority": -4000,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"allow_degradation": {
-						"default": false,
-						"type": "boolean"
-					},
-					"conf": {
-						"items": {
-							"properties": {
-								"name": {
-									"maxLength": 128,
-									"minLength": 1,
-									"type": "string"
-								},
-								"value": {
-									"type": "string"
-								}
-							},
-							"required": [
-								"name",
-								"value"
-							],
-							"type": "object"
-						},
-						"minItems": 1,
-						"type": "array"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"ext-plugin-pre-req": {
-			"priority": 12000,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"allow_degradation": {
-						"default": false,
-						"type": "boolean"
-					},
-					"conf": {
-						"items": {
-							"properties": {
-								"name": {
-									"maxLength": 128,
-									"minLength": 1,
-									"type": "string"
-								},
-								"value": {
-									"type": "string"
-								}
-							},
-							"required": [
-								"name",
-								"value"
-							],
-							"type": "object"
-						},
-						"minItems": 1,
-						"type": "array"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"fault-injection": {
-			"priority": 11000,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"minProperties": 1,
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"abort": {
-						"properties": {
-							"body": {
-								"minLength": 0,
-								"type": "string"
-							},
-							"http_status": {
-								"minimum": 200,
-								"type": "integer"
-							},
-							"percentage": {
-								"maximum": 100,
-								"minimum": 0,
-								"type": "integer"
-							},
-							"vars": {
-								"items": {
-									"type": "array"
-								},
-								"maxItems": 20,
-								"type": "array"
-							}
-						},
-						"required": [
-							"http_status"
-						],
-						"type": "object"
-					},
-					"delay": {
-						"properties": {
-							"duration": {
-								"minimum": 0,
-								"type": "number"
-							},
-							"percentage": {
-								"maximum": 100,
-								"minimum": 0,
-								"type": "integer"
-							},
-							"vars": {
-								"items": {
-									"type": "array"
-								},
-								"maxItems": 20,
-								"type": "array"
-							}
-						},
-						"required": [
-							"duration"
-						],
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"file-logger": {
-			"metadata_schema": {
-				"properties": {
-					"log_format": {
-						"default": {
-							"@timestamp": "$time_iso8601",
-							"client_ip": "$remote_addr",
-							"host": "$host"
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 399,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"path": {
-						"type": "string"
-					}
-				},
-				"required": [
-					"path"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"forward-auth": {
-			"priority": 2002,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"client_headers": {
-						"default": {},
-						"description": "authorization response header that will be sent tothe client when authorizing failed",
-						"items": {
-							"type": "string"
-						},
-						"type": "array"
-					},
-					"keepalive": {
-						"default": true,
-						"type": "boolean"
-					},
-					"keepalive_pool": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"keepalive_timeout": {
-						"default": 60000,
-						"minimum": 1000,
-						"type": "integer"
-					},
-					"request_headers": {
-						"default": {},
-						"description": "client request header that will be sent to the authorization service",
-						"items": {
-							"type": "string"
-						},
-						"type": "array"
-					},
-					"request_method": {
-						"default": "GET",
-						"description": "the method for client to request the authorization service",
-						"enum": [
-							"GET",
-							"POST"
-						],
-						"type": "string"
-					},
-					"ssl_verify": {
-						"default": true,
-						"type": "boolean"
-					},
-					"timeout": {
-						"default": 3000,
-						"description": "timeout in milliseconds",
-						"maximum": 60000,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"upstream_headers": {
-						"default": {},
-						"description": "authorization response header that will be sent to the upstream",
-						"items": {
-							"type": "string"
-						},
-						"type": "array"
-					},
-					"uri": {
-						"type": "string"
-					}
-				},
-				"required": [
-					"uri"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"google-cloud-logging": {
-			"priority": 407,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"oneOf": [
-					{
-						"required": [
-							"auth_config"
-						]
-					},
-					{
-						"required": [
-							"auth_file"
-						]
-					}
-				],
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"auth_config": {
-						"properties": {
-							"entries_uri": {
-								"default": "https://logging.googleapis.com/v2/entries:write",
-								"type": "string"
-							},
-							"private_key": {
-								"type": "string"
-							},
-							"project_id": {
-								"type": "string"
-							},
-							"scopes": {
-								"default": [
-									"https://www.googleapis.com/auth/cloud-platform",
-									"https://www.googleapis.com/auth/logging.admin",
-									"https://www.googleapis.com/auth/logging.read",
-									"https://www.googleapis.com/auth/logging.write"
-								],
-								"items": {
-									"description": "Google OAuth2 Authorization Scopes",
-									"type": "string"
-								},
-								"minItems": 1,
-								"type": "array",
-								"uniqueItems": true
-							},
-							"token_uri": {
-								"default": "https://oauth2.googleapis.com/token",
-								"type": "string"
-							}
-						},
-						"required": [
-							"private_key",
-							"project_id",
-							"token_uri"
-						],
-						"type": "object"
-					},
-					"auth_file": {
-						"type": "string"
-					},
-					"batch_max_size": {
-						"default": 1000,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"buffer_duration": {
-						"default": 60,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"inactive_timeout": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"log_id": {
-						"default": "apisix.apache.org%2Flogs",
-						"type": "string"
-					},
-					"max_retry_count": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"name": {
-						"default": "google-cloud-logging",
-						"type": "string"
-					},
-					"resource": {
-						"default": {
-							"type": "global"
-						},
-						"properties": {
-							"labels": {
-								"type": "object"
-							},
-							"type": {
-								"type": "string"
-							}
-						},
-						"required": [
-							"type"
-						],
-						"type": "object"
-					},
-					"retry_delay": {
-						"default": 1,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"ssl_verify": {
-						"default": true,
-						"type": "boolean"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"grpc-transcode": {
-			"priority": 506,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"additionalProperties": true,
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"deadline": {
-						"default": 0,
-						"description": "deadline for grpc, millisecond",
-						"type": "number"
-					},
-					"method": {
-						"description": "the method name in the grpc service.",
-						"type": "string"
-					},
-					"pb_option": {
-						"default": [
-							"auto_default_values",
-							"disable_hooks",
-							"enum_as_name",
-							"int64_as_number"
-						],
-						"items": {
-							"anyOf": [
-								{
-									"description": "enum as result",
-									"enum": [
-										"int64_as_hexstring",
-										"int64_as_number",
-										"int64_as_string"
-									],
-									"type": "string"
-								},
-								{
-									"description": "int64 as result",
-									"enum": [
-										"enum_as_name",
-										"enum_as_value"
-									],
-									"type": "string"
-								},
-								{
-									"description": "default values option",
-									"enum": [
-										"auto_default_values",
-										"no_default_values",
-										"use_default_metatable",
-										"use_default_values"
-									],
-									"type": "string"
-								},
-								{
-									"description": "hooks option",
-									"enum": [
-										"disable_hooks",
-										"enable_hooks"
-									],
-									"type": "string"
-								}
-							],
-							"type": "string"
-						},
-						"minItems": 1,
-						"type": "array"
-					},
-					"proto_id": {
-						"anyOf": [
-							{
-								"maxLength": 64,
-								"minLength": 1,
-								"pattern": "^[a-zA-Z0-9-_.]+$",
-								"type": "string"
-							},
-							{
-								"minimum": 1,
-								"type": "integer"
-							}
-						]
-					},
-					"service": {
-						"description": "the grpc service name",
-						"type": "string"
-					}
-				},
-				"required": [
-					"method",
-					"proto_id",
-					"service"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"grpc-web": {
-			"priority": 505,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"gzip": {
-			"priority": 995,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"buffers": {
-						"default": {
-							"number": 32,
-							"size": 4096
-						},
-						"properties": {
-							"number": {
-								"default": 32,
-								"minimum": 1,
-								"type": "integer"
-							},
-							"size": {
-								"default": 4096,
-								"minimum": 1,
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"comp_level": {
-						"default": 1,
-						"maximum": 9,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"http_version": {
-						"default": 1.1,
-						"enum": [
-							1,
-							1.1
-						]
-					},
-					"min_length": {
-						"default": 20,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"types": {
-						"anyOf": [
-							{
-								"items": {
-									"minLength": 1,
-									"type": "string"
-								},
-								"minItems": 1,
-								"type": "array"
-							},
-							{
-								"enum": [
-									"*"
-								]
-							}
-						],
-						"default": [
-							"text/html"
-						]
-					},
-					"vary": {
-						"type": "boolean"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"hmac-auth": {
-			"consumer_schema": {
-				"properties": {
-					"access_key": {
-						"maxLength": 256,
-						"minLength": 1,
-						"type": "string"
-					},
-					"algorithm": {
-						"default": "hmac-sha256",
-						"enum": [
-							"hmac-sha1",
-							"hmac-sha256",
-							"hmac-sha512"
-						],
-						"type": "string"
-					},
-					"clock_skew": {
-						"default": 0,
-						"type": "integer"
-					},
-					"encode_uri_params": {
-						"default": true,
-						"title": "Whether to escape the uri parameter",
-						"type": "boolean"
-					},
-					"keep_headers": {
-						"default": false,
-						"title": "whether to keep the http request header",
-						"type": "boolean"
-					},
-					"max_req_body": {
-						"default": 524288,
-						"title": "Max request body size",
-						"type": "integer"
-					},
-					"secret_key": {
-						"maxLength": 256,
-						"minLength": 1,
-						"type": "string"
-					},
-					"signed_headers": {
-						"items": {
-							"maxLength": 50,
-							"minLength": 1,
-							"type": "string"
-						},
-						"type": "array"
-					},
-					"validate_request_body": {
-						"default": false,
-						"title": "A boolean value telling the plugin to enable body validation",
-						"type": "boolean"
-					}
-				},
-				"required": [
-					"access_key",
-					"secret_key"
-				],
-				"title": "work with consumer object",
-				"type": "object"
-			},
-			"priority": 2530,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					}
-				},
-				"title": "work with route or service object",
-				"type": "object"
-			},
-			"type": "auth",
-			"version": 0.1
-		},
-		"http-logger": {
-			"metadata_schema": {
-				"properties": {
-					"log_format": {
-						"default": {
-							"@timestamp": "$time_iso8601",
-							"client_ip": "$remote_addr",
-							"host": "$host"
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 410,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"auth_header": {
-						"type": "string"
-					},
-					"batch_max_size": {
-						"default": 1000,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"buffer_duration": {
-						"default": 60,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"concat_method": {
-						"default": "json",
-						"enum": [
-							"json",
-							"new_line"
-						],
-						"type": "string"
-					},
-					"inactive_timeout": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"include_req_body": {
-						"default": false,
-						"type": "boolean"
-					},
-					"include_resp_body": {
-						"default": false,
-						"type": "boolean"
-					},
-					"include_resp_body_expr": {
-						"items": {
-							"type": "array"
-						},
-						"minItems": 1,
-						"type": "array"
-					},
-					"max_retry_count": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"name": {
-						"default": "http logger",
-						"type": "string"
-					},
-					"retry_delay": {
-						"default": 1,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"ssl_verify": {
-						"default": false,
-						"type": "boolean"
-					},
-					"timeout": {
-						"default": 3,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"uri": {
-						"pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?",
-						"type": "string"
-					}
-				},
-				"required": [
-					"uri"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"ip-restriction": {
-			"priority": 3000,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"oneOf": [
-					{
-						"required": [
-							"whitelist"
-						]
-					},
-					{
-						"required": [
-							"blacklist"
-						]
-					}
-				],
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"blacklist": {
-						"items": {
-							"anyOf": [
-								{
-									"format": "ipv4",
-									"title": "IPv4",
-									"type": "string"
-								},
-								{
-									"pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$",
-									"title": "IPv4/CIDR",
-									"type": "string"
-								},
-								{
-									"format": "ipv6",
-									"title": "IPv6",
-									"type": "string"
-								},
-								{
-									"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
-									"title": "IPv6/CIDR",
-									"type": "string"
-								}
-							]
-						},
-						"minItems": 1,
-						"type": "array"
-					},
-					"message": {
-						"default": "Your IP address is not allowed",
-						"maxLength": 1024,
-						"minLength": 1,
-						"type": "string"
-					},
-					"whitelist": {
-						"items": {
-							"anyOf": [
-								{
-									"format": "ipv4",
-									"title": "IPv4",
-									"type": "string"
-								},
-								{
-									"pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$",
-									"title": "IPv4/CIDR",
-									"type": "string"
-								},
-								{
-									"format": "ipv6",
-									"title": "IPv6",
-									"type": "string"
-								},
-								{
-									"pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$",
-									"title": "IPv6/CIDR",
-									"type": "string"
-								}
-							]
-						},
-						"minItems": 1,
-						"type": "array"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"jwt-auth": {
-			"consumer_schema": {
-				"dependencies": {
-					"algorithm": {
-						"oneOf": [
-							{
-								"properties": {
-									"algorithm": {
-										"default": "HS256",
-										"enum": [
-											"HS256",
-											"HS512"
-										]
-									}
-								}
-							},
-							{
-								"properties": {
-									"algorithm": {
-										"enum": [
-											"ES256",
-											"RS256"
-										]
-									},
-									"private_key": {
-										"type": "string"
-									},
-									"public_key": {
-										"type": "string"
-									}
-								},
-								"required": [
-									"private_key",
-									"public_key"
-								]
-							},
-							{
-								"properties": {
-									"algorithm": {
-										"enum": [
-											"ES256",
-											"RS256"
-										]
-									},
-									"vault": {
-										"properties": {},
-										"type": "object"
-									}
-								},
-								"required": [
-									"vault"
-								]
-							}
-						]
-					}
-				},
-				"properties": {
-					"algorithm": {
-						"default": "HS256",
-						"enum": [
-							"ES256",
-							"HS256",
-							"HS512",
-							"RS256"
-						],
-						"type": "string"
-					},
-					"base64_secret": {
-						"default": false,
-						"type": "boolean"
-					},
-					"exp": {
-						"default": 86400,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"key": {
-						"type": "string"
-					},
-					"lifetime_grace_period": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"secret": {
-						"type": "string"
-					},
-					"vault": {
-						"properties": {},
-						"type": "object"
-					}
-				},
-				"required": [
-					"key"
-				],
-				"type": "object"
-			},
-			"priority": 2510,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"cookie": {
-						"default": "jwt",
-						"type": "string"
-					},
-					"header": {
-						"default": "authorization",
-						"type": "string"
-					},
-					"query": {
-						"default": "jwt",
-						"type": "string"
-					}
-				},
-				"type": "object"
-			},
-			"type": "auth",
-			"version": 0.1
-		},
-		"kafka-logger": {
-			"metadata_schema": {
-				"properties": {
-					"log_format": {
-						"default": {
-							"@timestamp": "$time_iso8601",
-							"client_ip": "$remote_addr",
-							"host": "$host"
-						},
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"priority": 403,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"oneOf": [
-					{
-						"required": [
-							"broker_list",
-							"kafka_topic"
-						]
-					},
-					{
-						"required": [
-							"brokers",
-							"kafka_topic"
-						]
-					}
-				],
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"batch_max_size": {
-						"default": 1000,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"broker_list": {
-						"minProperties": 1,
-						"patternProperties": {
-							".*": {
-								"description": "the port of kafka broker",
-								"maximum": 65535,
-								"minimum": 1,
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"brokers": {
-						"items": {
-							"properties": {
-								"host": {
-									"description": "the host of kafka broker",
-									"type": "string"
-								},
-								"port": {
-									"description": "the port of kafka broker",
-									"maximum": 65535,
-									"minimum": 1,
-									"type": "integer"
-								},
-								"sasl_config": {
-									"description": "sasl config",
-									"properties": {
-										"mechanism": {
-											"default": "PLAIN",
-											"enum": [
-												"PLAIN"
-											],
-											"type": "string"
-										},
-										"password": {
-											"description": "password",
-											"type": "string"
-										},
-										"user": {
-											"description": "user",
-											"type": "string"
-										}
-									},
-									"required": [
-										"password",
-										"user"
-									],
-									"type": "object"
-								}
-							},
-							"required": [
-								"host",
-								"port"
-							],
-							"type": "object"
-						},
-						"minItems": 1,
-						"type": "array",
-						"uniqueItems": true
-					},
-					"buffer_duration": {
-						"default": 60,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"cluster_name": {
-						"default": 1,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"inactive_timeout": {
-						"default": 5,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"include_req_body": {
-						"default": false,
-						"type": "boolean"
-					},
-					"include_req_body_expr": {
-						"items": {
-							"type": "array"
-						},
-						"minItems": 1,
-						"type": "array"
-					},
-					"include_resp_body": {
-						"default": false,
-						"type": "boolean"
-					},
-					"include_resp_body_expr": {
-						"items": {
-							"type": "array"
-						},
-						"minItems": 1,
-						"type": "array"
-					},
-					"kafka_topic": {
-						"type": "string"
-					},
-					"key": {
-						"type": "string"
-					},
-					"max_retry_count": {
-						"default": 0,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"meta_format": {
-						"default": "default",
-						"enum": [
-							"default",
-							"origin"
-						],
-						"type": "string"
-					},
-					"name": {
-						"default": "kafka logger",
-						"type": "string"
-					},
-					"producer_batch_num": {
-						"default": 200,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"producer_batch_size": {
-						"default": 1048576,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"producer_max_buffering": {
-						"default": 50000,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"producer_time_linger": {
-						"default": 1,
-						"minimum": 1,
-						"type": "integer"
-					},
-					"producer_type": {
-						"default": "async",
-						"enum": [
-							"async",
-							"sync"
-						],
-						"type": "string"
-					},
-					"required_acks": {
-						"default": 1,
-						"enum": [
-							-1,
-							0,
-							1
-						],
-						"type": "integer"
-					},
-					"retry_delay": {
-						"default": 1,
-						"minimum": 0,
-						"type": "integer"
-					},
-					"timeout": {
-						"default": 3,
-						"minimum": 1,
-						"type": "integer"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"kafka-proxy": {
-			"priority": 508,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"sasl": {
-						"properties": {
-							"password": {
-								"type": "string"
-							},
-							"username": {
-								"type": "string"
-							}
-						},
-						"required": [
-							"password",
-							"username"
-						],
-						"type": "object"
-					}
-				},
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"key-auth": {
-			"consumer_schema": {
-				"properties": {
-					"key": {
-						"type": "string"
-					}
-				},
-				"required": [
-					"key"
-				],
-				"type": "object"
-			},
-			"priority": 2500,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"header": {
-						"default": "apikey",
-						"type": "string"
-					},
-					"hide_credentials": {
-						"default": false,
-						"type": "boolean"
-					},
-					"query": {
-						"default": "apikey",
-						"type": "string"
-					}
-				},
-				"type": "object"
-			},
-			"type": "auth",
-			"version": 0.1
-		},
-		"ldap-auth": {
-			"consumer_schema": {
-				"properties": {
-					"user_dn": {
-						"type": "string"
-					}
-				},
-				"required": [
-					"user_dn"
-				],
-				"title": "work with consumer object",
-				"type": "object"
-			},
-			"priority": 2540,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"base_dn": {
-						"type": "string"
-					},
-					"ldap_uri": {
-						"type": "string"
-					},
-					"tls_verify": {
-						"default": false,
-						"type": "boolean"
-					},
-					"uid": {
-						"default": "cn",
-						"type": "string"
-					},
-					"use_tls": {
-						"default": false,
-						"type": "boolean"
-					}
-				},
-				"required": [
-					"base_dn",
-					"ldap_uri"
-				],
-				"title": "work with route or service object",
-				"type": "object"
-			},
-			"type": "auth",
-			"version": 0.1
-		},
-		"limit-conn": {
-			"priority": 1003,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"allow_degradation": {
-						"default": false,
-						"type": "boolean"
-					},
-					"burst": {
-						"minimum": 0,
-						"type": "integer"
-					},
-					"conn": {
-						"exclusiveMinimum": 0,
-						"type": "integer"
-					},
-					"default_conn_delay": {
-						"exclusiveMinimum": 0,
-						"type": "number"
-					},
-					"key": {
-						"type": "string"
-					},
-					"key_type": {
-						"default": "var",
-						"enum": [
-							"var",
-							"var_combination"
-						],
-						"type": "string"
-					},
-					"only_use_default_delay": {
-						"default": false,
-						"type": "boolean"
-					},
-					"rejected_code": {
-						"default": 503,
-						"maximum": 599,
-						"minimum": 200,
-						"type": "integer"
-					},
-					"rejected_msg": {
-						"minLength": 1,
-						"type": "string"
-					}
-				},
-				"required": [
-					"burst",
-					"conn",
-					"default_conn_delay",
-					"key"
-				],
-				"type": "object"
-			},
-			"version": 0.1
-		},
-		"limit-count": {
-			"priority": 1002,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"else": {
-					"if": {
-						"properties": {
-							"policy": {
-								"enum": [
-									"redis-cluster"
-								]
-							}
-						}
-					},
-					"then": {
-						"properties": {
-							"redis_cluster_name": {
-								"type": "string"
-							},
-							"redis_cluster_nodes": {
-								"items": {
-									"maxLength": 100,
-									"minLength": 2,
-									"type": "string"
-								},
-								"minItems": 2,
-								"type": "array"
-							},
-							"redis_password": {
-								"minLength": 0,
-								"type": "string"
-							},
-							"redis_timeout": {
-								"default": 1000,
-								"minimum": 1,
-								"type": "integer"
-							}
-						},
-						"required": [
-							"redis_cluster_name",
-							"redis_cluster_nodes"
-						]
-					}
-				},
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"allow_degradation": {
-						"default": false,
-						"type": "boolean"
-					},
-					"count": {
-						"exclusiveMinimum": 0,
-						"type": "integer"
-					},
-					"group": {
-						"type": "string"
-					},
-					"key": {
-						"default": "remote_addr",
-						"type": "string"
-					},
-					"key_type": {
-						"default": "var",
-						"enum": [
-							"constant",
-							"var",
-							"var_combination"
-						],
-						"type": "string"
-					},
-					"policy": {
-						"default": "local",
-						"enum": [
-							"local",
-							"redis",
-							"redis-cluster"
-						],
-						"type": "string"
-					},
-					"rejected_code": {
-						"default": 503,
-						"maximum": 599,
-						"minimum": 200,
-						"type": "integer"
-					},
-					"rejected_msg": {
-						"minLength": 1,
-						"type": "string"
-					},
-					"show_limit_quota_header": {
-						"default": true,
-						"type": "boolean"
-					},
-					"time_window": {
-						"exclusiveMinimum": 0,
-						"type": "integer"
-					}
-				},
-				"required": [
-					"count",
-					"time_window"
-				],
-				"if": {
-					"properties": {
-						"policy": {
-							"enum": [
-								"redis"
-							]
-						}
-					}
-				},
-				"then": {
-					"properties": {
-						"redis_database": {
-							"default": 0,
-							"minimum": 0,
-							"type": "integer"
-						},
-						"redis_host": {
-							"minLength": 2,
-							"type": "string"
-						},
-						"redis_password": {
-							"minLength": 0,
-							"type": "string"
-						},
-						"redis_port": {
-							"default": 6379,
-							"minimum": 1,
-							"type": "integer"
-						},
-						"redis_timeout": {
-							"default": 1000,
-							"minimum": 1,
-							"type": "integer"
-						}
-					},
-					"required": [
-						"redis_host"
-					]
-				},
-				"type": "object"
-			},
-			"version": 0.4
-		},
-		"limit-req": {
-			"priority": 1001,
-			"schema": {
-				"$comment": "this is a mark for our injected plugin schema",
-				"properties": {
-					"_meta": {
-						"properties": {
-							"disable": {
-								"type": "boolean"
-							},
-							"error_response": {
-								"oneOf": [
-									{
-										"type": "string"
-									},
-									{
-										"type": "object"
-									}
-								]
-							},
-							"filter": {
-								"description": "filter determines whether the plugin needs to be executed at runtime",
-								"type": "array"
-							},
-							"priority": {
-								"description": "priority of plugins by customized order",
-								"type": "integer"
-							}
-						},
-						"type": "object"
-					},
-					"allow_degradation": {
-						"default": false,
-						"type": "boolean"
-					},
-					"burst": {
-						"minimum": 0,
-						"type": "number"
-					},
-					"key": {
-						"type": "string"
-					},
-					"key_type": {
-						"default": "var",
-						"enum": [
-							"var",
-							"var_combination"
-						],
-						"type": "string"
-					},
-					"nodelay": {
-						"default": false,
-						"type": "boolean"
-					},
-					"rate": {
-						"exclusiveMinimum": 0,
-						"type": "number"
-					},
-					"rejected_code": {
-						"default": 503,
-						"maximum": 599,
-						"minimum": 200,
-						"type": "integer"
-					},
-					"rejected_msg": {
-						"minLength": 1,
-						"type": "string"
-					}
-				},
-				"required": [
-					"burst",
-					"key",
-					"rate"
... 120523 lines suppressed ...