Skip to content

Add 'endpoints' to Gateway to support multiple vhosts#2139

Open
senthuran16 wants to merge 1 commit into
wso2:mainfrom
senthuran16:multiple-vhost
Open

Add 'endpoints' to Gateway to support multiple vhosts#2139
senthuran16 wants to merge 1 commit into
wso2:mainfrom
senthuran16:multiple-vhost

Conversation

@senthuran16

Copy link
Copy Markdown
Member
- DO NOT MERGE. We have to have a discussion and find out if we are going to get rid of the vhost column, along with a migration. Until that's figured out, we shouldn't merge this

Purpose

Multiple vhost support is needed for gateways like the Event Gateway, where there will be multiple ports. Event Gateway currently has the following ports:

  • WebSub APIs: https on 8443
  • WebBroker APIs: wss on 8444 for WebSocket receiver
  • In future, we will add different types of receivers for WebBroker APIs, such as SSE.

Resolves #2128.

Goals

Along with the existing vhost field, we will add an optional endpoints array.

curl --location 'https://localhost:9243/api/v1/gateways' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ****' \
--data '{
  "name": "event-gateway-01",
  "displayName": "Event Gateway 01",
  "vhost": "mg.wso2.com",
  "functionalityType": "regular",
  "description": "Production Event gateway for handling API traffic",
  "endpoints": [
    {
      "host": "api.example.com",
      "protocol": "https",
      "port": 8443
    },
    {
      "host": "events.example.com",
      "protocol": "wss",
      "port": 8444
    }
  ],
  "isCritical": true,
  "properties": {
    "region": "us-west",
    "tier": "premium"
  },
  "version": "1.0"
}'

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary

This PR adds support for multiple endpoints (vhosts) to gateways, enabling them to operate across multiple host/protocol/port combinations. This resolves the need for Event Gateway to support services on different ports and protocols simultaneously (e.g., HTTPS on 8443 for WebSub and WSS on 8444 for WebBroker).

Changes

API Layer:

  • Added GatewayEndpoint and GatewayEndpointProtocol types to represent individual gateway endpoints with host, protocol, and port
  • Extended CreateGatewayRequest, GatewayResponse, RESTAPIGatewayResponse, and UpdateGatewayRequest to include an optional endpoints array field
  • Updated OpenAPI schema to define the GatewayEndpoint structure and validate endpoints with hostname regex, protocol constraints (https/wss), and port ranges

Data Model:

  • Added GatewayEndpoint model to represent endpoint configuration
  • Extended Gateway and APIGatewayWithDetails models to include the Endpoints slice alongside existing fields

Database:

  • Added endpoints column to the gateways table across all supported databases (PostgreSQL as JSONB, SQLite and generic SQL as TEXT) with a default value of an empty array

Service Layer:

  • Updated RegisterGateway method to accept and persist endpoints when provided
  • Updated UpdateGateway method to accept and persist endpoint changes
  • Implemented JSON serialization/deserialization for storing and retrieving endpoints from the database

Handler & Repository:

  • Updated gateway handler to convert incoming endpoint requests and pass them to the service layer
  • Updated gateway repository to handle endpoint persistence and retrieval, including JSON marshaling/unmarshaling

Tests:

  • Added comprehensive test coverage for endpoint registration including single and multiple endpoint scenarios
  • Updated existing property tests to reflect the new method signatures

The existing vhost field remains in place for backward compatibility pending design discussion on future deprecation and migration strategy.

Walkthrough

