You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by GitBox <gi...@apache.org> on 2020/12/23 02:24:08 UTC
[GitHub] [apisix-dashboard] Jaycean opened a new pull request #1102: Import & Export route from OpenAPI Specification3.0
Jaycean opened a new pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102
Signed-off-by: Jacean <ji...@163.com>
Import & Export route from OpenAPI Specification3.0
- Why submit this pull request?
- [ ] Bugfix
- [x] New feature provided
- [ ] Improve performance
- Related issues
issue: #825
___
### New feature or improvement
speed of progress:
It has implemented the basic information and authentication plugins of OpenAPI configuration file: basic-auth, JWT-auth, key-auth; parameter authentication plugin, request-validation and request header parameter parsing.
Remaining problems:
When writing etcd for parameter verification, the system will report the following error because there are no upstream and service related parameters in OpenAPI.
```
scheme validate fail: (root): Must validate at least one schema (anyOf)
(root): plugins is required
```
It is difficult to write to etcd in batch because it is necessary to verify the properties of upstream and service when writing data to etcd, and there is no relevant interface in the underlying layer.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (4e06b76) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/1bdcaa8df2fe2fa6caba23809e69e26c5ad7902d?el=desc) (1bdcaa8) will **decrease** coverage by `19.95%`.
> The diff coverage is `31.72%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
===========================================
- Coverage 62.29% 42.33% -19.96%
===========================================
Files 42 34 -8
Lines 2395 2258 -137
===========================================
- Hits 1492 956 -536
- Misses 722 1165 +443
+ Partials 181 137 -44
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (-62.50%)` | :arrow_down: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (-55.47%)` | :arrow_down: |
| [api/internal/utils/utils.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3V0aWxzL3V0aWxzLmdv) | `47.56% <0.00%> (-23.66%)` | :arrow_down: |
| [api/internal/handler/data\_loader/import.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvZGF0YV9sb2FkZXIvaW1wb3J0Lmdv) | `29.96% <29.96%> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `46.52% <66.66%> (-20.87%)` | :arrow_down: |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.10% <75.00%> (-10.83%)` | :arrow_down: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `81.81% <100.00%> (-4.26%)` | :arrow_down: |
| [api/internal/filter/request\_id.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9yZXF1ZXN0X2lkLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [api/internal/core/store/storehub.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmVodWIuZ28=) | `0.00% <0.00%> (-74.49%)` | :arrow_down: |
| [api/internal/filter/cors.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9jb3JzLmdv) | `0.00% <0.00%> (-66.67%)` | :arrow_down: |
| ... and [30 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [1bdcaa8...4e06b76](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] starsz commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
starsz commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r564449030
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,531 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/data"
+ "github.com/shiningrush/droplet/middleware"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/log"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore *store.GenericStore
+ svcStore store.Interface
+ upstreamStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", wgin.Wraps(h.Import))
Review comment:
`/apisix/admin/import/routes` is better.
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,531 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/data"
+ "github.com/shiningrush/droplet/middleware"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/log"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore *store.GenericStore
+ svcStore store.Interface
+ upstreamStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", wgin.Wraps(h.Import))
+}
+
+type ImportInput struct {
+ Force bool `auto_read:"force,query"`
+}
+
+func (h *Handler) Import(c droplet.Context) (interface{}, error) {
+ httpReq := c.Get(middleware.KeyHttpRequest)
+ if httpReq == nil {
+ return nil, errors.New("input middleware cannot get http request")
+ }
+ req := httpReq.(*http.Request)
+ req.Body = http.MaxBytesReader(nil, req.Body, int64(conf.ImportSizeLimit))
+ if err := req.ParseMultipartForm(int64(conf.ImportSizeLimit)); err != nil {
+ log.Warnf("upload file size exceeds limit: %s", err)
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ Force := req.URL.Query().Get("force")
+
+ _, fileHeader, err := req.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
+
+ // file check
+ suffix := path.Ext(fileHeader.Filename)
+ if suffix != ".json" && suffix != ".yaml" && suffix != ".yml" {
+ return nil, fmt.Errorf("required file type is .yaml, .yml or .json but got: %s", suffix)
+ }
+
+ // read file and parse
+ handle, err := fileHeader.Open()
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ err = handle.Close()
+ }()
+
+ reader := bufio.NewReader(handle)
+ bytes := make([]byte, fileHeader.Size)
+ _, err = reader.Read(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(swagger.Paths) < 1 {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ errors.New("empty or invalid imported file")
+ }
+
+ routes, err := OpenAPI3ToRoute(swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ // check route
+ for _, route := range routes {
+ err := checkRouteExist(c.Context(), h.routeStore, route)
+ if err != nil && Force != "1" {
+ log.Warnf("import duplicate: %s, route: %#v", err, route)
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ if route.ServiceID != nil {
+ _, err := h.svcStore.Get(c.Context(), utils.InterfaceToString(route.ServiceID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("service id: %s not found", route.ServiceID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.UpstreamID != nil {
+ _, err := h.upstreamStore.Get(c.Context(), utils.InterfaceToString(route.UpstreamID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("upstream id: %s not found", route.UpstreamID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+
+ if _, err := h.routeStore.CreateCheck(route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+
+ // create route
+ for _, route := range routes {
+ if Force == "1" && route.ID != nil {
+ if _, err := h.routeStore.Update(c.Context(), route, true); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ } else {
+ if _, err := h.routeStore.Create(c.Context(), route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+ }
+
+ return nil, nil
+}
+
+func checkRouteExist(ctx context.Context, routeStore *store.GenericStore, route *entity.Route) error {
+ //routeStore := store.GetStore(store.HubKeyRoute)
+ ret, err := routeStore.List(ctx, store.ListInput{
+ Predicate: func(obj interface{}) bool {
+ id := utils.InterfaceToString(route.ID)
+ item := obj.(*entity.Route)
+ if id != "" && id != utils.InterfaceToString(item.ID) {
+ return false
+ }
+
+ if !(item.Host == route.Host && item.URI == route.URI && utils.StringSliceEqual(item.Uris, route.Uris) &&
+ utils.StringSliceEqual(item.RemoteAddrs, route.RemoteAddrs) && item.RemoteAddr == route.RemoteAddr &&
+ utils.StringSliceEqual(item.Hosts, route.Hosts) && item.Priority == route.Priority &&
+ utils.ValueEqual(item.Vars, route.Vars) && item.FilterFunc == route.FilterFunc) {
+ return false
+ }
+ return true
+ },
+ PageSize: 0,
+ PageNumber: 0,
+ })
+ if err != nil {
+ return err
+ }
+ if len(ret.Rows) > 0 {
+ return consts.InvalidParam("route is duplicate")
+ }
+ return nil
+}
+
+func parseExtension(val *openapi3.Operation) (*entity.Route, error) {
+ routeMap := map[string]interface{}{}
+ for key, val := range val.Extensions {
+ if strings.HasPrefix(key, "x-apisix-") {
+ routeMap[strings.TrimPrefix(key, "x-apisix-")] = val
+ }
+ }
+
+ route := new(entity.Route)
+ routeJson, err := json.Marshal(routeMap)
+ if err != nil {
+ return nil, err
+ }
+
+ err = json.Unmarshal(routeJson, &route)
+ if err != nil {
+ return nil, err
+ }
+
+ return route, nil
+}
+
+type PathValue struct {
+ Method string
+ Value *openapi3.Operation
+}
+
+func mergePathValue(key string, values []PathValue, swagger *openapi3.Swagger) (map[string]*entity.Route, error) {
+ var parsed []PathValue
+ var routes = map[string]*entity.Route{}
+ for _, value := range values {
+ value.Value.OperationID = strings.Replace(value.Value.OperationID, value.Method, "", 1)
+ var eq = false
+ for _, v := range parsed {
+ if utils.ValueEqual(v.Value, value.Value) {
+ eq = true
+ if routes[v.Method].Methods == nil {
+ routes[v.Method].Methods = []string{}
+ }
+ routes[v.Method].Methods = append(routes[v.Method].Methods, value.Method)
+ }
+ }
+ // not equal to the previous ones
+ if !eq {
+ route, err := getRouteFromPaths(value.Method, key, value.Value, swagger)
+ if err != nil {
+ return nil, err
+ }
+ routes[value.Method] = route
+ parsed = append(parsed, value)
+ }
+ }
+
+ return routes, nil
+}
+
+func OpenAPI3ToRoute(swagger *openapi3.Swagger) ([]*entity.Route, error) {
+ var routes []*entity.Route
+ paths := swagger.Paths
+ var upstream *entity.UpstreamDef
+ var err error
+ for k, v := range paths {
+ upstream = &entity.UpstreamDef{}
+ if up, ok := v.Extensions["x-apisix-upstream"]; ok {
+ err = json.Unmarshal(up.(json.RawMessage), upstream)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var values []PathValue
+ if v.Get != nil {
+ value := PathValue{
+ Method: http.MethodGet,
+ Value: v.Get,
+ }
+ values = append(values, value)
+ }
+ if v.Post != nil {
+ value := PathValue{
+ Method: http.MethodPost,
+ Value: v.Post,
+ }
+ values = append(values, value)
+ }
+ if v.Head != nil {
+ value := PathValue{
+ Method: http.MethodHead,
+ Value: v.Head,
+ }
+ values = append(values, value)
+ }
+ if v.Put != nil {
+ value := PathValue{
+ Method: http.MethodPut,
+ Value: v.Put,
+ }
+ values = append(values, value)
+ }
+ if v.Patch != nil {
+ value := PathValue{
+ Method: http.MethodPatch,
+ Value: v.Patch,
+ }
+ values = append(values, value)
+ }
+ if v.Delete != nil {
+ value := PathValue{
+ Method: http.MethodDelete,
+ Value: v.Delete,
+ }
+ values = append(values, value)
+ }
+
+ // merge same route
+ tmp, err := mergePathValue(k, values, swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, route := range tmp {
+ routes = append(routes, route)
+ }
+ }
+
+ return routes, nil
+}
+
+func parseParameters(parameters openapi3.Parameters, plugins map[string]interface{}) {
+ props := make(map[string]interface{})
+ var required []string
+ for _, v := range parameters {
+ if v.Value.Schema != nil {
+ v.Value.Schema.Value.Format = ""
+ v.Value.Schema.Value.XML = nil
+ }
+
+ switch v.Value.In {
+ case "header":
+ if v.Value.Schema != nil && v.Value.Schema.Value != nil {
+ props[v.Value.Name] = v.Value.Schema.Value
+ }
+ if v.Value.Required {
+ required = append(required, v.Value.Name)
+ }
+ }
+ }
+
+ requestValidation := make(map[string]interface{})
+ if rv, ok := plugins["request-validation"]; ok {
+ requestValidation = rv.(map[string]interface{})
+ }
+ requestValidation["header_schema"] = &entity.RequestValidation{
+ Type: "object",
+ Required: required,
+ Properties: props,
+ }
+ plugins["request-validation"] = requestValidation
+}
+
+func parseRequestBody(requestBody *openapi3.RequestBodyRef, swagger *openapi3.Swagger, plugins map[string]interface{}) {
+ schema := requestBody.Value.Content
+ requestValidation := make(map[string]interface{})
+ if rv, ok := plugins["request-validation"]; ok {
+ requestValidation = rv.(map[string]interface{})
+ }
+ for _, v := range schema {
+ if v.Schema.Ref != "" {
+ s := getParameters(v.Schema.Ref, &swagger.Components).Value
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: s.Type,
+ Required: s.Required,
+ Properties: s.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ } else if v.Schema.Value != nil {
+ if v.Schema.Value.Properties != nil {
+ for k1, v1 := range v.Schema.Value.Properties {
+ if v1.Ref != "" {
+ s := getParameters(v1.Ref, &swagger.Components)
+ v.Schema.Value.Properties[k1] = s
+ }
+ v1.Value.Format = ""
+ }
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: v.Schema.Value.Type,
+ Required: v.Schema.Value.Required,
+ Properties: v.Schema.Value.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ } else if v.Schema.Value.Items != nil {
+ if v.Schema.Value.Items.Ref != "" {
+ s := getParameters(v.Schema.Value.Items.Ref, &swagger.Components).Value
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: s.Type,
+ Required: s.Required,
+ Properties: s.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ }
+ } else {
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: "object",
+ Required: []string{},
+ Properties: v.Schema.Value.Properties,
+ }
+ }
+ }
+ plugins["request-validation"] = requestValidation
+ }
+}
+
+func parseSecurity(security openapi3.SecurityRequirements, securitySchemes openapi3.SecuritySchemes, plugins map[string]interface{}) {
+ // todo: import consumers
+ for _, securities := range security {
+ for name := range securities {
+ if schema, ok := securitySchemes[name]; ok {
+ value := schema.Value
+ if value == nil {
+ continue
+ }
+
+ // basic auth
+ if value.Type == "http" && value.Scheme == "basic" {
+ plugins["basic-auth"] = map[string]interface{}{}
+ //username, ok := value.Extensions["username"]
+ //if !ok {
+ // continue
+ //}
+ //password, ok := value.Extensions["password"]
+ //if !ok {
+ // continue
+ //}
+ //plugins["basic-auth"] = map[string]interface{}{
+ // "username": username,
+ // "password": password,
+ //}
+ // jwt auth
+ } else if value.Type == "http" && value.Scheme == "bearer" && value.BearerFormat == "JWT" {
+ plugins["jwt-auth"] = map[string]interface{}{}
+ //key, ok := value.Extensions["key"]
+ //if !ok {
+ // continue
+ //}
+ //secret, ok := value.Extensions["secret"]
+ //if !ok {
+ // continue
+ //}
+ //plugins["jwt-auth"] = map[string]interface{}{
+ // "key": key,
+ // "secret": secret,
+ //}
+ // key auth
+ } else if value.Type == "apiKey" {
+ plugins["key-auth"] = map[string]interface{}{}
+ //key, ok := value.Extensions["key"]
+ //if !ok {
+ // continue
+ //}
+ //plugins["key-auth"] = map[string]interface{}{
+ // "key": key,
+ //}
+ }
+ }
+ }
+ }
+}
+
+func getRouteFromPaths(method, key string, value *openapi3.Operation, swagger *openapi3.Swagger) (*entity.Route, error) {
+ // transform /path/{var} to /path/*
+ reg := regexp.MustCompile(`{[\w.]*}`)
Review comment:
This can be put out of function.
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,531 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/data"
+ "github.com/shiningrush/droplet/middleware"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/log"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore *store.GenericStore
+ svcStore store.Interface
+ upstreamStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", wgin.Wraps(h.Import))
+}
+
+type ImportInput struct {
+ Force bool `auto_read:"force,query"`
+}
+
+func (h *Handler) Import(c droplet.Context) (interface{}, error) {
+ httpReq := c.Get(middleware.KeyHttpRequest)
+ if httpReq == nil {
+ return nil, errors.New("input middleware cannot get http request")
+ }
+ req := httpReq.(*http.Request)
+ req.Body = http.MaxBytesReader(nil, req.Body, int64(conf.ImportSizeLimit))
+ if err := req.ParseMultipartForm(int64(conf.ImportSizeLimit)); err != nil {
+ log.Warnf("upload file size exceeds limit: %s", err)
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ Force := req.URL.Query().Get("force")
+
+ _, fileHeader, err := req.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
Review comment:
Ditto.
##########
File path: api/internal/route.go
##########
@@ -18,6 +18,7 @@ package internal
import (
"fmt"
+ "github.com/apisix/manager-api/internal/handler/data_loader"
Review comment:
Style.
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,531 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/data"
+ "github.com/shiningrush/droplet/middleware"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/log"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore *store.GenericStore
+ svcStore store.Interface
+ upstreamStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", wgin.Wraps(h.Import))
+}
+
+type ImportInput struct {
+ Force bool `auto_read:"force,query"`
+}
+
+func (h *Handler) Import(c droplet.Context) (interface{}, error) {
+ httpReq := c.Get(middleware.KeyHttpRequest)
+ if httpReq == nil {
+ return nil, errors.New("input middleware cannot get http request")
+ }
+ req := httpReq.(*http.Request)
+ req.Body = http.MaxBytesReader(nil, req.Body, int64(conf.ImportSizeLimit))
Review comment:
Droplet lib is supportting to read body now.
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,531 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/data"
+ "github.com/shiningrush/droplet/middleware"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/log"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore *store.GenericStore
+ svcStore store.Interface
+ upstreamStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", wgin.Wraps(h.Import))
+}
+
+type ImportInput struct {
+ Force bool `auto_read:"force,query"`
+}
+
+func (h *Handler) Import(c droplet.Context) (interface{}, error) {
+ httpReq := c.Get(middleware.KeyHttpRequest)
+ if httpReq == nil {
+ return nil, errors.New("input middleware cannot get http request")
+ }
+ req := httpReq.(*http.Request)
+ req.Body = http.MaxBytesReader(nil, req.Body, int64(conf.ImportSizeLimit))
+ if err := req.ParseMultipartForm(int64(conf.ImportSizeLimit)); err != nil {
+ log.Warnf("upload file size exceeds limit: %s", err)
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ Force := req.URL.Query().Get("force")
+
+ _, fileHeader, err := req.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
+
+ // file check
+ suffix := path.Ext(fileHeader.Filename)
+ if suffix != ".json" && suffix != ".yaml" && suffix != ".yml" {
+ return nil, fmt.Errorf("required file type is .yaml, .yml or .json but got: %s", suffix)
+ }
+
+ // read file and parse
+ handle, err := fileHeader.Open()
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ err = handle.Close()
+ }()
+
+ reader := bufio.NewReader(handle)
+ bytes := make([]byte, fileHeader.Size)
+ _, err = reader.Read(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(swagger.Paths) < 1 {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ errors.New("empty or invalid imported file")
+ }
+
+ routes, err := OpenAPI3ToRoute(swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ // check route
+ for _, route := range routes {
+ err := checkRouteExist(c.Context(), h.routeStore, route)
+ if err != nil && Force != "1" {
+ log.Warnf("import duplicate: %s, route: %#v", err, route)
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ if route.ServiceID != nil {
+ _, err := h.svcStore.Get(c.Context(), utils.InterfaceToString(route.ServiceID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("service id: %s not found", route.ServiceID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.UpstreamID != nil {
+ _, err := h.upstreamStore.Get(c.Context(), utils.InterfaceToString(route.UpstreamID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("upstream id: %s not found", route.UpstreamID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+
+ if _, err := h.routeStore.CreateCheck(route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
Review comment:
Enrich the return info.
##########
File path: api/internal/handler/route/route.go
##########
@@ -259,7 +259,7 @@ func (h *Handler) List(c droplet.Context) (interface{}, error) {
return ret, nil
}
-func generateLuaCode(script map[string]interface{}) (string, error) {
+func GenerateLuaCode(script map[string]interface{}) (string, error) {
Review comment:
This can be rollback.
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,531 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/data"
+ "github.com/shiningrush/droplet/middleware"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/log"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore *store.GenericStore
+ svcStore store.Interface
+ upstreamStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", wgin.Wraps(h.Import))
+}
+
+type ImportInput struct {
+ Force bool `auto_read:"force,query"`
+}
+
+func (h *Handler) Import(c droplet.Context) (interface{}, error) {
+ httpReq := c.Get(middleware.KeyHttpRequest)
+ if httpReq == nil {
+ return nil, errors.New("input middleware cannot get http request")
+ }
+ req := httpReq.(*http.Request)
+ req.Body = http.MaxBytesReader(nil, req.Body, int64(conf.ImportSizeLimit))
+ if err := req.ParseMultipartForm(int64(conf.ImportSizeLimit)); err != nil {
+ log.Warnf("upload file size exceeds limit: %s", err)
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ Force := req.URL.Query().Get("force")
+
+ _, fileHeader, err := req.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
+
+ // file check
+ suffix := path.Ext(fileHeader.Filename)
+ if suffix != ".json" && suffix != ".yaml" && suffix != ".yml" {
+ return nil, fmt.Errorf("required file type is .yaml, .yml or .json but got: %s", suffix)
+ }
+
+ // read file and parse
+ handle, err := fileHeader.Open()
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ err = handle.Close()
+ }()
+
+ reader := bufio.NewReader(handle)
+ bytes := make([]byte, fileHeader.Size)
+ _, err = reader.Read(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(swagger.Paths) < 1 {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ errors.New("empty or invalid imported file")
+ }
+
+ routes, err := OpenAPI3ToRoute(swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ // check route
+ for _, route := range routes {
+ err := checkRouteExist(c.Context(), h.routeStore, route)
+ if err != nil && Force != "1" {
+ log.Warnf("import duplicate: %s, route: %#v", err, route)
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ if route.ServiceID != nil {
+ _, err := h.svcStore.Get(c.Context(), utils.InterfaceToString(route.ServiceID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("service id: %s not found", route.ServiceID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.UpstreamID != nil {
+ _, err := h.upstreamStore.Get(c.Context(), utils.InterfaceToString(route.UpstreamID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("upstream id: %s not found", route.UpstreamID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+
+ if _, err := h.routeStore.CreateCheck(route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+
+ // create route
+ for _, route := range routes {
+ if Force == "1" && route.ID != nil {
+ if _, err := h.routeStore.Update(c.Context(), route, true); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ } else {
+ if _, err := h.routeStore.Create(c.Context(), route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+ }
+
+ return nil, nil
Review comment:
TODO: return the sum info.
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,531 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/data"
+ "github.com/shiningrush/droplet/middleware"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/log"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore *store.GenericStore
+ svcStore store.Interface
+ upstreamStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", wgin.Wraps(h.Import))
+}
+
+type ImportInput struct {
+ Force bool `auto_read:"force,query"`
+}
+
+func (h *Handler) Import(c droplet.Context) (interface{}, error) {
+ httpReq := c.Get(middleware.KeyHttpRequest)
+ if httpReq == nil {
+ return nil, errors.New("input middleware cannot get http request")
+ }
+ req := httpReq.(*http.Request)
+ req.Body = http.MaxBytesReader(nil, req.Body, int64(conf.ImportSizeLimit))
+ if err := req.ParseMultipartForm(int64(conf.ImportSizeLimit)); err != nil {
+ log.Warnf("upload file size exceeds limit: %s", err)
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ Force := req.URL.Query().Get("force")
+
+ _, fileHeader, err := req.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
+
+ // file check
+ suffix := path.Ext(fileHeader.Filename)
+ if suffix != ".json" && suffix != ".yaml" && suffix != ".yml" {
+ return nil, fmt.Errorf("required file type is .yaml, .yml or .json but got: %s", suffix)
+ }
+
+ // read file and parse
+ handle, err := fileHeader.Open()
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ err = handle.Close()
+ }()
+
+ reader := bufio.NewReader(handle)
+ bytes := make([]byte, fileHeader.Size)
+ _, err = reader.Read(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(swagger.Paths) < 1 {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ errors.New("empty or invalid imported file")
+ }
+
+ routes, err := OpenAPI3ToRoute(swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ // check route
+ for _, route := range routes {
+ err := checkRouteExist(c.Context(), h.routeStore, route)
+ if err != nil && Force != "1" {
+ log.Warnf("import duplicate: %s, route: %#v", err, route)
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ if route.ServiceID != nil {
+ _, err := h.svcStore.Get(c.Context(), utils.InterfaceToString(route.ServiceID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("service id: %s not found", route.ServiceID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.UpstreamID != nil {
+ _, err := h.upstreamStore.Get(c.Context(), utils.InterfaceToString(route.UpstreamID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("upstream id: %s not found", route.UpstreamID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+
+ if _, err := h.routeStore.CreateCheck(route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+
+ // create route
+ for _, route := range routes {
+ if Force == "1" && route.ID != nil {
+ if _, err := h.routeStore.Update(c.Context(), route, true); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ } else {
+ if _, err := h.routeStore.Create(c.Context(), route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+ }
+
+ return nil, nil
+}
+
+func checkRouteExist(ctx context.Context, routeStore *store.GenericStore, route *entity.Route) error {
+ //routeStore := store.GetStore(store.HubKeyRoute)
+ ret, err := routeStore.List(ctx, store.ListInput{
+ Predicate: func(obj interface{}) bool {
+ id := utils.InterfaceToString(route.ID)
+ item := obj.(*entity.Route)
+ if id != "" && id != utils.InterfaceToString(item.ID) {
+ return false
+ }
+
+ if !(item.Host == route.Host && item.URI == route.URI && utils.StringSliceEqual(item.Uris, route.Uris) &&
+ utils.StringSliceEqual(item.RemoteAddrs, route.RemoteAddrs) && item.RemoteAddr == route.RemoteAddr &&
+ utils.StringSliceEqual(item.Hosts, route.Hosts) && item.Priority == route.Priority &&
+ utils.ValueEqual(item.Vars, route.Vars) && item.FilterFunc == route.FilterFunc) {
+ return false
+ }
+ return true
+ },
+ PageSize: 0,
+ PageNumber: 0,
+ })
+ if err != nil {
+ return err
+ }
+ if len(ret.Rows) > 0 {
+ return consts.InvalidParam("route is duplicate")
+ }
+ return nil
+}
+
+func parseExtension(val *openapi3.Operation) (*entity.Route, error) {
+ routeMap := map[string]interface{}{}
+ for key, val := range val.Extensions {
+ if strings.HasPrefix(key, "x-apisix-") {
+ routeMap[strings.TrimPrefix(key, "x-apisix-")] = val
+ }
+ }
+
+ route := new(entity.Route)
+ routeJson, err := json.Marshal(routeMap)
+ if err != nil {
+ return nil, err
+ }
+
+ err = json.Unmarshal(routeJson, &route)
+ if err != nil {
+ return nil, err
+ }
+
+ return route, nil
+}
+
+type PathValue struct {
+ Method string
+ Value *openapi3.Operation
+}
+
+func mergePathValue(key string, values []PathValue, swagger *openapi3.Swagger) (map[string]*entity.Route, error) {
+ var parsed []PathValue
+ var routes = map[string]*entity.Route{}
+ for _, value := range values {
+ value.Value.OperationID = strings.Replace(value.Value.OperationID, value.Method, "", 1)
+ var eq = false
+ for _, v := range parsed {
+ if utils.ValueEqual(v.Value, value.Value) {
+ eq = true
+ if routes[v.Method].Methods == nil {
+ routes[v.Method].Methods = []string{}
+ }
+ routes[v.Method].Methods = append(routes[v.Method].Methods, value.Method)
+ }
+ }
+ // not equal to the previous ones
+ if !eq {
+ route, err := getRouteFromPaths(value.Method, key, value.Value, swagger)
+ if err != nil {
+ return nil, err
+ }
+ routes[value.Method] = route
+ parsed = append(parsed, value)
+ }
+ }
+
+ return routes, nil
+}
+
+func OpenAPI3ToRoute(swagger *openapi3.Swagger) ([]*entity.Route, error) {
+ var routes []*entity.Route
+ paths := swagger.Paths
+ var upstream *entity.UpstreamDef
+ var err error
+ for k, v := range paths {
+ upstream = &entity.UpstreamDef{}
+ if up, ok := v.Extensions["x-apisix-upstream"]; ok {
+ err = json.Unmarshal(up.(json.RawMessage), upstream)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var values []PathValue
+ if v.Get != nil {
+ value := PathValue{
+ Method: http.MethodGet,
+ Value: v.Get,
+ }
+ values = append(values, value)
+ }
+ if v.Post != nil {
+ value := PathValue{
+ Method: http.MethodPost,
+ Value: v.Post,
+ }
+ values = append(values, value)
+ }
+ if v.Head != nil {
+ value := PathValue{
+ Method: http.MethodHead,
+ Value: v.Head,
+ }
+ values = append(values, value)
+ }
+ if v.Put != nil {
+ value := PathValue{
+ Method: http.MethodPut,
+ Value: v.Put,
+ }
+ values = append(values, value)
+ }
+ if v.Patch != nil {
+ value := PathValue{
+ Method: http.MethodPatch,
+ Value: v.Patch,
+ }
+ values = append(values, value)
+ }
+ if v.Delete != nil {
+ value := PathValue{
+ Method: http.MethodDelete,
+ Value: v.Delete,
+ }
+ values = append(values, value)
+ }
+
+ // merge same route
+ tmp, err := mergePathValue(k, values, swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, route := range tmp {
+ routes = append(routes, route)
+ }
+ }
+
+ return routes, nil
+}
+
+func parseParameters(parameters openapi3.Parameters, plugins map[string]interface{}) {
+ props := make(map[string]interface{})
+ var required []string
+ for _, v := range parameters {
+ if v.Value.Schema != nil {
+ v.Value.Schema.Value.Format = ""
+ v.Value.Schema.Value.XML = nil
+ }
+
+ switch v.Value.In {
+ case "header":
+ if v.Value.Schema != nil && v.Value.Schema.Value != nil {
+ props[v.Value.Name] = v.Value.Schema.Value
+ }
+ if v.Value.Required {
+ required = append(required, v.Value.Name)
+ }
+ }
+ }
+
+ requestValidation := make(map[string]interface{})
+ if rv, ok := plugins["request-validation"]; ok {
+ requestValidation = rv.(map[string]interface{})
+ }
+ requestValidation["header_schema"] = &entity.RequestValidation{
+ Type: "object",
+ Required: required,
+ Properties: props,
+ }
+ plugins["request-validation"] = requestValidation
+}
+
+func parseRequestBody(requestBody *openapi3.RequestBodyRef, swagger *openapi3.Swagger, plugins map[string]interface{}) {
+ schema := requestBody.Value.Content
+ requestValidation := make(map[string]interface{})
+ if rv, ok := plugins["request-validation"]; ok {
+ requestValidation = rv.(map[string]interface{})
+ }
+ for _, v := range schema {
+ if v.Schema.Ref != "" {
+ s := getParameters(v.Schema.Ref, &swagger.Components).Value
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: s.Type,
+ Required: s.Required,
+ Properties: s.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ } else if v.Schema.Value != nil {
+ if v.Schema.Value.Properties != nil {
+ for k1, v1 := range v.Schema.Value.Properties {
+ if v1.Ref != "" {
+ s := getParameters(v1.Ref, &swagger.Components)
+ v.Schema.Value.Properties[k1] = s
+ }
+ v1.Value.Format = ""
+ }
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: v.Schema.Value.Type,
+ Required: v.Schema.Value.Required,
+ Properties: v.Schema.Value.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ } else if v.Schema.Value.Items != nil {
+ if v.Schema.Value.Items.Ref != "" {
+ s := getParameters(v.Schema.Value.Items.Ref, &swagger.Components).Value
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: s.Type,
+ Required: s.Required,
+ Properties: s.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ }
+ } else {
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: "object",
+ Required: []string{},
+ Properties: v.Schema.Value.Properties,
+ }
+ }
+ }
Review comment:
Need to remove the suffix.
##########
File path: api/test/e2e/http.go
##########
@@ -0,0 +1,106 @@
+/*
+ * 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 e2e
+
+import (
+ "bytes"
+ "encoding/json"
+ "io"
+ "io/ioutil"
+ "mime/multipart"
+ "net/http"
+ "net/url"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+type UploadFile struct {
+ Name string
+ Filepath string
+}
+
+var httpClient = &http.Client{}
+
+func PostFile(reqUrl string, reqParams map[string]string, files []UploadFile, headers map[string]string) string {
+ return post(reqUrl, reqParams, "multipart/form-data", files, headers)
+}
+
+func post(reqUrl string, reqParams map[string]string, contentType string, files []UploadFile, headers map[string]string) string {
+ requestBody, realContentType := getReader(reqParams, contentType, files)
+ httpRequest, _ := http.NewRequest("POST", reqUrl, requestBody)
+ httpRequest.Header.Add("Content-Type", realContentType)
+ if headers != nil {
+ for k, v := range headers {
+ httpRequest.Header.Add(k, v)
+ }
+ }
+ resp, err := httpClient.Do(httpRequest)
+
+ defer func() {
+ err = resp.Body.Close()
Review comment:
Need to make sure.
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,531 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet"
+ "github.com/shiningrush/droplet/data"
+ "github.com/shiningrush/droplet/middleware"
+ wgin "github.com/shiningrush/droplet/wrapper/gin"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ "github.com/apisix/manager-api/internal/log"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore *store.GenericStore
+ svcStore store.Interface
+ upstreamStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", wgin.Wraps(h.Import))
+}
+
+type ImportInput struct {
+ Force bool `auto_read:"force,query"`
+}
+
+func (h *Handler) Import(c droplet.Context) (interface{}, error) {
+ httpReq := c.Get(middleware.KeyHttpRequest)
+ if httpReq == nil {
+ return nil, errors.New("input middleware cannot get http request")
+ }
+ req := httpReq.(*http.Request)
+ req.Body = http.MaxBytesReader(nil, req.Body, int64(conf.ImportSizeLimit))
+ if err := req.ParseMultipartForm(int64(conf.ImportSizeLimit)); err != nil {
+ log.Warnf("upload file size exceeds limit: %s", err)
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ Force := req.URL.Query().Get("force")
+
+ _, fileHeader, err := req.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
+
+ // file check
+ suffix := path.Ext(fileHeader.Filename)
+ if suffix != ".json" && suffix != ".yaml" && suffix != ".yml" {
+ return nil, fmt.Errorf("required file type is .yaml, .yml or .json but got: %s", suffix)
+ }
+
+ // read file and parse
+ handle, err := fileHeader.Open()
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ err = handle.Close()
+ }()
+
+ reader := bufio.NewReader(handle)
+ bytes := make([]byte, fileHeader.Size)
+ _, err = reader.Read(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(swagger.Paths) < 1 {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ errors.New("empty or invalid imported file")
+ }
+
+ routes, err := OpenAPI3ToRoute(swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ // check route
+ for _, route := range routes {
+ err := checkRouteExist(c.Context(), h.routeStore, route)
+ if err != nil && Force != "1" {
+ log.Warnf("import duplicate: %s, route: %#v", err, route)
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ if route.ServiceID != nil {
+ _, err := h.svcStore.Get(c.Context(), utils.InterfaceToString(route.ServiceID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("service id: %s not found", route.ServiceID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.UpstreamID != nil {
+ _, err := h.upstreamStore.Get(c.Context(), utils.InterfaceToString(route.UpstreamID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("upstream id: %s not found", route.UpstreamID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+
+ if _, err := h.routeStore.CreateCheck(route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+
+ // create route
+ for _, route := range routes {
+ if Force == "1" && route.ID != nil {
+ if _, err := h.routeStore.Update(c.Context(), route, true); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ } else {
+ if _, err := h.routeStore.Create(c.Context(), route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+ }
+
+ return nil, nil
+}
+
+func checkRouteExist(ctx context.Context, routeStore *store.GenericStore, route *entity.Route) error {
+ //routeStore := store.GetStore(store.HubKeyRoute)
+ ret, err := routeStore.List(ctx, store.ListInput{
+ Predicate: func(obj interface{}) bool {
+ id := utils.InterfaceToString(route.ID)
+ item := obj.(*entity.Route)
+ if id != "" && id != utils.InterfaceToString(item.ID) {
+ return false
+ }
+
+ if !(item.Host == route.Host && item.URI == route.URI && utils.StringSliceEqual(item.Uris, route.Uris) &&
+ utils.StringSliceEqual(item.RemoteAddrs, route.RemoteAddrs) && item.RemoteAddr == route.RemoteAddr &&
+ utils.StringSliceEqual(item.Hosts, route.Hosts) && item.Priority == route.Priority &&
+ utils.ValueEqual(item.Vars, route.Vars) && item.FilterFunc == route.FilterFunc) {
+ return false
+ }
+ return true
+ },
+ PageSize: 0,
+ PageNumber: 0,
+ })
+ if err != nil {
+ return err
+ }
+ if len(ret.Rows) > 0 {
+ return consts.InvalidParam("route is duplicate")
+ }
+ return nil
+}
+
+func parseExtension(val *openapi3.Operation) (*entity.Route, error) {
+ routeMap := map[string]interface{}{}
+ for key, val := range val.Extensions {
+ if strings.HasPrefix(key, "x-apisix-") {
+ routeMap[strings.TrimPrefix(key, "x-apisix-")] = val
+ }
+ }
+
+ route := new(entity.Route)
+ routeJson, err := json.Marshal(routeMap)
+ if err != nil {
+ return nil, err
+ }
+
+ err = json.Unmarshal(routeJson, &route)
+ if err != nil {
+ return nil, err
+ }
+
+ return route, nil
+}
+
+type PathValue struct {
+ Method string
+ Value *openapi3.Operation
+}
+
+func mergePathValue(key string, values []PathValue, swagger *openapi3.Swagger) (map[string]*entity.Route, error) {
+ var parsed []PathValue
+ var routes = map[string]*entity.Route{}
+ for _, value := range values {
+ value.Value.OperationID = strings.Replace(value.Value.OperationID, value.Method, "", 1)
+ var eq = false
+ for _, v := range parsed {
+ if utils.ValueEqual(v.Value, value.Value) {
+ eq = true
+ if routes[v.Method].Methods == nil {
+ routes[v.Method].Methods = []string{}
+ }
+ routes[v.Method].Methods = append(routes[v.Method].Methods, value.Method)
+ }
+ }
+ // not equal to the previous ones
+ if !eq {
+ route, err := getRouteFromPaths(value.Method, key, value.Value, swagger)
+ if err != nil {
+ return nil, err
+ }
+ routes[value.Method] = route
+ parsed = append(parsed, value)
+ }
+ }
+
+ return routes, nil
+}
+
+func OpenAPI3ToRoute(swagger *openapi3.Swagger) ([]*entity.Route, error) {
+ var routes []*entity.Route
+ paths := swagger.Paths
+ var upstream *entity.UpstreamDef
+ var err error
+ for k, v := range paths {
+ upstream = &entity.UpstreamDef{}
+ if up, ok := v.Extensions["x-apisix-upstream"]; ok {
+ err = json.Unmarshal(up.(json.RawMessage), upstream)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var values []PathValue
+ if v.Get != nil {
+ value := PathValue{
+ Method: http.MethodGet,
+ Value: v.Get,
+ }
+ values = append(values, value)
+ }
+ if v.Post != nil {
+ value := PathValue{
+ Method: http.MethodPost,
+ Value: v.Post,
+ }
+ values = append(values, value)
+ }
+ if v.Head != nil {
+ value := PathValue{
+ Method: http.MethodHead,
+ Value: v.Head,
+ }
+ values = append(values, value)
+ }
+ if v.Put != nil {
+ value := PathValue{
+ Method: http.MethodPut,
+ Value: v.Put,
+ }
+ values = append(values, value)
+ }
+ if v.Patch != nil {
+ value := PathValue{
+ Method: http.MethodPatch,
+ Value: v.Patch,
+ }
+ values = append(values, value)
+ }
+ if v.Delete != nil {
+ value := PathValue{
+ Method: http.MethodDelete,
+ Value: v.Delete,
+ }
+ values = append(values, value)
+ }
+
+ // merge same route
+ tmp, err := mergePathValue(k, values, swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, route := range tmp {
+ routes = append(routes, route)
+ }
+ }
+
+ return routes, nil
+}
+
+func parseParameters(parameters openapi3.Parameters, plugins map[string]interface{}) {
+ props := make(map[string]interface{})
+ var required []string
+ for _, v := range parameters {
+ if v.Value.Schema != nil {
+ v.Value.Schema.Value.Format = ""
+ v.Value.Schema.Value.XML = nil
+ }
+
+ switch v.Value.In {
+ case "header":
+ if v.Value.Schema != nil && v.Value.Schema.Value != nil {
+ props[v.Value.Name] = v.Value.Schema.Value
+ }
+ if v.Value.Required {
+ required = append(required, v.Value.Name)
+ }
+ }
+ }
+
+ requestValidation := make(map[string]interface{})
+ if rv, ok := plugins["request-validation"]; ok {
+ requestValidation = rv.(map[string]interface{})
+ }
+ requestValidation["header_schema"] = &entity.RequestValidation{
+ Type: "object",
+ Required: required,
+ Properties: props,
+ }
+ plugins["request-validation"] = requestValidation
+}
+
+func parseRequestBody(requestBody *openapi3.RequestBodyRef, swagger *openapi3.Swagger, plugins map[string]interface{}) {
+ schema := requestBody.Value.Content
+ requestValidation := make(map[string]interface{})
+ if rv, ok := plugins["request-validation"]; ok {
+ requestValidation = rv.(map[string]interface{})
+ }
+ for _, v := range schema {
+ if v.Schema.Ref != "" {
+ s := getParameters(v.Schema.Ref, &swagger.Components).Value
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: s.Type,
+ Required: s.Required,
+ Properties: s.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ } else if v.Schema.Value != nil {
+ if v.Schema.Value.Properties != nil {
+ for k1, v1 := range v.Schema.Value.Properties {
+ if v1.Ref != "" {
+ s := getParameters(v1.Ref, &swagger.Components)
+ v.Schema.Value.Properties[k1] = s
+ }
+ v1.Value.Format = ""
+ }
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: v.Schema.Value.Type,
+ Required: v.Schema.Value.Required,
+ Properties: v.Schema.Value.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ } else if v.Schema.Value.Items != nil {
+ if v.Schema.Value.Items.Ref != "" {
+ s := getParameters(v.Schema.Value.Items.Ref, &swagger.Components).Value
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: s.Type,
+ Required: s.Required,
+ Properties: s.Properties,
+ }
+ plugins["request-validation"] = requestValidation
+ }
+ } else {
+ requestValidation["body_schema"] = &entity.RequestValidation{
+ Type: "object",
+ Required: []string{},
+ Properties: v.Schema.Value.Properties,
+ }
+ }
+ }
+ plugins["request-validation"] = requestValidation
+ }
+}
+
+func parseSecurity(security openapi3.SecurityRequirements, securitySchemes openapi3.SecuritySchemes, plugins map[string]interface{}) {
+ // todo: import consumers
+ for _, securities := range security {
+ for name := range securities {
+ if schema, ok := securitySchemes[name]; ok {
+ value := schema.Value
+ if value == nil {
+ continue
+ }
+
+ // basic auth
+ if value.Type == "http" && value.Scheme == "basic" {
+ plugins["basic-auth"] = map[string]interface{}{}
+ //username, ok := value.Extensions["username"]
+ //if !ok {
+ // continue
+ //}
+ //password, ok := value.Extensions["password"]
+ //if !ok {
+ // continue
+ //}
+ //plugins["basic-auth"] = map[string]interface{}{
+ // "username": username,
+ // "password": password,
+ //}
+ // jwt auth
+ } else if value.Type == "http" && value.Scheme == "bearer" && value.BearerFormat == "JWT" {
+ plugins["jwt-auth"] = map[string]interface{}{}
+ //key, ok := value.Extensions["key"]
+ //if !ok {
+ // continue
+ //}
+ //secret, ok := value.Extensions["secret"]
+ //if !ok {
+ // continue
+ //}
+ //plugins["jwt-auth"] = map[string]interface{}{
+ // "key": key,
+ // "secret": secret,
+ //}
+ // key auth
+ } else if value.Type == "apiKey" {
+ plugins["key-auth"] = map[string]interface{}{}
+ //key, ok := value.Extensions["key"]
+ //if !ok {
+ // continue
+ //}
+ //plugins["key-auth"] = map[string]interface{}{
+ // "key": key,
+ //}
+ }
+ }
+ }
+ }
+}
+
+func getRouteFromPaths(method, key string, value *openapi3.Operation, swagger *openapi3.Swagger) (*entity.Route, error) {
+ // transform /path/{var} to /path/*
+ reg := regexp.MustCompile(`{[\w.]*}`)
+ foundStr := reg.FindString(key)
+ if foundStr != "" {
+ key = strings.Split(key, foundStr)[0] + "*"
+ }
+
+ route, err := parseExtension(value)
+ if err != nil {
+ return nil, err
+ }
+
+ route.URI = key
Review comment:
Should be put in to URIs.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r555511815
##########
File path: api/test/e2e/import_test.go
##########
@@ -0,0 +1,238 @@
+/*
+ * 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 e2e
+
+import (
+ "github.com/stretchr/testify/assert"
+ "github.com/tidwall/gjson"
+ "io/ioutil"
+ "net/http"
+ "path/filepath"
+ "testing"
+)
+
+func TestImport_default(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test-default.yaml")
+ assert.Nil(t, err)
+
+ headers := map[string]string{
+ "Authorization": token,
+ }
+ files := []UploadFile{
+ {Name: "file", Filepath: path},
+ }
+ PostFile(ManagerAPIHost+"/apisix/admin/import", nil, files, headers)
+
+ request, _ := http.NewRequest("GET", ManagerAPIHost+"/apisix/admin/routes", nil)
+ request.Header.Add("Authorization", token)
+ resp, err := http.DefaultClient.Do(request)
+ assert.Nil(t, err)
+ defer resp.Body.Close()
+ respBody, _ := ioutil.ReadAll(resp.Body)
+ list := gjson.Get(string(respBody), "data.rows").Value().([]interface{})
+
+ var tests []HttpTestCase
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "route patch for update status(online)",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodPatch,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Body: `{"status":1}`,
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ Sleep: sleepTime,
+ }
+ tests = append(tests, tc)
+ }
+
+ // verify route
+ tests = append(tests, HttpTestCase{
+ Desc: "verify the route just imported",
+ Object: APISIXExpect(t),
+ Method: http.MethodGet,
+ Path: "/hello",
+ ExpectStatus: http.StatusOK,
+ ExpectBody: "hello world",
+ Sleep: sleepTime,
+ })
+
+ // delete test data
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "delete route",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodDelete,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ }
+ tests = append(tests, tc)
+ }
+
+ for _, tc := range tests {
+ testCaseCheck(tc, t)
+ }
+}
+
+func TestImport_json(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test.json")
+ assert.Nil(t, err)
+
+ headers := map[string]string{
+ "Authorization": token,
+ }
+ files := []UploadFile{
+ {Name: "file", Filepath: path},
+ }
+ PostFile(ManagerAPIHost+"/apisix/admin/import", nil, files, headers)
+
+ request, _ := http.NewRequest("GET", ManagerAPIHost+"/apisix/admin/routes", nil)
+ request.Header.Add("Authorization", token)
+ resp, err := http.DefaultClient.Do(request)
+ assert.Nil(t, err)
+ defer resp.Body.Close()
+ respBody, _ := ioutil.ReadAll(resp.Body)
+ list := gjson.Get(string(respBody), "data.rows").Value().([]interface{})
+
+ var tests []HttpTestCase
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "route patch for update status(online)",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodPatch,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Body: `{"status":1}`,
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ Sleep: sleepTime,
+ }
+ tests = append(tests, tc)
+ }
+
+ // verify route
+ tests = append(tests, HttpTestCase{
+ Desc: "verify the route just imported",
+ Object: APISIXExpect(t),
+ Method: http.MethodGet,
+ Path: "/hello",
+ ExpectStatus: http.StatusOK,
+ ExpectBody: "hello world",
+ Sleep: sleepTime,
+ })
+
+ // delete test data
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "delete route",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodDelete,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ }
+ tests = append(tests, tc)
+ }
+
+ for _, tc := range tests {
+ testCaseCheck(tc, t)
+ }
+}
+
+func TestImport_with_plugins(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test-plugins.yaml")
+ assert.Nil(t, err)
+
+ headers := map[string]string{
+ "Authorization": token,
+ }
+ files := []UploadFile{
+ {Name: "file", Filepath: path},
+ }
+ PostFile(ManagerAPIHost+"/apisix/admin/import", nil, files, headers)
+
+ request, _ := http.NewRequest("GET", ManagerAPIHost+"/apisix/admin/routes", nil)
+ request.Header.Add("Authorization", token)
+ resp, err := http.DefaultClient.Do(request)
+ assert.Nil(t, err)
+ defer resp.Body.Close()
+ respBody, _ := ioutil.ReadAll(resp.Body)
+ list := gjson.Get(string(respBody), "data.rows").Value().([]interface{})
+
+ var tests []HttpTestCase
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "route patch for update status(online)",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodPatch,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Body: `{"status":1}`,
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ Sleep: sleepTime,
+ }
+ tests = append(tests, tc)
+ }
+
+ // verify route
+ verifyTests := []HttpTestCase{
+ {
+ Desc: "verify the route just imported",
+ Object: APISIXExpect(t),
+ Method: http.MethodPost,
+ Path: "/hello",
+ Body: `{}`,
+ ExpectStatus: http.StatusBadRequest,
+ ExpectBody: `property "status" is required`,
+ Sleep: sleepTime,
+ },
+ {
+ Desc: "verify the route just imported",
+ Object: APISIXExpect(t),
+ Method: http.MethodPost,
+ Path: "/hello",
+ Body: `{"status": "1"}`,
+ ExpectStatus: http.StatusUnauthorized,
+ ExpectBody: `{"message":"Missing authorization in request"}`,
+ Sleep: sleepTime,
+ },
+ }
+ tests = append(tests, verifyTests...)
+
+ // delete test data
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "delete route",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodDelete,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ }
+ tests = append(tests, tc)
+ }
+
+ for _, tc := range tests {
+ testCaseCheck(tc, t)
+ }
+}
Review comment:
while debugging Fe, I found the file below could also be imported, It would be better to add a test case to cover the wrong file.
```yaml
#
# 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.
#
conf:
listen:
host: 127.0.0.1 # `manager api` listening ip or host name
port: 9000 # `manager api` listening port
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
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
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
# 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": []}
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
```
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r555161547
##########
File path: api/test/testdata/import-test-plugins.yaml
##########
@@ -0,0 +1,99 @@
+#
+# 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.
+#
+# 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:
+#
+consumes:
+- application/json
+- application/xml
+components:
+ securitySchemes:
+ basicAuth:
+ type: http
+ scheme: basic
+ username: test
+ password: testp
+info:
+ description: |-
+ test desc
+ license:
+ name: Apache License 2.0
+ url: http://www.apache.org/licenses/LICENSE-2.0
+ title: |-
+ test title
+paths:
+ /hello:
+ post:
+ x-api-limit: 20
+ description: |-
+ hello world.
+ operationId: hello
+ x-apisix-upstream:
+ type: roundrobin
+ nodes:
+ - host: "172.16.238.20"
+ port: 1980
+ weight: 1
+ parameters:
+ - name: id
+ in: header
+ description: ID of pet to use
+ required: true
+ schema:
+ type: array
+ items:
+ type: string
+ style: simple
+
+ requestBody:
+ content:
+ 'application/x-www-form-urlencoded':
+ schema:
+ properties:
+ name:
+ description: Updated name of the pet
+ type: string
+ status:
+ description: Updated status of the pet
+ type: string
+ required:
+ - status
+
+ produces:
+ - application/json
+
+ security:
+ - basicAuth: []
+
+ responses:
+ "0":
+ description: list response
+ schema:
+ items:
+ $ref: '#/definitions/service'
+ type: array
+ default:
+ description: unexpected error
+ schema:
+ $ref: '#/definitions/ApiError'
+produces:
+- application/json
+- application/xml
+schemes:
+- http
+- https
+swagger: "2.0"
Review comment:
I noticed that the version of this test file is swagger is 2.0, and our basic version of this issue is OAS3.0, which equals to swagger 3.0. As far as I know, there are some difference between the these versions, so I just want to make sure that is the current feature compatible with two versions of file or just for 2.0?
For the export feature in #1245 is only for 3.0 now, baseline alignment is necessary.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-764442783
Do we need to add **test cases** about
1. import a error file
2. a file includes two or more APIs
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (4e06b76) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/1bdcaa8df2fe2fa6caba23809e69e26c5ad7902d?el=desc) (1bdcaa8) will **decrease** coverage by `19.95%`.
> The diff coverage is `31.72%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
===========================================
- Coverage 62.29% 42.33% -19.96%
===========================================
Files 42 34 -8
Lines 2395 2258 -137
===========================================
- Hits 1492 956 -536
- Misses 722 1165 +443
+ Partials 181 137 -44
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (-62.50%)` | :arrow_down: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (-55.47%)` | :arrow_down: |
| [api/internal/utils/utils.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3V0aWxzL3V0aWxzLmdv) | `47.56% <0.00%> (-23.66%)` | :arrow_down: |
| [api/internal/handler/data\_loader/import.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvZGF0YV9sb2FkZXIvaW1wb3J0Lmdv) | `29.96% <29.96%> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `46.52% <66.66%> (-20.87%)` | :arrow_down: |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.10% <75.00%> (-10.83%)` | :arrow_down: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `81.81% <100.00%> (-4.26%)` | :arrow_down: |
| [api/internal/filter/request\_id.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9yZXF1ZXN0X2lkLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [api/internal/core/store/storehub.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmVodWIuZ28=) | `0.00% <0.00%> (-74.49%)` | :arrow_down: |
| [api/internal/filter/cors.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9jb3JzLmdv) | `0.00% <0.00%> (-66.67%)` | :arrow_down: |
| ... and [30 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [1bdcaa8...4e06b76](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] nic-chen commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
nic-chen commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-759184568
> > > before we import new route data, do we need to clean the old route first?
> >
> >
> > I think that the original data should not be modified, and the status of the imported route should be `offline`.
>
> agree with the `offline` status, and do we consider letting the user choose whether to override it or not? that may be more flexible
I feel that there is a certain risk in overriding, and I don't think it is necessary to do so. Waiting for the opinions of others. .
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] juzhiyuan commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-764448583
> Do we need to add **test cases** about
>
> 1. import a error file
> 2. a file includes two or more APIs
Yep
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] juzhiyuan commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-760885133
> For example, how can I change my folder to your folder name 'data loader'.
Couldn't get your point 🤣 just to make sure, do you mean if we could keep those 2 files at the same folder?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] tokers commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
tokers commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-760951330
@Jaycean Conflicts should be resolved firstly :)
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-764442783
Do we need to add **test cases** about
1. import a error file
2. a file includes two or more APIs
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] nic-chen commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
nic-chen commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-759145529
> before we import new route data, do we need to clean the old route first?
I think that the original data should not be modified, and the status of the imported route should be `offline`.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (9576e27) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/81dbdbfd639610b653f9ac7ed95c559aa890c5e3?el=desc) (81dbdbf) will **decrease** coverage by `18.87%`.
> The diff coverage is `41.17%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
===========================================
- Coverage 63.13% 44.25% -18.88%
===========================================
Files 41 32 -9
Lines 2360 1986 -374
===========================================
- Hits 1490 879 -611
- Misses 695 996 +301
+ Partials 175 111 -64
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (-62.50%)` | :arrow_down: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (-55.47%)` | :arrow_down: |
| [api/internal/utils/utils.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3V0aWxzL3V0aWxzLmdv) | `47.56% <0.00%> (-23.66%)` | :arrow_down: |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `46.52% <66.66%> (-20.87%)` | :arrow_down: |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.10% <75.00%> (-10.83%)` | :arrow_down: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `81.81% <81.81%> (-5.84%)` | :arrow_down: |
| [api/internal/filter/request\_id.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9yZXF1ZXN0X2lkLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [api/internal/core/store/storehub.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmVodWIuZ28=) | `0.00% <0.00%> (-74.49%)` | :arrow_down: |
| [api/internal/filter/cors.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9jb3JzLmdv) | `0.00% <0.00%> (-66.67%)` | :arrow_down: |
| ... and [27 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [81dbdbf...9576e27](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] Jaycean commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
Jaycean commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-760798891
Hi, the two functions of import and export are closely related, so I want to discuss the name of the folder with you. I personally think that the two files are ultimately in one folder. For example, how can I change my folder to your folder name 'data loader'. I wonder if you have any good suggestions
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] Jaycean commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
Jaycean commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-762555156
> > Hi, the two functions of import and export are closely related, so I want to discuss the name of the folder with you. I personally think that the two files are ultimately in one folder. For example, how can I change my folder to your folder name 'data loader'. I wonder if you have any good suggestions
>
> how about we use the same folder name `data_loader` ? just rename your folder.
Now I change my folder name, and there is a problem of package reference, but if I change my package to 'data_loader', I don't think the description of my function is accurate, so I'll discuss it with you. Because the folder contains import and export functions, we can change the folder to 'data_operation' Do you have any other good suggestions?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (c1a6a1c) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/61f7c210baa21c65f0fa46dc0f1301ee96ccd7a5?el=desc) (61f7c21) will **increase** coverage by `0.29%`.
> The diff coverage is `81.81%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
==========================================
+ Coverage 42.44% 42.73% +0.29%
==========================================
Files 31 31
Lines 1932 1942 +10
==========================================
+ Hits 820 830 +10
Misses 1001 1001
Partials 111 111
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (ø)` | |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `43.43% <66.66%> (ø)` | |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.33% <80.00%> (+0.70%)` | :arrow_up: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `80.83% <85.71%> (+0.83%)` | :arrow_up: |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [61f7c21...c1a6a1c](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] nic-chen commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
nic-chen commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-760890023
> Hi, the two functions of import and export are closely related, so I want to discuss the name of the folder with you. I personally think that the two files are ultimately in one folder. For example, how can I change my folder to your folder name 'data loader'. I wonder if you have any good suggestions
how about we use the same folder name `data_loader` ? just rename your folder.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] Jaycean commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
Jaycean commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-761918967
> > Hi, the two functions of import and export are closely related, so I want to discuss the name of the folder with you. I personally think that the two files are ultimately in one folder. For example, how can I change my folder to your folder name 'data loader'. I wonder if you have any good suggestions
>
> how about we use the same folder name `data_loader` ? just rename your folder.
no problem.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] nic-chen commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
nic-chen commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-765366914
> Do we need to add a test case about a route with as many props as possible
sure
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] nic-chen commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
nic-chen commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r556206018
##########
File path: api/test/testdata/import-test-plugins.yaml
##########
@@ -0,0 +1,99 @@
+#
+# 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.
+#
+# 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:
+#
+consumes:
+- application/json
+- application/xml
+components:
+ securitySchemes:
+ basicAuth:
+ type: http
+ scheme: basic
+ username: test
+ password: testp
+info:
+ description: |-
+ test desc
+ license:
+ name: Apache License 2.0
+ url: http://www.apache.org/licenses/LICENSE-2.0
+ title: |-
+ test title
+paths:
+ /hello:
+ post:
+ x-api-limit: 20
+ description: |-
+ hello world.
+ operationId: hello
+ x-apisix-upstream:
+ type: roundrobin
+ nodes:
+ - host: "172.16.238.20"
+ port: 1980
+ weight: 1
+ parameters:
+ - name: id
+ in: header
+ description: ID of pet to use
+ required: true
+ schema:
+ type: array
+ items:
+ type: string
+ style: simple
+
+ requestBody:
+ content:
+ 'application/x-www-form-urlencoded':
+ schema:
+ properties:
+ name:
+ description: Updated name of the pet
+ type: string
+ status:
+ description: Updated status of the pet
+ type: string
+ required:
+ - status
+
+ produces:
+ - application/json
+
+ security:
+ - basicAuth: []
+
+ responses:
+ "0":
+ description: list response
+ schema:
+ items:
+ $ref: '#/definitions/service'
+ type: array
+ default:
+ description: unexpected error
+ schema:
+ $ref: '#/definitions/ApiError'
+produces:
+- application/json
+- application/xml
+schemes:
+- http
+- https
+swagger: "2.0"
Review comment:
fixed.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-759148662
> > before we import new route data, do we need to clean the old route first?
>
> I think that the original data should not be modified, and the status of the imported route should be `offline`.
agree with the `offline` status, and do we consider letting the user choose whether to override it or not? that may be more flexible
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] tokers commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
tokers commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r557885773
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,468 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet/data"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ routeHandler "github.com/apisix/manager-api/internal/handler/route"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore store.Interface
+ svcStore store.Interface
+ upstreamStore store.Interface
+ scriptStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ scriptStore: store.GetStore(store.HubKeyScript),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", consts.ErrorWrapper(Import))
+}
+
+func Import(c *gin.Context) (interface{}, error) {
+ file, err := c.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
+
+ // file check
+ suffix := path.Ext(file.Filename)
+ if suffix != ".json" && suffix != ".yaml" && suffix != ".yml" {
+ return nil, fmt.Errorf("the file type error: %s", suffix)
+ }
+ if file.Size > int64(conf.ImportSizeLimit) {
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ // read file and parse
+ handle, err := file.Open()
+ defer func() {
+ err = handle.Close()
+ }()
+ if err != nil {
+ return nil, err
+ }
+
+ reader := bufio.NewReader(handle)
+ bytes := make([]byte, file.Size)
+ _, err = reader.Read(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ routes, err := OpenAPI3ToRoute(swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ routeStore := store.GetStore(store.HubKeyRoute)
+ upstreamStore := store.GetStore(store.HubKeyUpstream)
+ scriptStore := store.GetStore(store.HubKeyScript)
+
+ // check route
+ for _, route := range routes {
+ _, err := checkRouteName(route.Name)
+ if err != nil {
+ continue
+ }
+ if route.ServiceID != nil {
+ _, err := routeStore.Get(utils.InterfaceToString(route.ServiceID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("service id: %s not found", route.ServiceID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.UpstreamID != nil {
+ _, err := upstreamStore.Get(utils.InterfaceToString(route.UpstreamID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("upstream id: %s not found", route.UpstreamID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.Script != nil {
+ if route.ID == "" {
+ route.ID = utils.GetFlakeUidStr()
+ }
+ script := &entity.Script{}
+ script.ID = utils.InterfaceToString(route.ID)
+ script.Script = route.Script
Review comment:
```suggestion
script := &entity.Script{
ID: utils.InterfaceToString(route.ID),
Script: route.Script,
}
```
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,468 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet/data"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ routeHandler "github.com/apisix/manager-api/internal/handler/route"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore store.Interface
+ svcStore store.Interface
+ upstreamStore store.Interface
+ scriptStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ scriptStore: store.GetStore(store.HubKeyScript),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", consts.ErrorWrapper(Import))
+}
+
+func Import(c *gin.Context) (interface{}, error) {
+ file, err := c.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
+
+ // file check
+ suffix := path.Ext(file.Filename)
+ if suffix != ".json" && suffix != ".yaml" && suffix != ".yml" {
+ return nil, fmt.Errorf("the file type error: %s", suffix)
+ }
+ if file.Size > int64(conf.ImportSizeLimit) {
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ // read file and parse
+ handle, err := file.Open()
+ defer func() {
Review comment:
Should check `err` before the `defer` call.
##########
File path: api/internal/core/store/validate.go
##########
@@ -243,6 +245,8 @@ func (v *APISIXJsonSchemaValidator) Validate(obj interface{}) error {
}
errString.AppendString(vErr.String())
}
+ j, _ := json.Marshal(obj)
+ log.Errorf("schema validate failed:s: %v, obj: %s", v.schemaDef, string(j))
Review comment:
Why not just using `%#v` to show the object?
##########
File path: api/internal/handler/data_loader/import.go
##########
@@ -0,0 +1,468 @@
+/*
+ * 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 data_loader
+
+import (
+ "bufio"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "path"
+ "regexp"
+ "strings"
+
+ "github.com/getkin/kin-openapi/openapi3"
+ "github.com/gin-gonic/gin"
+ "github.com/shiningrush/droplet/data"
+
+ "github.com/apisix/manager-api/internal/conf"
+ "github.com/apisix/manager-api/internal/core/entity"
+ "github.com/apisix/manager-api/internal/core/store"
+ "github.com/apisix/manager-api/internal/handler"
+ routeHandler "github.com/apisix/manager-api/internal/handler/route"
+ "github.com/apisix/manager-api/internal/utils"
+ "github.com/apisix/manager-api/internal/utils/consts"
+)
+
+type Handler struct {
+ routeStore store.Interface
+ svcStore store.Interface
+ upstreamStore store.Interface
+ scriptStore store.Interface
+}
+
+func NewHandler() (handler.RouteRegister, error) {
+ return &Handler{
+ routeStore: store.GetStore(store.HubKeyRoute),
+ svcStore: store.GetStore(store.HubKeyService),
+ upstreamStore: store.GetStore(store.HubKeyUpstream),
+ scriptStore: store.GetStore(store.HubKeyScript),
+ }, nil
+}
+
+func (h *Handler) ApplyRoute(r *gin.Engine) {
+ r.POST("/apisix/admin/import", consts.ErrorWrapper(Import))
+}
+
+func Import(c *gin.Context) (interface{}, error) {
+ file, err := c.FormFile("file")
+ if err != nil {
+ return nil, err
+ }
+
+ // file check
+ suffix := path.Ext(file.Filename)
+ if suffix != ".json" && suffix != ".yaml" && suffix != ".yml" {
+ return nil, fmt.Errorf("the file type error: %s", suffix)
+ }
+ if file.Size > int64(conf.ImportSizeLimit) {
+ return nil, fmt.Errorf("the file size exceeds the limit; limit %d", conf.ImportSizeLimit)
+ }
+
+ // read file and parse
+ handle, err := file.Open()
+ defer func() {
+ err = handle.Close()
+ }()
+ if err != nil {
+ return nil, err
+ }
+
+ reader := bufio.NewReader(handle)
+ bytes := make([]byte, file.Size)
+ _, err = reader.Read(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(bytes)
+ if err != nil {
+ return nil, err
+ }
+
+ routes, err := OpenAPI3ToRoute(swagger)
+ if err != nil {
+ return nil, err
+ }
+
+ routeStore := store.GetStore(store.HubKeyRoute)
+ upstreamStore := store.GetStore(store.HubKeyUpstream)
+ scriptStore := store.GetStore(store.HubKeyScript)
+
+ // check route
+ for _, route := range routes {
+ _, err := checkRouteName(route.Name)
+ if err != nil {
+ continue
+ }
+ if route.ServiceID != nil {
+ _, err := routeStore.Get(utils.InterfaceToString(route.ServiceID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("service id: %s not found", route.ServiceID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.UpstreamID != nil {
+ _, err := upstreamStore.Get(utils.InterfaceToString(route.UpstreamID))
+ if err != nil {
+ if err == data.ErrNotFound {
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
+ fmt.Errorf("upstream id: %s not found", route.UpstreamID)
+ }
+ return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
+ }
+ }
+ if route.Script != nil {
+ if route.ID == "" {
+ route.ID = utils.GetFlakeUidStr()
+ }
+ script := &entity.Script{}
+ script.ID = utils.InterfaceToString(route.ID)
+ script.Script = route.Script
+ // to lua
+ var err error
+ route.Script, err = routeHandler.GenerateLuaCode(route.Script.(map[string]interface{}))
+ if err != nil {
+ return nil, err
+ }
+ // save original conf
+ if err = scriptStore.Create(c, script); err != nil {
+ return nil, err
+ }
+ }
+
+ if _, err := routeStore.CreateCheck(route); err != nil {
+ return handler.SpecCodeResponse(err), err
+ }
+ }
+
+ // create route
+ for _, route := range routes {
+ if err := routeStore.Create(c, route); err != nil {
+ println(err.Error())
Review comment:
Debugging code?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (f370f54) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/754f5598706fe5dfe9a09bf0d51d0701406c692c?el=desc) (754f559) will **increase** coverage by `0.23%`.
> The diff coverage is `88.88%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
==========================================
+ Coverage 44.19% 44.43% +0.23%
==========================================
Files 31 31
Lines 1948 1958 +10
==========================================
+ Hits 861 870 +9
- Misses 975 976 +1
Partials 112 112
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (ø)` | |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `46.49% <66.66%> (ø)` | |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.33% <80.00%> (+0.70%)` | :arrow_up: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `79.76% <100.00%> (+0.25%)` | :arrow_up: |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [754f559...f370f54](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-765343958
Do we need to add a test case about a route with as many props as possible?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] membphis commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
membphis commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-759181507
> how about giving the choice to users? e.g: Add a param to deside whether to cover the old routes or return a error, which tells users that they already have the same routes.
I think this is a good way. we can implement the first version: `return error` ^_^
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (0e71f3b) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/754f5598706fe5dfe9a09bf0d51d0701406c692c?el=desc) (754f559) will **increase** coverage by `0.25%`.
> The diff coverage is `88.23%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
==========================================
+ Coverage 44.19% 44.45% +0.25%
==========================================
Files 31 31
Lines 1948 1957 +9
==========================================
+ Hits 861 870 +9
Misses 975 975
Partials 112 112
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (ø)` | |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `46.49% <66.66%> (ø)` | |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.10% <75.00%> (+0.47%)` | :arrow_up: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `80.35% <100.00%> (+0.85%)` | :arrow_up: |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [754f559...0e71f3b](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (1caeb35) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/81dbdbfd639610b653f9ac7ed95c559aa890c5e3?el=desc) (81dbdbf) will **decrease** coverage by `18.56%`.
> The diff coverage is `72.22%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
===========================================
- Coverage 63.13% 44.56% -18.57%
===========================================
Files 41 32 -9
Lines 2360 1970 -390
===========================================
- Hits 1490 878 -612
- Misses 695 981 +286
+ Partials 175 111 -64
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (-62.50%)` | :arrow_down: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (-55.47%)` | :arrow_down: |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `46.52% <66.66%> (-20.87%)` | :arrow_down: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `81.21% <72.72%> (-6.45%)` | :arrow_down: |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.10% <75.00%> (-10.83%)` | :arrow_down: |
| [api/internal/filter/request\_id.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9yZXF1ZXN0X2lkLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [api/internal/core/store/storehub.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmVodWIuZ28=) | `0.00% <0.00%> (-74.49%)` | :arrow_down: |
| [api/internal/filter/cors.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9jb3JzLmdv) | `0.00% <0.00%> (-66.67%)` | :arrow_down: |
| ... and [26 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [81dbdbf...1caeb35](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (1de6730) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/61f7c210baa21c65f0fa46dc0f1301ee96ccd7a5?el=desc) (61f7c21) will **increase** coverage by `0.24%`.
> The diff coverage is `81.81%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
==========================================
+ Coverage 42.44% 42.68% +0.24%
==========================================
Files 31 31
Lines 1932 1942 +10
==========================================
+ Hits 820 829 +9
- Misses 1001 1002 +1
Partials 111 111
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (ø)` | |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `43.43% <66.66%> (ø)` | |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.33% <80.00%> (+0.70%)` | :arrow_up: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `80.23% <85.71%> (+0.23%)` | :arrow_up: |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [61f7c21...1de6730](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r561648621
##########
File path: api/test/e2e/import_test.go
##########
@@ -0,0 +1,248 @@
+/*
+ * 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 e2e
+
+import (
+ "github.com/stretchr/testify/assert"
+ "github.com/tidwall/gjson"
+ "io/ioutil"
+ "net/http"
+ "path/filepath"
+ "testing"
+ "time"
+)
+
+func TestImport_default(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test-default.yaml")
+ assert.Nil(t, err)
+
+ headers := map[string]string{
+ "Authorization": token,
+ }
+ files := []UploadFile{
+ {Name: "file", Filepath: path},
+ }
+ PostFile(ManagerAPIHost+"/apisix/admin/import", nil, files, headers)
+
+ // sleep for data sync
+ time.Sleep(sleepTime)
+
+ request, _ := http.NewRequest("GET", ManagerAPIHost+"/apisix/admin/routes", nil)
+ request.Header.Add("Authorization", token)
+ resp, err := http.DefaultClient.Do(request)
+ assert.Nil(t, err)
+ defer resp.Body.Close()
+ respBody, _ := ioutil.ReadAll(resp.Body)
+ list := gjson.Get(string(respBody), "data.rows").Value().([]interface{})
+
+ var tests []HttpTestCase
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "route patch for update status(online)",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodPatch,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Body: `{"status":1}`,
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ Sleep: sleepTime,
+ }
+ tests = append(tests, tc)
+ }
+
+ // verify route
+ tests = append(tests, HttpTestCase{
+ Desc: "verify the route just imported",
+ Object: APISIXExpect(t),
+ Method: http.MethodGet,
+ Path: "/hello",
+ ExpectStatus: http.StatusOK,
+ ExpectBody: "hello world",
+ Sleep: sleepTime,
+ })
+
+ // delete test data
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "delete route",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodDelete,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ }
+ tests = append(tests, tc)
+ }
+
+ for _, tc := range tests {
+ testCaseCheck(tc, t)
+ }
+}
+
+func TestImport_json(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test.json")
+ assert.Nil(t, err)
+
+ headers := map[string]string{
+ "Authorization": token,
+ }
+ files := []UploadFile{
+ {Name: "file", Filepath: path},
+ }
+ PostFile(ManagerAPIHost+"/apisix/admin/import", nil, files, headers)
+
+ // sleep for data sync
+ time.Sleep(sleepTime)
+
+ request, _ := http.NewRequest("GET", ManagerAPIHost+"/apisix/admin/routes", nil)
+ request.Header.Add("Authorization", token)
+ resp, err := http.DefaultClient.Do(request)
+ assert.Nil(t, err)
+ defer resp.Body.Close()
+ respBody, _ := ioutil.ReadAll(resp.Body)
+ list := gjson.Get(string(respBody), "data.rows").Value().([]interface{})
+
+ var tests []HttpTestCase
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "route patch for update status(online)",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodPatch,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Body: `{"status":1}`,
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ Sleep: sleepTime,
+ }
+ tests = append(tests, tc)
+ }
+
+ // verify route
+ tests = append(tests, HttpTestCase{
+ Desc: "verify the route just imported",
+ Object: APISIXExpect(t),
+ Method: http.MethodGet,
+ Path: "/hello",
+ ExpectStatus: http.StatusOK,
+ ExpectBody: "hello world",
+ Sleep: sleepTime,
+ })
+
+ // delete test data
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "delete route",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodDelete,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ }
+ tests = append(tests, tc)
+ }
+
+ for _, tc := range tests {
+ testCaseCheck(tc, t)
+ }
+}
+
+func TestImport_with_plugins(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test-plugins.yaml")
Review comment:
I have a question @nic-chen
It seems that the API in this file includes a required header params `id`(/testdata/import-test-plugins.yaml L48-57), but the route imported from this file did not has header params validation.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] nic-chen commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
nic-chen commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-764209076
> @nic-chen Hi, the CI of your PR has not been passed. You need to rebase the master branch, and the get list method of store needs to add the `context` parameter
thanks for remind.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-768155965
ping @starsz @imjoey @Jaycean for review, thanks
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (be06fbc) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/6d7f11a14c84c4f918827ae5f24befaf02bf681f?el=desc) (6d7f11a) will **decrease** coverage by `1.02%`.
> The diff coverage is `46.61%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
==========================================
- Coverage 62.79% 61.77% -1.03%
==========================================
Files 41 42 +1
Lines 2352 2595 +243
==========================================
+ Hits 1477 1603 +126
- Misses 700 787 +87
- Partials 175 205 +30
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/conf/conf.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvbmYvY29uZi5nbw==) | `67.85% <ø> (ø)` | |
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `81.25% <ø> (+18.75%)` | :arrow_up: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `55.46% <ø> (ø)` | |
| [api/internal/handler/data\_loader/import.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvZGF0YV9sb2FkZXIvaW1wb3J0Lmdv) | `43.34% <43.34%> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `68.26% <66.66%> (+0.86%)` | :arrow_up: |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `69.27% <75.00%> (+0.34%)` | :arrow_up: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `88.62% <100.00%> (+0.49%)` | :arrow_up: |
| [api/internal/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3JvdXRlLmdv) | `84.37% <100.00%> (+0.50%)` | :arrow_up: |
| [api/internal/core/storage/etcd.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmFnZS9ldGNkLmdv) | `44.94% <0.00%> (-2.25%)` | :arrow_down: |
| ... and [6 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [6d7f11a...be06fbc](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] Jaycean commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
Jaycean commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-764194110
@nic-chen Hi, the CI of your PR has not been passed. You need to rebase the master branch, and the get list method of store needs to add the `context` parameter
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (a47ef38) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/6d7f11a14c84c4f918827ae5f24befaf02bf681f?el=desc) (6d7f11a) will **decrease** coverage by `1.06%`.
> The diff coverage is `46.61%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
==========================================
- Coverage 62.79% 61.73% -1.07%
==========================================
Files 41 42 +1
Lines 2352 2595 +243
==========================================
+ Hits 1477 1602 +125
- Misses 700 791 +91
- Partials 175 202 +27
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/conf/conf.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvbmYvY29uZi5nbw==) | `67.85% <ø> (ø)` | |
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `81.25% <ø> (+18.75%)` | :arrow_up: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `55.46% <ø> (ø)` | |
| [api/internal/handler/data\_loader/import.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvZGF0YV9sb2FkZXIvaW1wb3J0Lmdv) | `43.34% <43.34%> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `68.26% <66.66%> (+0.86%)` | :arrow_up: |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `69.27% <75.00%> (+0.34%)` | :arrow_up: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `88.62% <100.00%> (+0.49%)` | :arrow_up: |
| [api/internal/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3JvdXRlLmdv) | `84.37% <100.00%> (+0.50%)` | :arrow_up: |
| [api/cmd/managerapi.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2NtZC9tYW5hZ2VyYXBpLmdv) | `70.83% <0.00%> (-6.25%)` | :arrow_down: |
| [api/internal/utils/closer.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3V0aWxzL2Nsb3Nlci5nbw==) | `33.33% <0.00%> (ø)` | |
| ... and [7 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [6d7f11a...a47ef38](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r561648621
##########
File path: api/test/e2e/import_test.go
##########
@@ -0,0 +1,248 @@
+/*
+ * 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 e2e
+
+import (
+ "github.com/stretchr/testify/assert"
+ "github.com/tidwall/gjson"
+ "io/ioutil"
+ "net/http"
+ "path/filepath"
+ "testing"
+ "time"
+)
+
+func TestImport_default(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test-default.yaml")
+ assert.Nil(t, err)
+
+ headers := map[string]string{
+ "Authorization": token,
+ }
+ files := []UploadFile{
+ {Name: "file", Filepath: path},
+ }
+ PostFile(ManagerAPIHost+"/apisix/admin/import", nil, files, headers)
+
+ // sleep for data sync
+ time.Sleep(sleepTime)
+
+ request, _ := http.NewRequest("GET", ManagerAPIHost+"/apisix/admin/routes", nil)
+ request.Header.Add("Authorization", token)
+ resp, err := http.DefaultClient.Do(request)
+ assert.Nil(t, err)
+ defer resp.Body.Close()
+ respBody, _ := ioutil.ReadAll(resp.Body)
+ list := gjson.Get(string(respBody), "data.rows").Value().([]interface{})
+
+ var tests []HttpTestCase
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "route patch for update status(online)",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodPatch,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Body: `{"status":1}`,
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ Sleep: sleepTime,
+ }
+ tests = append(tests, tc)
+ }
+
+ // verify route
+ tests = append(tests, HttpTestCase{
+ Desc: "verify the route just imported",
+ Object: APISIXExpect(t),
+ Method: http.MethodGet,
+ Path: "/hello",
+ ExpectStatus: http.StatusOK,
+ ExpectBody: "hello world",
+ Sleep: sleepTime,
+ })
+
+ // delete test data
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "delete route",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodDelete,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ }
+ tests = append(tests, tc)
+ }
+
+ for _, tc := range tests {
+ testCaseCheck(tc, t)
+ }
+}
+
+func TestImport_json(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test.json")
+ assert.Nil(t, err)
+
+ headers := map[string]string{
+ "Authorization": token,
+ }
+ files := []UploadFile{
+ {Name: "file", Filepath: path},
+ }
+ PostFile(ManagerAPIHost+"/apisix/admin/import", nil, files, headers)
+
+ // sleep for data sync
+ time.Sleep(sleepTime)
+
+ request, _ := http.NewRequest("GET", ManagerAPIHost+"/apisix/admin/routes", nil)
+ request.Header.Add("Authorization", token)
+ resp, err := http.DefaultClient.Do(request)
+ assert.Nil(t, err)
+ defer resp.Body.Close()
+ respBody, _ := ioutil.ReadAll(resp.Body)
+ list := gjson.Get(string(respBody), "data.rows").Value().([]interface{})
+
+ var tests []HttpTestCase
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "route patch for update status(online)",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodPatch,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Body: `{"status":1}`,
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ Sleep: sleepTime,
+ }
+ tests = append(tests, tc)
+ }
+
+ // verify route
+ tests = append(tests, HttpTestCase{
+ Desc: "verify the route just imported",
+ Object: APISIXExpect(t),
+ Method: http.MethodGet,
+ Path: "/hello",
+ ExpectStatus: http.StatusOK,
+ ExpectBody: "hello world",
+ Sleep: sleepTime,
+ })
+
+ // delete test data
+ for _, item := range list {
+ route := item.(map[string]interface{})
+ tc := HttpTestCase{
+ Desc: "delete route",
+ Object: ManagerApiExpect(t),
+ Method: http.MethodDelete,
+ Path: "/apisix/admin/routes/" + route["id"].(string),
+ Headers: map[string]string{"Authorization": token},
+ ExpectStatus: http.StatusOK,
+ }
+ tests = append(tests, tc)
+ }
+
+ for _, tc := range tests {
+ testCaseCheck(tc, t)
+ }
+}
+
+func TestImport_with_plugins(t *testing.T) {
+ path, err := filepath.Abs("../testdata/import-test-plugins.yaml")
Review comment:
I have a question @nic-chen
It seems that the API in this file includes a required header params `id`(/testdata/import-test-plugins.yaml L48-57), but the route imported from this file did not has header params validation.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] juzhiyuan commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r559947748
##########
File path: api/test/testdata/import-test-plugins.yaml
##########
@@ -61,17 +61,17 @@ paths:
'application/x-www-form-urlencoded':
schema:
properties:
- name:
- description: Updated name of the pet
- type: string
- status:
- description: Updated status of the pet
- type: string
+ name:
+ description: Updated name of the pet
Review comment:
```suggestion
description: Update pet's name
```
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io commented on pull request #1102: Import & Export route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (17b356c) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/3d14164e276eb3c846888f0c2fb4f264f950c816?el=desc) (3d14164) will **decrease** coverage by `3.78%`.
> The diff coverage is `0.00%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
==========================================
- Coverage 42.30% 38.52% -3.79%
==========================================
Files 31 31
Lines 1924 2113 +189
==========================================
Hits 814 814
- Misses 1000 1189 +189
Partials 110 110
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `23.03% <0.00%> (-19.89%)` | :arrow_down: |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [3d14164...17b356c](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] nic-chen commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
nic-chen commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-764209076
> @nic-chen Hi, the CI of your PR has not been passed. You need to rebase the master branch, and the get list method of store needs to add the `context` parameter
thanks for remind.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] imjoey commented on a change in pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
imjoey commented on a change in pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#discussion_r565160065
##########
File path: api/internal/conf/conf.go
##########
@@ -52,6 +52,7 @@ var (
UserList = make(map[string]User, 2)
AuthConf Authentication
SSLDefaultStatus = 1 //enable ssl by default
+ ImportSizeLimit = 10 * 1024 * 1024
Review comment:
Is the unit `bytes`? It would be better for clear comments.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] juzhiyuan commented on pull request #1102: Import & Export route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-751658690
Any update about this feature?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-768166641
Thanks for @nic-chen and all reviewers, pr megerd
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import & Export route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752830445
> Any update about this feature?
After communicated with @nic-chen , he will continue doing import on current pr, and @Jaycean will go on doing export route on another pr, and it is planed to be ready later next week.
cc @juzhiyuan
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-759148972
https://github.com/apache/apisix-dashboard/pull/1102/checks?check_run_id=1686825100
another unstable fe e2e test case, cc @LiteSun
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (8c6ffa9) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/9cb9aa7354d6daf231af689c80e3ca79234a0605?el=desc) (9cb9aa7) will **decrease** coverage by `21.64%`.
> The diff coverage is `29.13%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
===========================================
- Coverage 65.42% 43.77% -21.65%
===========================================
Files 43 35 -8
Lines 2655 2508 -147
===========================================
- Hits 1737 1098 -639
- Misses 713 1253 +540
+ Partials 205 157 -48
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (-81.25%)` | :arrow_down: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (-55.47%)` | :arrow_down: |
| [api/internal/utils/utils.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3V0aWxzL3V0aWxzLmdv) | `47.56% <0.00%> (-23.66%)` | :arrow_down: |
| [api/internal/handler/data\_loader/route\_import.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvZGF0YV9sb2FkZXIvcm91dGVfaW1wb3J0Lmdv) | `27.41% <27.41%> (ø)` | |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.10% <75.00%> (-10.83%)` | :arrow_down: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `81.81% <100.00%> (-4.26%)` | :arrow_down: |
| [api/internal/filter/request\_id.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9yZXF1ZXN0X2lkLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [api/internal/core/store/storehub.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmVodWIuZ28=) | `0.00% <0.00%> (-70.41%)` | :arrow_down: |
| [api/internal/filter/cors.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9jb3JzLmdv) | `0.00% <0.00%> (-66.67%)` | :arrow_down: |
| ... and [34 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [9cb9aa7...8c6ffa9](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-758287503
> before we import new route data, do we need to clean the old route first?
how about giving the choice to users? e.g: Add a param to deside whether to cover the old routes or return a error, which tells users that they already have the same routes.
BTW, I just want to make sure what is the matching strategy of the apisix when there are two or more same routes?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] nic-chen commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
nic-chen commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-762577575
> > > Hi, the two functions of import and export are closely related, so I want to discuss the name of the folder with you. I personally think that the two files are ultimately in one folder. For example, how can I change my folder to your folder name 'data loader'. I wonder if you have any good suggestions
> >
> >
> > how about we use the same folder name `data_loader` ? just rename your folder.
>
> Now I change my folder name, and there is a problem of package reference, but if I change my package to 'data_loader', I don't think the description of my function is accurate, so I'll discuss it with you. Because the folder contains import and export functions, we can change the folder to 'data_operation' Do you have any other good suggestions?
loader can load and unload stuff, I think is OK for us..
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] Jaycean commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
Jaycean commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-764194110
@nic-chen Hi, the CI of your PR has not been passed. You need to rebase the master branch, and the get list method of store needs to add the `context` parameter
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (be06fbc) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/6d7f11a14c84c4f918827ae5f24befaf02bf681f?el=desc) (6d7f11a) will **decrease** coverage by `18.22%`.
> The diff coverage is `88.23%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
===========================================
- Coverage 62.79% 44.57% -18.23%
===========================================
Files 41 32 -9
Lines 2352 1972 -380
===========================================
- Hits 1477 879 -598
- Misses 700 981 +281
+ Partials 175 112 -63
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (-62.50%)` | :arrow_down: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (-55.47%)` | :arrow_down: |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `46.52% <66.66%> (-20.87%)` | :arrow_down: |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.10% <75.00%> (-10.83%)` | :arrow_down: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `80.83% <100.00%> (-7.29%)` | :arrow_down: |
| [api/internal/filter/request\_id.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9yZXF1ZXN0X2lkLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [api/internal/core/store/storehub.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmVodWIuZ28=) | `0.00% <0.00%> (-70.41%)` | :arrow_down: |
| [api/internal/filter/cors.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9jb3JzLmdv) | `0.00% <0.00%> (-66.67%)` | :arrow_down: |
| ... and [26 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [6d7f11a...be06fbc](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (a47ef38) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/6d7f11a14c84c4f918827ae5f24befaf02bf681f?el=desc) (6d7f11a) will **decrease** coverage by `18.22%`.
> The diff coverage is `88.23%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
===========================================
- Coverage 62.79% 44.57% -18.23%
===========================================
Files 41 32 -9
Lines 2352 1972 -380
===========================================
- Hits 1477 879 -598
- Misses 700 981 +281
+ Partials 175 112 -63
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (-62.50%)` | :arrow_down: |
| [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <ø> (-55.47%)` | :arrow_down: |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `46.52% <66.66%> (-20.87%)` | :arrow_down: |
| [api/internal/core/store/validate.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvdmFsaWRhdGUuZ28=) | `58.10% <75.00%> (-10.83%)` | :arrow_down: |
| [api/internal/core/store/store.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmUuZ28=) | `80.83% <100.00%> (-7.29%)` | :arrow_down: |
| [api/internal/filter/request\_id.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9yZXF1ZXN0X2lkLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [api/internal/core/store/storehub.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmVodWIuZ28=) | `0.00% <0.00%> (-70.41%)` | :arrow_down: |
| [api/internal/filter/cors.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9jb3JzLmdv) | `0.00% <0.00%> (-66.67%)` | :arrow_down: |
| ... and [26 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree-more) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [6d7f11a...a47ef38](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] juzhiyuan commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-764448583
> Do we need to add **test cases** about
>
> 1. import a error file
> 2. a file includes two or more APIs
Yep
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] membphis commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
membphis commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-758014961
before we import new route data, do we need to clean the old route first?
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] Jaycean commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
Jaycean commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-762579150
> > > > Hi, the two functions of import and export are closely related, so I want to discuss the name of the folder with you. I personally think that the two files are ultimately in one folder. For example, how can I change my folder to your folder name 'data loader'. I wonder if you have any good suggestions
> > >
> > >
> > > how about we use the same folder name `data_loader` ? just rename your folder.
> >
> >
> > Now I change my folder name, and there is a problem of package reference, but if I change my package to 'data_loader', I don't think the description of my function is accurate, so I'll discuss it with you. Because the folder contains import and export functions, we can change the folder to 'data_operation' Do you have any other good suggestions?
>
> loader can load and unload stuff, I think is OK for us..
OK, no problem.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] Jaycean commented on pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
Jaycean commented on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-760622249
> > > > before we import new route data, do we need to clean the old route first?
> > >
> > >
> > > I think that the original data should not be modified, and the status of the imported route should be `offline`.
> >
> >
> > agree with the `offline` status, and do we consider letting the user choose whether to override it or not? that may be more flexible
>
> I feel that there is a certain risk in overriding, and I don't think it is necessary to do so. Waiting for the opinions of others. .
I think the front end can directly ask the user whether the same data is covered when importing. If it is covered, the front end will pass a parameter to the back end, such as `is_covered` (of course, the default is false).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1102: feat: import & Export route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102#issuecomment-752030848
# [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=h1) Report
> Merging [#1102](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=desc) (e04fc9a) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/c0241ee83450e2f26695aed12dbb17d6f9da59d3?el=desc) (c0241ee) will **decrease** coverage by `3.78%`.
> The diff coverage is `0.00%`.
[![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree)
```diff
@@ Coverage Diff @@
## master #1102 +/- ##
==========================================
- Coverage 42.38% 38.60% -3.79%
==========================================
Files 31 31
Lines 1930 2119 +189
==========================================
Hits 818 818
- Misses 1001 1190 +189
Partials 111 111
```
| [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <ø> (ø)` | |
| [api/internal/handler/route/route.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1102/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvcm91dGUvcm91dGUuZ28=) | `23.03% <0.00%> (-19.89%)` | :arrow_down: |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=footer). Last update [c0241ee...e04fc9a](https://codecov.io/gh/apache/apisix-dashboard/pull/1102?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix-dashboard] liuxiran merged pull request #1102: feat: import route from OpenAPI Specification3.0
Posted by GitBox <gi...@apache.org>.
liuxiran merged pull request #1102:
URL: https://github.com/apache/apisix-dashboard/pull/1102
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org