Skip to content

add swagger2.0#92

Merged
iFurySt merged 3 commits into
AmoyLab:mainfrom
KamToHung:fix-48
May 17, 2025
Merged

add swagger2.0#92
iFurySt merged 3 commits into
AmoyLab:mainfrom
KamToHung:fix-48

Conversation

@KamToHung
Copy link
Copy Markdown
Contributor

@KamToHung KamToHung commented May 16, 2025

Summary by Sourcery

Introduce full Swagger 2.0 support by adding a converter, handler, API route, tests, dependency updates, and associated i18n messages

New Features:

  • Add Swagger 2.0 converter for transforming Swagger specifications into MCP configurations
  • Introduce Swagger import handler and POST /swagger/import endpoint

Enhancements:

  • Relax existing OpenAPI converter tests by commenting out outdated assertions

Build:

  • Add Swagger and related Go OpenAPI dependencies to go.mod

Tests:

  • Add unit tests for Swagger converter supporting JSON and YAML inputs

Chores:

  • Add i18n constants for Swagger import, export, and validation success messages

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 16, 2025

Reviewer's Guide

This pull request adds full Swagger 2.0 import support by introducing a new Converter in pkg/swagger (with JSON/YAML wrappers and comprehensive unit tests), wiring up a Swagger import HTTP handler and route in the API server, defining corresponding i18n messages, and updating module dependencies. Key OpenAPI tests are also relaxed by commenting out redundant assertions.

Sequence Diagram for Swagger 2.0 Import Process

sequenceDiagram
    actor User
    participant GinRouter as Gin Router
    participant SwaggerHandler as handler.Swagger
    participant SwaggerConverter as swagger.Converter
    participant Store as storage.Store
    participant Notifier as notifier.Notifier

    User->>+GinRouter: POST /swagger/import (multipart/form-data with file)
    GinRouter->>+SwaggerHandler: HandleImport(context)
    SwaggerHandler->>SwaggerHandler: Get file from request
    SwaggerHandler->>SwaggerConverter: NewConverter()
    SwaggerHandler->>+SwaggerConverter: Convert(fileContent)
    SwaggerConverter->>SwaggerConverter: Parse Swagger spec (loads.Analyzed)
    SwaggerConverter->>SwaggerConverter: Transform to MCPConfig
    SwaggerConverter-->>-SwaggerHandler: *config.MCPConfig
    SwaggerHandler->>+Store: Create(context, mcpConfig)
    Store-->>-SwaggerHandler: (success/error)
    SwaggerHandler->>+Notifier: NotifyUpdate(context, mcpConfig)
    Notifier-->>-SwaggerHandler: (success/error)
    SwaggerHandler-->>-GinRouter: HTTP Response (success/error)
    GinRouter-->>-User: HTTP Response
Loading

Class Diagram for Swagger Import Components

classDiagram
    namespace handler {
        class Swagger {
            -db database.Database
            -store storage.Store
            -notifier notifier.Notifier
            -logger *zap.Logger
            +NewSwagger(db, store, ntf, logger) *Swagger
            +HandleImport(c *gin.Context)
        }
    }

    namespace swagger {
        class Converter {
            +NewConverter() *Converter
            +Convert(specData []byte) (*config.MCPConfig, error)
            +ConvertFromJSON(jsonData []byte) (*config.MCPConfig, error)
            +ConvertFromYAML(yamlData []byte) (*config.MCPConfig, error)
        }
    }

    namespace config {
        class MCPConfig {
            +Name string
            +Tenant string
            +CreatedAt time.Time
            +UpdatedAt time.Time
            +Routers []RouterConfig
            +Servers []ServerConfig
            +Tools []ToolConfig
        }
        class ServerConfig {
            +Name string
            +Description string
            +Config map[string]string
            +AllowedTools []string
        }
        class RouterConfig {
            +Server string
            +Prefix string
            +CORS *CORSConfig
        }
        class ToolConfig {
            +Name string
            +Description string
            +Method string
            +Endpoint string
            +Headers map[string]string
            +Args []ArgConfig
            +RequestBody string
            +ResponseBody string
        }
        class ArgConfig {
            +Name string
            +Position string
            +Required bool
            +Type string
            +Description string
            +Default string
        }
        class CORSConfig {
            +AllowOrigins []string
            +AllowMethods []string
            +AllowHeaders []string
            +ExposeHeaders []string
            +AllowCredentials bool
        }
    }

    handler.Swagger ..> swagger.Converter : uses
    handler.Swagger ..> storage.Store : uses
    handler.Swagger ..> notifier.Notifier : uses
    handler.Swagger ..> database.Database : uses
    swagger.Converter ..> config.MCPConfig : creates
    config.MCPConfig *-- "0..*" config.ServerConfig : contains
    config.MCPConfig *-- "0..*" config.RouterConfig : contains
    config.MCPConfig *-- "0..*" config.ToolConfig : contains
    config.RouterConfig *-- "1" config.CORSConfig : contains
    config.ToolConfig *-- "0..*" config.ArgConfig : contains
