Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ object core extends BaseJavaModule {
object protobuf extends BaseJavaModule {}

val scalaVersionsMap =
Map("2.13" -> "2.13.7", "2.12" -> "2.12.17", "3" -> "3.3.0")
Map("2.13" -> "2.13.15", "2.12" -> "2.12.17", "3" -> "3.3.0")
object openapi extends Cross[OpenapiModule](scalaVersionsMap.keys.toList)
trait OpenapiModule extends BaseCrossScalaModule {
val crossVersion = crossValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,48 @@ abstract class AlloyAbstractRestProtocol[T <: Trait]
createRequestBody(context, bindingIndex, operation)
.foreach(builder.requestBody)
createResponses(context, bindingIndex, operation)
.foreach { case (k, v) => builder.putResponse(k, v) }
.foreach { case (k, values) =>
combineResponseContent(values).foreach(v =>
builder.putResponse(k, v)
)
}
Operation.create(method, uri, builder)
})
.asJava

def combineResponseContent(
responses: List[ResponseObject]
): Option[ResponseObject] = {
responses match {
case Nil => None
case head :: Nil => Some(head)
case head :: tail =>
val all = head +: tail
val mediaTypeObjects: List[MediaTypeObject] =
all.flatMap(_.getContent().asScala.toList.map {
case (_, mediaTypeObject) => mediaTypeObject
})
val schemas =
mediaTypeObjects.flatMap(_.getSchema().asScala)
val newSchema = Schema.builder().oneOf(schemas.asJava).build()
val newExamples = mediaTypeObjects
.flatMap(_.getExamples().asScala.toList)
.toMap
.map { case (k, exampleObj) => k -> exampleObj.toNode() }
val media = MediaTypeObject.builder
.examples(
newExamples.asJava
)
.schema(newSchema)
.build()
// `AlloyAbstractRestProtocol` only supports a single content-type, application/json
// This is why we can just use the content from `head` here
val newContent =
head.getContent().asScala.map { case (k, _) => k -> media }
Some(head.toBuilder().content(newContent.asJava).build())
}
}

def createPathParameters(
context: Context[T],
operation: OperationShape
Expand Down Expand Up @@ -401,7 +438,7 @@ abstract class AlloyAbstractRestProtocol[T <: Trait]
// operation shape.
val updatedModel =
context.getModel().toBuilder().addShape(operation).build()
val result = new util.TreeMap[String, ResponseObject]
val result = new util.TreeMap[String, List[ResponseObject]]
val operationIndex = OperationIndex.of(updatedModel)
operationIndex
.getOutputShape(operation)
Expand Down Expand Up @@ -467,7 +504,7 @@ abstract class AlloyAbstractRestProtocol[T <: Trait]
bindingIndex: HttpBindingIndex,
operation: OperationShape,
shape: StructureShape,
responses: util.Map[String, ResponseObject]
responses: util.Map[String, List[ResponseObject]]
) = {
val operationOrError = reorganizeExampleTraits(operation, shape)
val statusCode = context.getOpenApiProtocol.getOperationResponseStatusCode(
Expand All @@ -480,7 +517,14 @@ abstract class AlloyAbstractRestProtocol[T <: Trait]
statusCode,
operationOrError
)
responses.put(statusCode, response)
val currentResponses: Option[List[ResponseObject]] = Option(
responses.get(statusCode)
)
val updatedResponses = currentResponses match {
case Some(current) => current :+ response
case None => List(response)
}
responses.put(statusCode, updatedResponses)
}

private def createResponse(
Expand Down
30 changes: 29 additions & 1 deletion modules/openapi/test/resources/foo.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@
"in": "testinput"
}
},
"THREE": {
"value": {
"in": "testinputthree"
}
},
"TWO": {
"value": {
"in": "testinputtwo"
Expand Down Expand Up @@ -177,9 +182,21 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotFoundResponseContent"
"oneOf": [
{
"$ref": "#/components/schemas/NotFoundResponseContent"
},
{
"$ref": "#/components/schemas/NotFoundTwoResponseContent"
}
]
},
"examples": {
"THREE": {
"value": {
"messageTwo": "Notfoundmessagetwo"
}
},
"TWO": {
"value": {
"message": "Notfoundmessage"
Expand Down Expand Up @@ -424,6 +441,17 @@
"message"
]
},
"NotFoundTwoResponseContent": {
"type": "object",
"properties": {
"messageTwo": {
"type": "string"
}
},
"required": [
"messageTwo"
]
},
"SomeValue": {
"oneOf": [
{
Expand Down
Loading