Skip to content

Commit f32d296

Browse files
committed
fix(openapi): improves schema type detection when generating examples.
1 parent 2604b2e commit f32d296

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

mock/openapi/src/main/java/io/gatehill/imposter/plugin/openapi/service/SchemaServiceImpl.kt

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class SchemaServiceImpl : SchemaService {
118118
is ObjectSchema -> buildFromProperties(spec, schema.properties)
119119
is ArraySchema -> buildFromArraySchema(spec, schema)
120120
is ComposedSchema -> buildFromComposedSchema(spec, schema)
121-
else -> getPropertyDefault(schema, propNameHint)
121+
else -> determineFromType(spec, schema, propNameHint)
122122
}
123123
}
124124
return example
@@ -127,7 +127,51 @@ class SchemaServiceImpl : SchemaService {
127127
}
128128
}
129129

130-
private fun buildFromArraySchema(spec: OpenAPI, schema: ArraySchema): List<Any?> {
130+
/**
131+
* Use the schema `type` or `types` (OpenAPI 3.1) properties to build an example.
132+
*/
133+
private fun determineFromType(spec: OpenAPI, schema: Schema<*>, propNameHint: String?): Any? {
134+
schema.type?.let { schemaType ->
135+
return buildFromType(spec, schema, schemaType, propNameHint)
136+
137+
} ?: schema.types?.let { schemaTypes ->
138+
if (schemaTypes.isEmpty()) {
139+
LOGGER.warn("Schema type is null and no schema types set [propName={}] - falling back to property default: {}", propNameHint, schema)
140+
return getPropertyDefault(schema, propNameHint)
141+
} else {
142+
val schemaType = schemaTypes.first()
143+
if (schemaTypes.size > 1) {
144+
// TODO consider `null` as a valid type in an array of `types` in OpenAPI 3.1 - choose first non-null
145+
LOGGER.warn("More than one schema type ({}) set [propName={}] - choosing first: {}", schemaTypes, propNameHint, schemaType)
146+
} else {
147+
LOGGER.trace("Exactly one schema type set [propName={}]: {}", propNameHint, schemaType)
148+
}
149+
return buildFromType(spec, schema, schemaType, propNameHint)
150+
}
151+
} ?: run {
152+
LOGGER.warn("No schema type or types set - falling back to property default for '{}', {}", propNameHint, schema)
153+
return getPropertyDefault(schema, propNameHint)
154+
}
155+
}
156+
157+
/**
158+
* Use the given schema type to build an example.
159+
*/
160+
private fun buildFromType(
161+
spec: OpenAPI,
162+
schema: Schema<*>,
163+
schemaType: String,
164+
propNameHint: String?,
165+
) = when (schemaType) {
166+
"array" -> buildFromArraySchema(spec, schema)
167+
"object" -> buildFromProperties(spec, schema.properties)
168+
else -> {
169+
// schema type is not an aggregate - look for specific example
170+
getPropertyDefault(schema, propNameHint)
171+
}
172+
}
173+
174+
private fun buildFromArraySchema(spec: OpenAPI, schema: Schema<*>): List<Any?> {
131175
if (null == schema.items) {
132176
return emptyList()
133177
}

0 commit comments

Comments
 (0)