Skip to content

Commit

Permalink
Support OpenApi common parameters (closes #42) (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
uuf6429 authored and cc-jhr committed Jul 5, 2019
1 parent e681762 commit 874300f
Show file tree
Hide file tree
Showing 13 changed files with 289 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,17 @@ class OpenApiConverter private constructor(private val specificationContent: Str
val extractPathParameters = PathParameterExtractor(openApi)

return openApi.paths.flatMap { (path, pathItem) ->
val commonQueryParameters = extractQueryParameters(pathItem.parameters)
val commonPathParameters = extractPathParameters(pathItem.parameters)
val commonHeaderParameters = extractHeaderParameters(pathItem.parameters)

pathItem.httpMethods().map { (httpMethod: HttpMethod, operation: Operation?) ->
Endpoint(
path = path,
httpMethod = httpMethod,
queryParameters = extractQueryParameters(operation),
pathParameters = extractPathParameters(operation),
headerParameters = extractHeaderParameters(operation),
queryParameters = commonQueryParameters.union(extractQueryParameters(operation?.parameters)),
pathParameters = commonPathParameters.union(extractPathParameters(operation?.parameters)),
headerParameters = commonHeaderParameters.union(extractHeaderParameters(operation?.parameters)),
consumes = extractConsumesMediaTypes(operation),
produces = extractProduceMediaTypes(operation),
deprecated = operation?.deprecated ?: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,25 @@ package de.codecentric.hikaku.converters.openapi.extractors
import de.codecentric.hikaku.converters.openapi.extensions.referencedSchema
import de.codecentric.hikaku.endpoints.HeaderParameter
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.Operation
import io.swagger.v3.oas.models.parameters.Parameter as OpenApiParameter
import io.swagger.v3.oas.models.parameters.HeaderParameter as OpenApiHeaderParameter

internal class HeaderParameterExtractor(private val openApi: OpenAPI) {

operator fun invoke(operation: Operation?): Set<HeaderParameter> {
return extractInlineHeaderParameters(operation).union(extractHeaderParametersFromComponents(operation))
operator fun invoke(parameters: List<OpenApiParameter>?): Set<HeaderParameter> {
return extractInlineHeaderParameters(parameters).union(extractHeaderParametersFromComponents(parameters))
}

private fun extractInlineHeaderParameters(operation: Operation?): Set<HeaderParameter> {
return operation?.parameters
private fun extractInlineHeaderParameters(parameters: List<OpenApiParameter>?): Set<HeaderParameter> {
return parameters
?.filterIsInstance<OpenApiHeaderParameter>()
?.map { HeaderParameter(it.name, it.required) }
.orEmpty()
.toSet()
}

private fun extractHeaderParametersFromComponents(operation: Operation?): Set<HeaderParameter> {
return operation?.parameters
?.filterIsInstance<OpenApiParameter>()
private fun extractHeaderParametersFromComponents(parameters: List<OpenApiParameter>?): Set<HeaderParameter> {
return parameters
?.filter { it.referencedSchema != null }
?.map {
Regex("#/components/parameters/(?<key>.+)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,25 @@ package de.codecentric.hikaku.converters.openapi.extractors
import de.codecentric.hikaku.converters.openapi.extensions.referencedSchema
import de.codecentric.hikaku.endpoints.PathParameter
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.Operation
import io.swagger.v3.oas.models.parameters.PathParameter as OpenApiPathParameter
import io.swagger.v3.oas.models.parameters.Parameter as OpenApiParameter

internal class PathParameterExtractor(private val openApi: OpenAPI) {

operator fun invoke(operation: Operation?): Set<PathParameter> {
return extractInlinePathParameters(operation).union(extractPathParametersFromComponents(operation))
operator fun invoke(parameters: List<OpenApiParameter>?): Set<PathParameter> {
return extractInlinePathParameters(parameters).union(extractPathParametersFromComponents(parameters))
}

private fun extractInlinePathParameters(operation: Operation?): Set<PathParameter> {
return operation?.parameters
private fun extractInlinePathParameters(parameters: List<OpenApiParameter>?): Set<PathParameter> {
return parameters
?.filterIsInstance<OpenApiPathParameter>()
?.map { PathParameter(it.name) }
.orEmpty()
.toSet()
}

private fun extractPathParametersFromComponents(operation: Operation?): Set<PathParameter> {
return operation?.parameters
?.filterIsInstance<OpenApiParameter>()
private fun extractPathParametersFromComponents(parameters: List<OpenApiParameter>?): Set<PathParameter> {
return parameters
?.filter { it.referencedSchema != null }
?.map {
Regex("#/components/parameters/(?<key>.+)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,25 @@ package de.codecentric.hikaku.converters.openapi.extractors
import de.codecentric.hikaku.converters.openapi.extensions.referencedSchema
import de.codecentric.hikaku.endpoints.QueryParameter
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.Operation
import io.swagger.v3.oas.models.parameters.Parameter as OpenApiParameter
import io.swagger.v3.oas.models.parameters.QueryParameter as OpenApiQueryParameter

internal class QueryParameterExtractor(private val openApi: OpenAPI) {

operator fun invoke(operation: Operation?): Set<QueryParameter> {
return extractInlineQueryParameters(operation).union(extractQueryParametersFromComponents(operation))
operator fun invoke(parameters: List<OpenApiParameter>?): Set<QueryParameter> {
return extractInlineQueryParameters(parameters).union(extractQueryParametersFromComponents(parameters))
}

private fun extractInlineQueryParameters(operation: Operation?): Set<QueryParameter> {
return operation?.parameters
private fun extractInlineQueryParameters(parameters: List<OpenApiParameter>?): Set<QueryParameter> {
return parameters
?.filterIsInstance<OpenApiQueryParameter>()
?.map { QueryParameter(it.name, it.required) }
.orEmpty()
.toSet()
}

private fun extractQueryParametersFromComponents(operation: Operation?): Set<QueryParameter> {
return operation?.parameters
?.filterIsInstance<OpenApiParameter>()
private fun extractQueryParametersFromComponents(parameters: List<OpenApiParameter>?): Set<QueryParameter> {
return parameters
?.filter { it.referencedSchema != null }
?.map {
Regex("#/components/parameters/(?<key>.+)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,36 @@ class OpenApiConverterHeaderParameterTest {
//then
assertThat(result).containsExactlyInAnyOrderElementsOf(headerParameters)
}

@Test
fun `common header parameter inline declaration on Operation object`() {
//given
val file = Paths.get(this::class.java.classLoader.getResource("header_parameter/common_header_parameter_inline.yaml").toURI())
val headerParameters = setOf(
HeaderParameter("x-b3-traceid", false),
HeaderParameter("allow-cache", true)
)

//when
val result = OpenApiConverter(file).conversionResult.toList()[0].headerParameters

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(headerParameters)
}

@Test
fun `one common header parameter declared inline and one parameter referenced from parameters section in components`() {
//given
val file = Paths.get(this::class.java.classLoader.getResource("header_parameter/common_header_parameter_in_components.yaml").toURI())
val headerParameters = setOf(
HeaderParameter("x-b3-traceid", false),
HeaderParameter("allow-cache", true)
)

//when
val result = OpenApiConverter(file).conversionResult.toList()[0].headerParameters

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(headerParameters)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,34 @@ class OpenApiConverterPathParameterTest {
assertThat(result[1].pathParameters).containsExactly(pathParameter)
assertThat(result[2].pathParameters).containsExactly(pathParameter)
}

@Test
fun `common path parameter inline declaration`() {
//given
val file = Paths.get(this::class.java.classLoader.getResource("path_parameter/common_path_parameter_inline.yaml").toURI())
val pathParameter = PathParameter("id")

//when
val result = OpenApiConverter(file).conversionResult.toList()

//then
assertThat(result[0].pathParameters).containsExactly(pathParameter)
assertThat(result[1].pathParameters).containsExactly(pathParameter)
assertThat(result[2].pathParameters).containsExactly(pathParameter)
}

@Test
fun `common path parameter referenced from parameters section in components`() {
//given
val file = Paths.get(this::class.java.classLoader.getResource("path_parameter/common_path_parameter_in_components.yaml").toURI())
val pathParameter = PathParameter("id")

//when
val result = OpenApiConverter(file).conversionResult.toList()

//then
assertThat(result[0].pathParameters).containsExactly(pathParameter)
assertThat(result[1].pathParameters).containsExactly(pathParameter)
assertThat(result[2].pathParameters).containsExactly(pathParameter)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,36 @@ class OpenApiConverterQueryParameterTest {
//then
assertThat(result).containsExactlyInAnyOrderElementsOf(queryParameters)
}

@Test
fun `common query parameter inline declaration on Operation object`() {
//given
val file = Paths.get(this::class.java.classLoader.getResource("query_parameter/common_query_parameter_inline.yaml").toURI())
val queryParameters = setOf(
QueryParameter("tag", false),
QueryParameter("limit", true)
)

//when
val result = OpenApiConverter(file).conversionResult.toList()[0].queryParameters

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(queryParameters)
}

@Test
fun `one query parameter declared inline and one common parameter referenced from parameters section in components`() {
//given
val file = Paths.get(this::class.java.classLoader.getResource("query_parameter/common_query_parameter_in_components.yaml").toURI())
val queryParameters = setOf(
QueryParameter("tag", false),
QueryParameter("limit", true)
)

//when
val result = OpenApiConverter(file).conversionResult.toList()[0].queryParameters

//then
assertThat(result).containsExactlyInAnyOrderElementsOf(queryParameters)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
openapi: 3.0.2
info:
version: 1.0.0
title: Todo List
paths:
/todos:
parameters:
- name: x-b3-traceid
in: header
required: false
description: "Trace id."
schema:
type: string
- $ref: "#/components/parameters/allowCacheParam"
get:
description: 'Get all todos'
responses:
'200':
description: OK
components:
parameters:
allowCacheParam:
name: allow-cache
in: header
required: true
description: "Whether cached data is allowed or not."
schema:
type: boolean
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
openapi: 3.0.2
info:
version: 1.0.0
title: Todo List
paths:
/todos:
parameters:
- name: x-b3-traceid
in: header
required: false
description: "Trace id."
schema:
type: string
- name: allow-cache
in: header
required: true
description: "Whether cached data is allowed or not."
schema:
type: boolean
get:
description: 'Get all todos'
responses:
'200':
description: OK
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
openapi: 3.0.2
info:
version: 1.0.0
title: Todo List
paths:
/todos/{id}:
parameters:
- $ref: "#/components/parameters/todoIdParam"
get:
description: 'Get all todos'
responses:
'200':
description: OK
post:
description: 'Create a new todo.'
responses:
'200':
description: OK
delete:
description: 'Delete a todo entry.'
responses:
'200':
description: OK
components:
parameters:
todoIdParam:
name: id
in: path
required: true
description: "Identifier of a specific todo entry."
schema:
type: integer
format: int32
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
openapi: 3.0.2
info:
version: 1.0.0
title: Todo List
paths:
/todos/{id}:
parameters:
- name: id
in: path
required: true
description: "Identifier of a specific todo entry."
schema:
type: integer
format: int32
get:
description: 'Get all todos'
responses:
'200':
description: OK
post:
description: 'Create a new todo.'
responses:
'200':
description: OK
delete:
description: 'Delete a todo entry.'
responses:
'200':
description: OK
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
openapi: 3.0.2
info:
version: 1.0.0
title: Todo List
paths:
/todos:
parameters:
- $ref: "#/components/parameters/limitParam"
get:
description: 'Get all todos'
parameters:
- name: tag
in: query
required: false
description: "Filter todos by a given tag."
schema:
type: string
responses:
'200':
description: OK
components:
parameters:
limitParam:
name: limit
in: query
required: true
description: "Limit"
schema:
type: number
format: int32
Loading

0 comments on commit 874300f

Please sign in to comment.