This pull request introduces gateway endpoint support by adding a new GatewayEndpoint data structure (host, port, protocol) across the entire application stack. The API contract defines endpoints with validation for HTTPS and WSS protocols and bounded port ranges. Database schemas across PostgreSQL, SQLite, and generic SQL are updated with a new endpoints JSONB/TEXT column defaulting to an empty array. Internal models extend gateway types to include an Endpoints collection. The repository layer handles JSON serialization and deserialization for all CRUD operations. The service layer accepts endpoints during gateway registration and updates, converting them to API response format. HTTP handlers map incoming request endpoints to service calls. Comprehensive tests validate endpoint registration with zero, single, and multiple endpoint configurations, and existing tests are updated for the new method signatures.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Handler as GatewayHandler
    participant Service as GatewayService
    participant Repository as GatewayRepo
    participant Database
    
    Client->>Handler: CreateGateway(endpoints: [{host, protocol, port}])
    Handler->>Handler: Convert api.Endpoint[] to model.Endpoint[]
    Handler->>Service: RegisterGateway(..., endpoints)
    Service->>Service: Assign endpoints to model.Gateway
    Service->>Repository: Create(gateway with endpoints)
    Repository->>Repository: Serialize endpoints to JSON
    Repository->>Database: INSERT gateways(endpoints, ...)
    Database-->>Repository: Success
    Repository-->>Service: gateway (loaded with endpoints)
    Service->>Service: Convert model.Endpoint[] to api.Endpoint[]
    Service-->>Handler: api.GatewayResponse(endpoints: [...])
    Handler-->>Client: JSON response with endpoints array
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description lacks several required template sections including Goals, Approach, User stories, Documentation, Automation tests, Security checks, Samples, and Test environment. Complete the PR description using the repository template by adding missing sections such as Goals, Approach, User stories, Documentation, Automation tests with coverage details, Security checks, Samples, Related PRs, and Test environment.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding an endpoints field to support multiple vhosts for gateways.
Linked Issues check ✅ Passed Changes implement the core coding requirements from issue #2128: updated OpenAPI schema, database schema, models, handlers, services, repositories, and tests to support multiple gateway endpoints.
Out of Scope Changes check ✅ Passed All changes are directly related to adding endpoints support to the Gateway model as specified in the linked issue; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@platform-api/src/api/generated.go`:
- Around line 462-463: The generated constants Http and Https on type
WebSubAPITransport break source compatibility; restore deprecated aliases named
WebSubAPITransportHttp and WebSubAPITransportHttps by adding a non-generated
file that declares var (or const) WebSubAPITransportHttp =
WebSubAPITransport("http") and WebSubAPITransportHttps =
WebSubAPITransport("https") (or assigns to the existing Http/Https values) with
a deprecation comment, so callers referencing
WebSubAPITransportHttp/WebSubAPITransportHttps continue to compile; reference
the existing WebSubAPITransport type and the generated Http and Https symbols
when locating where to add the aliases.

In `@platform-api/src/internal/service/gateway.go`:
- Around line 490-493: Validate the incoming endpoints slice before
assigning/persisting: in the gateway create/update service methods (the function
taking parameters including orgID, name, displayName, vhost, functionalityType,
properties, endpoints and calling s.validateGatewayInput), iterate over each
model.GatewayEndpoint and enforce required rules (e.g., non-empty Host, Port
within 1–65535, and any other protocol-specific fields you expect), returning a
descriptive error if any endpoint is invalid; perform this validation prior to
any assignment or DB call and apply the same checks in the corresponding update
path (the other handler mentioned around lines 647–649) so invalid endpoint
entries are rejected at the service boundary.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3b7fb5a8-cbf4-4047-a443-19e36f64d006

📥 Commits

Reviewing files that changed from the base of the PR and between e2f9459 and ebbec52.

📒 Files selected for processing (11)
  • platform-api/src/api/generated.go
  • platform-api/src/internal/database/schema.postgres.sql
  • platform-api/src/internal/database/schema.sql
  • platform-api/src/internal/database/schema.sqlite.sql
  • platform-api/src/internal/handler/gateway.go
  • platform-api/src/internal/model/gateway.go
  • platform-api/src/internal/repository/gateway.go
  • platform-api/src/internal/service/gateway.go
  • platform-api/src/internal/service/gateway_endpoints_test.go
  • platform-api/src/internal/service/gateway_properties_test.go
  • platform-api/src/resources/openapi.yaml

Comment on lines +462 to +463
Http WebSubAPITransport = "http"
Https WebSubAPITransport = "https"

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve backward compatibility for WebSubAPITransport exported constants.

Line 462 and Line 463 expose Http/Https, which is a source-compatible break for callers using WebSubAPITransportHttp/WebSubAPITransportHttps. Please add deprecated aliases (in a non-generated file) or restore enum var names in the OpenAPI generation config to avoid breaking existing consumers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@platform-api/src/api/generated.go` around lines 462 - 463, The generated
constants Http and Https on type WebSubAPITransport break source compatibility;
restore deprecated aliases named WebSubAPITransportHttp and
WebSubAPITransportHttps by adding a non-generated file that declares var (or
const) WebSubAPITransportHttp = WebSubAPITransport("http") and
WebSubAPITransportHttps = WebSubAPITransport("https") (or assigns to the
existing Http/Https values) with a deprecation comment, so callers referencing
WebSubAPITransportHttp/WebSubAPITransportHttps continue to compile; reference
the existing WebSubAPITransport type and the generated Http and Https symbols
when locating where to add the aliases.

Comment on lines +490 to 493
functionalityType, version string, properties map[string]interface{}, endpoints []model.GatewayEndpoint) (*api.GatewayResponse, error) {
// 1. Validate inputs
if err := s.validateGatewayInput(orgID, name, displayName, vhost, functionalityType); err != nil {
return nil, err

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate endpoint entries before storing them.

endpoints are accepted in create/update flows but are not validated at the service boundary. Add checks (e.g., non-empty host and valid port range) before assigning/persisting to keep stored gateway endpoint data consistent.

Proposed fix
+func validateGatewayEndpoints(endpoints []model.GatewayEndpoint) error {
+	for i, ep := range endpoints {
+		if strings.TrimSpace(ep.Host) == "" {
+			return fmt.Errorf("endpoint[%d].host is required", i)
+		}
+		if ep.Port < 1 || ep.Port > 65535 {
+			return fmt.Errorf("endpoint[%d].port must be between 1 and 65535", i)
+		}
+	}
+	return nil
+}
+
 func (s *GatewayService) RegisterGateway(orgID, name, displayName, description, vhost string, isCritical bool,
 	functionalityType, version string, properties map[string]interface{}, endpoints []model.GatewayEndpoint) (*api.GatewayResponse, error) {
 	// 1. Validate inputs
 	if err := s.validateGatewayInput(orgID, name, displayName, vhost, functionalityType); err != nil {
 		return nil, err
 	}
+	if err := validateGatewayEndpoints(endpoints); err != nil {
+		return nil, err
+	}
@@
 	if endpoints != nil {
+		if err := validateGatewayEndpoints(*endpoints); err != nil {
+			return nil, err
+		}
 		gateway.Endpoints = *endpoints
 	}

Also applies to: 647-649

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@platform-api/src/internal/service/gateway.go` around lines 490 - 493,
Validate the incoming endpoints slice before assigning/persisting: in the
gateway create/update service methods (the function taking parameters including
orgID, name, displayName, vhost, functionalityType, properties, endpoints and
calling s.validateGatewayInput), iterate over each model.GatewayEndpoint and
enforce required rules (e.g., non-empty Host, Port within 1–65535, and any other
protocol-specific fields you expect), returning a descriptive error if any
endpoint is invalid; perform this validation prior to any assignment or DB call
and apply the same checks in the corresponding update path (the other handler
mentioned around lines 647–649) so invalid endpoint entries are rejected at the
service boundary.

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.

[Task]: Add multiple vhost support for Event GW

1 participant