Skip to content

Commit

Permalink
[Rust Server] Sort operations so that the ones with fewest params com…
Browse files Browse the repository at this point in the history
…e first (#19368)

* [Rust Server] Sort operations so that the ones with fewest params come first

This resolves things correctly per
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#pathsObject
- "When matching URLs, concrete (non-templated) paths would be matched
before their templated counterparts."

* Update samples

* [Rust Server] Fix tabs vs spaces

---------

Co-authored-by: Rob Day <Robert.Day@metaswitch.com>
  • Loading branch information
richardwhiuk and rkday-pro committed Aug 18, 2024
1 parent fd62e38 commit df2b421
Show file tree
Hide file tree
Showing 18 changed files with 1,658 additions and 1,648 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import joptsimple.internal.Strings;
import lombok.Setter;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*;
Expand Down Expand Up @@ -803,6 +804,15 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
postProcessOperationWithModels(op, allModels);
}

operationList.sort((one, another) -> {
int params_compare = ObjectUtils.compare(one.pathParams.size(), another.pathParams.size());
if (params_compare == 0) {
return ObjectUtils.compare(one.operationId, another.operationId);
} else {
return params_compare;
}
});

return objs;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ Method | HTTP request | Description
[****](docs/default_api.md#) | **GET** /any-of |
[****](docs/default_api.md#) | **POST** /callback-with-header |
[****](docs/default_api.md#) | **GET** /complex-query-param |
[****](docs/default_api.md#) | **GET** /enum_in_path/{path_param} |
[****](docs/default_api.md#) | **GET** /json-complex-query-param |
[****](docs/default_api.md#) | **GET** /mandatory-request-header |
[****](docs/default_api.md#) | **GET** /merge-patch-json |
Expand All @@ -143,6 +142,7 @@ Method | HTTP request | Description
[****](docs/default_api.md#) | **PUT** /xml_other |
[****](docs/default_api.md#) | **POST** /xml | Post an array
[****](docs/default_api.md#) | **PUT** /xml |
[****](docs/default_api.md#) | **GET** /enum_in_path/{path_param} |
[**CreateRepo**](docs/repo_api.md#CreateRepo) | **POST** /repos |
[**GetRepoInfo**](docs/repo_api.md#GetRepoInfo) | **GET** /repos/{repoId} |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Method | HTTP request | Description
****](default_api.md#) | **GET** /any-of |
****](default_api.md#) | **POST** /callback-with-header |
****](default_api.md#) | **GET** /complex-query-param |
****](default_api.md#) | **GET** /enum_in_path/{path_param} |
****](default_api.md#) | **GET** /json-complex-query-param |
****](default_api.md#) | **GET** /mandatory-request-header |
****](default_api.md#) | **GET** /merge-patch-json |
Expand All @@ -28,6 +27,7 @@ Method | HTTP request | Description
****](default_api.md#) | **PUT** /xml_other |
****](default_api.md#) | **POST** /xml | Post an array
****](default_api.md#) | **PUT** /xml |
****](default_api.md#) | **GET** /enum_in_path/{path_param} |


# ****
Expand Down Expand Up @@ -119,31 +119,6 @@ No authorization required

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

# ****
> (path_param)

### Required Parameters

Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**path_param** | [****](.md)| |

### Return type

(empty response body)

### Authorization

No authorization required

### HTTP request headers

- **Content-Type**: Not defined
- **Accept**: Not defined

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

# ****
> (optional)
Expand Down Expand Up @@ -677,3 +652,28 @@ No authorization required

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

# ****
> (path_param)

### Required Parameters

Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**path_param** | [****](.md)| |

### Return type

(empty response body)

### Authorization

No authorization required

### HTTP request headers

- **Content-Type**: Not defined
- **Accept**: Not defined

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use openapi_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models,
AnyOfGetResponse,
CallbackWithHeaderPostResponse,
ComplexQueryParamGetResponse,
EnumInPathPathParamGetResponse,
JsonComplexQueryParamGetResponse,
MandatoryRequestHeaderGetResponse,
MergePatchJsonGetResponse,
Expand All @@ -30,6 +29,7 @@ use openapi_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models,
XmlOtherPutResponse,
XmlPostResponse,
XmlPutResponse,
EnumInPathPathParamGetResponse,
CreateRepoResponse,
GetRepoInfoResponse,
};
Expand Down Expand Up @@ -177,14 +177,6 @@ fn main() {
));
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
/* Disabled because there's no example.
Some("EnumInPathPathParamGet") => {
let result = rt.block_on(client.enum_in_path_path_param_get(
???
));
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
*/
Some("JsonComplexQueryParamGet") => {
let result = rt.block_on(client.json_complex_query_param_get(
Some(&Vec::new())
Expand Down Expand Up @@ -298,6 +290,14 @@ fn main() {
));
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
/* Disabled because there's no example.
Some("EnumInPathPathParamGet") => {
let result = rt.block_on(client.enum_in_path_path_param_get(
???
));
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
*/
Some("CreateRepo") => {
let result = rt.block_on(client.create_repo(
serde_json::from_str::<models::ObjectParam>(r#"{"requiredParam":true}"#).expect("Failed to parse JSON example")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ use openapi_v3::{
AnyOfGetResponse,
CallbackWithHeaderPostResponse,
ComplexQueryParamGetResponse,
EnumInPathPathParamGetResponse,
JsonComplexQueryParamGetResponse,
MandatoryRequestHeaderGetResponse,
MergePatchJsonGetResponse,
Expand All @@ -126,6 +125,7 @@ use openapi_v3::{
XmlOtherPutResponse,
XmlPostResponse,
XmlPutResponse,
EnumInPathPathParamGetResponse,
CreateRepoResponse,
GetRepoInfoResponse,
};
Expand Down Expand Up @@ -163,15 +163,6 @@ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString> + Send + Sync
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
}

async fn enum_in_path_path_param_get(
&self,
path_param: models::StringEnum,
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>
{
info!("enum_in_path_path_param_get({:?}) - X-Span-ID: {:?}", path_param, context.get().0.clone());
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
}

async fn json_complex_query_param_get(
&self,
list_of_strings: Option<&Vec<models::StringObject>>,
Expand Down Expand Up @@ -348,6 +339,15 @@ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString> + Send + Sync
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
}

async fn enum_in_path_path_param_get(
&self,
path_param: models::StringEnum,
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>
{
info!("enum_in_path_path_param_get({:?}) - X-Span-ID: {:?}", path_param, context.get().0.clone());
Err(ApiError("Api-Error: Operation is NOT implemented".into()))
}

async fn create_repo(
&self,
object_param: models::ObjectParam,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ use crate::{Api,
AnyOfGetResponse,
CallbackWithHeaderPostResponse,
ComplexQueryParamGetResponse,
EnumInPathPathParamGetResponse,
JsonComplexQueryParamGetResponse,
MandatoryRequestHeaderGetResponse,
MergePatchJsonGetResponse,
Expand All @@ -60,6 +59,7 @@ use crate::{Api,
XmlOtherPutResponse,
XmlPostResponse,
XmlPutResponse,
EnumInPathPathParamGetResponse,
CreateRepoResponse,
GetRepoInfoResponse
};
Expand Down Expand Up @@ -667,76 +667,6 @@ impl<S, C> Api<C> for Client<S, C> where
}
}

async fn enum_in_path_path_param_get(
&self,
param_path_param: models::StringEnum,
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>
{
let mut client_service = self.client_service.clone();
let mut uri = format!(
"{}/enum_in_path/{path_param}",
self.base_path
,path_param=utf8_percent_encode(&param_path_param.to_string(), ID_ENCODE_SET)
);

// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
query_string.finish()
};
if !query_string.is_empty() {
uri += "?";
uri += &query_string;
}

let uri = match Uri::from_str(&uri) {
Ok(uri) => uri,
Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
};

let mut request = match Request::builder()
.method("GET")
.uri(uri)
.body(Body::empty()) {
Ok(req) => req,
Err(e) => return Err(ApiError(format!("Unable to create request: {}", e)))
};

let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))
});

let response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?;

match response.status().as_u16() {
200 => {
Ok(
EnumInPathPathParamGetResponse::Success
)
}
code => {
let headers = response.headers().clone();
let body = response.into_body()
.take(100)
.into_raw().await;
Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
code,
headers,
match body {
Ok(body) => match String::from_utf8(body) {
Ok(body) => body,
Err(e) => format!("<Body was not UTF8: {:?}>", e),
},
Err(e) => format!("<Failed to read body: {}>", e),
}
)))
}
}
}

async fn json_complex_query_param_get(
&self,
param_list_of_strings: Option<&Vec<models::StringObject>>,
Expand Down Expand Up @@ -2597,6 +2527,76 @@ impl<S, C> Api<C> for Client<S, C> where
}
}

async fn enum_in_path_path_param_get(
&self,
param_path_param: models::StringEnum,
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>
{
let mut client_service = self.client_service.clone();
let mut uri = format!(
"{}/enum_in_path/{path_param}",
self.base_path
,path_param=utf8_percent_encode(&param_path_param.to_string(), ID_ENCODE_SET)
);

// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
query_string.finish()
};
if !query_string.is_empty() {
uri += "?";
uri += &query_string;
}

let uri = match Uri::from_str(&uri) {
Ok(uri) => uri,
Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
};

let mut request = match Request::builder()
.method("GET")
.uri(uri)
.body(Body::empty()) {
Ok(req) => req,
Err(e) => return Err(ApiError(format!("Unable to create request: {}", e)))
};

let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))
});

let response = client_service.call((request, context.clone()))
.map_err(|e| ApiError(format!("No response received: {}", e))).await?;

match response.status().as_u16() {
200 => {
Ok(
EnumInPathPathParamGetResponse::Success
)
}
code => {
let headers = response.headers().clone();
let body = response.into_body()
.take(100)
.into_raw().await;
Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
code,
headers,
match body {
Ok(body) => match String::from_utf8(body) {
Ok(body) => body,
Err(e) => format!("<Body was not UTF8: {:?}>", e),
},
Err(e) => format!("<Failed to read body: {}>", e),
}
)))
}
}
}

async fn create_repo(
&self,
param_object_param: models::ObjectParam,
Expand Down
Loading

0 comments on commit df2b421

Please sign in to comment.