-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding OpenAPI Export and Rib to OpenAPI Converter #1206
Open
zelosleone
wants to merge
46
commits into
golemcloud:main
Choose a base branch
from
zelosleone:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 9 commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
0abe608
Adding OpenAPI Export and Rib to OpenAPI Converter
zelosleone 3156eaf
Test2 (#2)
zelosleone ac845fc
Delete tests/client_generation_tests directory
zelosleone b502f26
Delete golem-worker-service-base/README.md
zelosleone bef7eee
Minor Code Updates, More on the way
zelosleone 06aa0ee
Update rib_converter.rs
zelosleone c1e6929
Update openapi_swagger_tests.rs
zelosleone 586b7b1
Update openapi_swagger_tests.rs
zelosleone aea1b7b
Deneme (#5)
zelosleone 8453f7d
Enhance testing framework and OpenAPI integration
zelosleone 703c651
Delete .github/workflows/openapi-tests.yaml
zelosleone ca1de38
Update Cargo.toml
zelosleone 2ee4da7
Merge branch 'main' of https://github.com/zelosleone/golem
zelosleone d872a65
Update Cargo.toml
zelosleone c25cfa7
Merge branch 'main' of https://github.com/zelosleone/golem
zelosleone ece2a76
Refactor and enhance test suite for OpenAPI and JSON schema validatio…
zelosleone e4af0b6
Literally rented Hosting to test this
zelosleone e30da1e
.
zelosleone 46d9777
Merge branch 'golemcloud:main' into main
zelosleone 9407d2c
Merge branch 'golemcloud:main' into main
zelosleone be15e1d
Testing State, Gonna post more updated so its not finished yet
zelosleone 1f85ada
16 End Points Worker Test Finally
zelosleone 1a82213
Fix complex_wit_type_validation_tests to run with cargo test
zelosleone 0c98323
Enhance API Definition and Swagger UI Functionality
zelosleone 89573aa
Merge branch 'golemcloud:main' into main
zelosleone cdd123b
Enhance API Definition and Swagger UI Functionality
zelosleone 31468e8
Copyright 2024-2025 Golem Cloud (#1215)
vigoo d767d97
Update api-response dependency to version 0.16.3 in Cargo.toml
zelosleone c86d532
.
zelosleone c74d9b1
Merge branch 'main' of https://github.com/zelosleone/golem
zelosleone 02665f3
.
zelosleone bb55ef2
Revert "."
zelosleone 7a291c2
Delete
zelosleone 4f872ab
Delete Cargo.lock
zelosleone b82dbb8
Implement Swagger UI Binding and Enhance API Functionality
zelosleone c45ad48
Fixed CWE-754
zelosleone 92ab25c
Merge branch 'golemcloud:main' into main
zelosleone 990b288
Enhance Swagger UI Configuration on Golem-cli
zelosleone 7f005ad
Updated Test Files After the whole deal of dynamic_linking update
zelosleone ce49dff
Test Files fixing testing
zelosleone e9dbd93
Had to Fix Tests and Command Line Generator too
zelosleone f6e68f0
More updated to be more compatible with the NEW PR that is merged wit…
zelosleone 2a3b342
Refactor API Definition Commands and Enhance Swagger UI Integration (…
zelosleone f02dd3e
Enhance Test API and Update Worker Service Metadata
zelosleone 58c0282
Enhance CORS Preflight Tests in API Gateway
zelosleone 686f12e
Merge branch 'golemcloud:main' into main
zelosleone File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
name: OpenAPI Tests | ||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
paths: | ||
- 'golem-worker-service-base/tests/openapi_swagger_tests.rs' | ||
- '**/openapi/**' | ||
- '**/swagger/**' | ||
|
||
jobs: | ||
openapi-tests: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 1 | ||
submodules: recursive | ||
|
||
- name: Fetch tag | ||
run: git fetch origin --deepen=1 | ||
|
||
- name: Setup Rust | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: stable | ||
override: true | ||
components: rustfmt, clippy | ||
|
||
- uses: Swatinem/rust-cache@v2 | ||
with: | ||
shared-key: openapi-tests | ||
cache-all-crates: true | ||
|
||
- name: Install Protoc | ||
uses: arduino/setup-protoc@v3 | ||
with: | ||
repo-token: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- uses: davidB/rust-cargo-make@v1 | ||
|
||
- name: Build all targets | ||
run: cargo make --profile ci build | ||
|
||
- name: Build tests | ||
run: cargo test --package golem-worker-service-base --test openapi_swagger_tests --no-run | ||
|
||
- name: Create output directory | ||
run: mkdir -p openapi_exports | ||
|
||
- name: Run OpenAPI tests | ||
run: | | ||
RUST_LOG=info cargo test --package golem-worker-service-base --test openapi_swagger_tests -- --nocapture | ||
env: | ||
RUST_BACKTRACE: 1 | ||
CARGO_TERM_COLOR: always | ||
|
||
- name: Upload OpenAPI artifacts | ||
if: always() | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: openapi-exports | ||
path: openapi_exports/ | ||
|
||
- name: Publish Test Report | ||
uses: mikepenz/action-junit-report@v4 | ||
if: success() || failure() | ||
with: | ||
report_paths: '**/target/report-*.xml' | ||
detailed_summary: true | ||
include_passed: true | ||
|
||
permissions: | ||
contents: read | ||
checks: write | ||
pull-requests: write |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
golem-worker-service-base/src/gateway_api_definition/http/handlers.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use poem::{ | ||
web::{Path, Query, Data}, | ||
Result, handler, | ||
}; | ||
use utoipa::openapi::OpenApi; | ||
use crate::gateway_api_definition::http::{ | ||
openapi_export::OpenApiFormat, | ||
openapi_converter::OpenApiConverter, | ||
}; | ||
use poem::web::Json; | ||
|
||
pub struct OpenApiHandler { | ||
converter: OpenApiConverter, | ||
} | ||
|
||
impl OpenApiHandler { | ||
pub fn new() -> Self { | ||
Self { | ||
converter: OpenApiConverter::new(), | ||
} | ||
} | ||
} | ||
|
||
#[handler] | ||
pub async fn export_openapi( | ||
Data(handler): Data<&OpenApiHandler>, | ||
Path((id, version)): Path<(String, String)>, | ||
Query(format): Query<OpenApiFormat>, | ||
Json(openapi): Json<OpenApi>, | ||
) -> Result<String> { | ||
let content = handler.converter.exporter.export_openapi(&id, &version, openapi, &format); | ||
Ok(content) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
175 changes: 175 additions & 0 deletions
175
golem-worker-service-base/src/gateway_api_definition/http/openapi_converter.rs
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing as openapi export, utoipa is used for majority of the cases. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
// Copyright 2024 Golem Cloud | ||
// | ||
// Licensed 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. | ||
|
||
use std::sync::Arc; | ||
use utoipa::openapi::OpenApi; | ||
use crate::gateway_api_definition::http::openapi_export::OpenApiExporter; | ||
|
||
pub struct OpenApiConverter { | ||
pub exporter: Arc<OpenApiExporter>, | ||
} | ||
|
||
impl OpenApiConverter { | ||
pub fn new() -> Self { | ||
Self { | ||
exporter: Arc::new(OpenApiExporter), | ||
} | ||
} | ||
|
||
pub fn merge_openapi(mut base: OpenApi, other: OpenApi) -> OpenApi { | ||
// Merge paths | ||
base.paths.paths.extend(other.paths.paths); | ||
|
||
// Merge components | ||
match (&mut base.components, other.components.as_ref()) { | ||
(Some(base_components), Some(other_components)) => { | ||
// Merge schemas | ||
base_components.schemas.extend(other_components.schemas.clone()); | ||
// Merge responses | ||
base_components.responses.extend(other_components.responses.clone()); | ||
// Merge security schemes | ||
base_components.security_schemes.extend(other_components.security_schemes.clone()); | ||
} | ||
_ => base.components = other.components, | ||
} | ||
|
||
// Merge security requirements | ||
match (&mut base.security, other.security.as_ref()) { | ||
(Some(base_security), Some(other_security)) => { | ||
base_security.extend(other_security.clone()); | ||
} | ||
_ => base.security = other.security, | ||
} | ||
|
||
// Merge tags | ||
match (&mut base.tags, other.tags.as_ref()) { | ||
(Some(base_tags), Some(other_tags)) => { | ||
base_tags.extend(other_tags.clone()); | ||
} | ||
_ => base.tags = other.tags, | ||
} | ||
|
||
// Merge servers | ||
match (&mut base.servers, other.servers.as_ref()) { | ||
(Some(base_servers), Some(other_servers)) => { | ||
base_servers.extend(other_servers.clone()); | ||
} | ||
_ => base.servers = other.servers, | ||
} | ||
|
||
base | ||
} | ||
} | ||
|
||
impl Default for OpenApiConverter { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::OpenApiConverter; | ||
use utoipa::openapi::{ | ||
OpenApi, | ||
Server, | ||
Tag, | ||
}; | ||
|
||
#[test] | ||
fn test_openapi_converter() { | ||
let _converter = OpenApiConverter::new(); | ||
|
||
// Create base OpenAPI | ||
let mut base = OpenApi::new(Default::default(), ()); | ||
let get_op = OperationBuilder::new().summary(Some("Base operation".to_string())).build(); | ||
let mut path_item = PathItem::new(HttpMethod::Get, ()); | ||
path_item.get = Some(get_op); | ||
base.paths.paths.insert("/base".to_string(), path_item); | ||
let mut components = Components::new(); | ||
components.schemas.insert("BaseSchema".to_string(), Schema::Object(Object::new()).into()); | ||
base.components = Some(components); | ||
base.security = Some(vec![SecurityRequirement::new("BaseAuth", ())]); | ||
base.tags = Some(vec![Tag::new("base")]); | ||
base.servers = Some(vec![Server::new("/base")]); | ||
|
||
// Create other OpenAPI with duplicate path | ||
let mut other = OpenApi::new(Default::default(), ()); | ||
let post_op = OperationBuilder::new().summary(Some("Other operation".to_string())).build(); | ||
let mut path_item = PathItem::new(HttpMethod::Get, ()); | ||
path_item.post = Some(post_op); | ||
other.paths.paths.insert("/base".to_string(), path_item); | ||
let mut components = Components::new(); | ||
components.schemas.insert("OtherSchema".to_string(), Schema::Object(Object::new()).into()); | ||
other.components = Some(components); | ||
other.security = Some(vec![SecurityRequirement::new("OtherAuth", ())]); | ||
other.tags = Some(vec![Tag::new("other")]); | ||
other.servers = Some(vec![Server::new("/other")]); | ||
|
||
// Test merging with duplicates | ||
let merged = OpenApiConverter::merge_openapi(base.clone(), other.clone()); | ||
|
||
// Verify paths merged and duplicates handled | ||
assert!(merged.paths.paths.contains_key("/base")); | ||
let base_path = merged.paths.paths.get("/base").unwrap(); | ||
assert!(base_path.get.is_some(), "GET operation should be preserved"); | ||
assert!(base_path.post.is_some(), "POST operation should be added"); | ||
|
||
// Verify components merged | ||
let components = merged.components.unwrap(); | ||
assert!(components.schemas.contains_key("BaseSchema")); | ||
assert!(components.schemas.contains_key("OtherSchema")); | ||
|
||
// Test empty component merging | ||
let mut empty_base = OpenApi::new(Default::default(), ()); | ||
empty_base.components = None; | ||
let merged = OpenApiConverter::merge_openapi(empty_base, other); | ||
assert!(merged.components.is_some()); | ||
let components = merged.components.unwrap(); | ||
assert!(components.schemas.contains_key("OtherSchema")); | ||
} | ||
|
||
#[test] | ||
fn test_openapi_converter_new() { | ||
let converter = OpenApiConverter::new(); | ||
assert_eq!(Arc::strong_count(&converter.exporter), 1); | ||
} | ||
|
||
#[test] | ||
fn test_merge_openapi_with_empty_fields() { | ||
// Test merging when base has empty optional fields | ||
let mut base = OpenApi::new(Default::default(), ()); | ||
base.security = None; | ||
base.tags = None; | ||
base.servers = None; | ||
base.components = None; | ||
|
||
// Create other OpenAPI with all fields populated | ||
let mut other = OpenApi::new(Default::default(), ()); | ||
other.security = Some(vec![SecurityRequirement::new("OtherAuth", ())]); | ||
other.tags = Some(vec![Tag::new("other")]); | ||
other.servers = Some(vec![Server::new("/other")]); | ||
let mut components = Components::new(); | ||
components.schemas.insert("OtherSchema".to_string(), Schema::Object(Object::new()).into()); | ||
other.components = Some(components); | ||
|
||
let merged = OpenApiConverter::merge_openapi(base, other.clone()); | ||
|
||
// Verify all fields were properly merged | ||
assert_eq!(merged.security, other.security); | ||
assert_eq!(merged.tags, other.tags); | ||
assert_eq!(merged.servers, other.servers); | ||
assert_eq!(merged.components, other.components); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I first tried harness=false, not noticing my tests would work better with harness=true, fixed that.