Loading

File-Level Changes

Change Details Files
Introduce Swagger 2.0 to MCPConfig conversion
  • Implement Converter.Convert using go-openapi/loads to parse spec
  • Generate MCPConfig fields: Name, Routers, Servers, Tools, handling paths/parameters
  • Provide JSON/YAML wrappers (ConvertFromJSON/ConvertFromYAML)
  • Add random prefix and CORS defaults on Routers
  • Unit tests covering GET, path params, JSON/YAML input
pkg/swagger/converter.go
pkg/swagger/converter_test.go
Add Swagger import handler in API server
  • Handle multipart file upload and read content
  • Invoke swagger.NewConverter and convert spec
  • Persist MCP configuration via storage.Store
  • Notify gateway and return Created response with config
internal/apiserver/handler/swagger.go
Register Swagger import route
  • Instantiate swaggerHandler in initRouter
  • Add protected POST endpoint at /swagger/import
cmd/apiserver/main.go
Define Swagger-specific i18n constants
  • Add SuccessSwaggerImported, SuccessSwaggerExported, SuccessSwaggerValidated
internal/i18n/const.go
Include Swagger dependencies in module
  • Add go-openapi/loads and go-openapi/spec to go.mod
  • Introduce indirect dependencies (analysis, errors, strfmt, etc.)
go.mod
go.sum
Relax OpenAPI converter test assertions
  • Comment out strict Name, Prefix, Server assertions in TestConverter_Convert
pkg/openapi/converter_test.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @KamToHung - I've reviewed your changes - here's some feedback:

  • The huge Convert method could be split into smaller helper functions (e.g. building server config, router config, and tools) to improve readability and maintainability.
  • The use of lol.RandomString for name/route prefixes introduces unpredictability—consider making prefixes deterministic or configurable (and replacing the lol dependency with a small internal utility).
  • There are multiple commented‐out assertions in the existing converter tests—either restore those checks or remove them to keep the test suite clear and up to date.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Testing: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread pkg/swagger/converter.go
// Convert converts Swagger 2.0 specification to MCP configuration
func (c *Converter) Convert(specData []byte) (*config.MCPConfig, error) {
// Parse Swagger specification
doc, err := loads.Analyzed(specData, "")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Incorrect use of loads.Analyzed for raw bytes

loads.Analyzed requires a *loads.Document, not raw []byte. First call loads.JSONSpec, loads.YAMLSpec, or loads.SpecFromData to get a Document, then pass it to loads.Analyzed.

Comment thread pkg/swagger/converter.go

swaggerSpec := doc.Spec()

rs := lol.RandomString(4)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Use a stronger unique ID generator

A 4-character random string risks collisions on large imports. Use a stronger generator like ULID or UUID (e.g., oklog/ulid or google/uuid) for non-colliding IDs.

@KamToHung
Copy link
Copy Markdown
Contributor Author

PTAL

@iFurySt
Copy link
Copy Markdown
Member

iFurySt commented May 17, 2025

Awesome! LGTM! Thanks!

@iFurySt iFurySt merged commit 7775dd0 into AmoyLab:main May 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants