Skip to content

Commit

Permalink
feat(core): add configuration property to toggle workarounds for Asyn…
Browse files Browse the repository at this point in the history
…cApi Studio

Co-authored-by: Timon Back <[email protected]>
  • Loading branch information
sam0r040 and timonback committed Jun 28, 2024
1 parent dfcc91b commit 1ec4db0
Show file tree
Hide file tree
Showing 7 changed files with 1,430 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ springwolf-bindings/springwolf-sqs-binding/build/
node_modules/

asyncapi.actual.json
asyncapi.actual.yaml

# Eclipse IDE
.classpath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,24 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
import io.swagger.v3.core.util.Yaml;

public class DefaultExampleYamlValueSerializer implements ExampleYamlValueSerializer {

private static final ObjectMapper yamlMapper = Yaml.mapper();
private final ObjectMapper yamlMapper;

public DefaultExampleYamlValueSerializer(SpringwolfConfigProperties springwolfConfigProperties) {
this.yamlMapper = Yaml.mapper();

if (springwolfConfigProperties.isStudioCompatibility()) {
// AsyncApi Studio has problems with missing quotes on dates, so we add quotes on every example
// see https://github.com/springwolf/springwolf-core/issues/820
((YAMLFactory) yamlMapper.getFactory()).disable(YAMLGenerator.Feature.MINIMIZE_QUOTES);
}
}

@Override
public String writeDocumentAsYamlString(JsonNode node) throws JsonProcessingException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.github.springwolf.core.asyncapi.components.examples.walkers.ExampleValueGenerator;
import io.github.springwolf.core.asyncapi.components.examples.walkers.PropertyExample;
import io.github.springwolf.core.asyncapi.components.examples.walkers.json.ExampleJsonValueGenerator;
import io.github.springwolf.core.configuration.properties.SpringwolfConfigProperties;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import lombok.RequiredArgsConstructor;
Expand All @@ -24,6 +25,7 @@ public class ExampleYamlValueGenerator implements ExampleValueGenerator<JsonNode

private final ExampleJsonValueGenerator exampleJsonValueGenerator;
private final ExampleYamlValueSerializer exampleYamlValueSerializer;
private final SpringwolfConfigProperties springwolfConfigProperties;

@Override
public boolean canHandle(String contentType) {
Expand All @@ -39,9 +41,12 @@ public Optional<String> lookupSchemaName(Schema schema) {
public String prepareForSerialization(Schema schema, JsonNode exampleObject) {
final String name = schema.getName();
try {
// spec workaround to embedded yaml examples as string https://github.com/asyncapi/spec/issues/1038
schema.setType(OVERRIDE_SCHEMA.getType());
schema.setTypes(OVERRIDE_SCHEMA.getTypes());
if (springwolfConfigProperties.isStudioCompatibility()) {

// spec workaround to embedded yaml examples as string https://github.com/asyncapi/spec/issues/1038
schema.setType(OVERRIDE_SCHEMA.getType());
schema.setTypes(OVERRIDE_SCHEMA.getTypes());
}

return exampleYamlValueSerializer.writeDocumentAsYamlString(exampleObject);
} catch (JsonProcessingException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,17 @@ public SchemaWalker xmlSchemaWalker(ExampleXmlValueSerializer exampleXmlValueSer

@Bean
@ConditionalOnMissingBean
public ExampleYamlValueSerializer defaultExampleYamlValueSerializer() {
return new DefaultExampleYamlValueSerializer();
public ExampleYamlValueSerializer defaultExampleYamlValueSerializer(
SpringwolfConfigProperties springwolfConfigProperties) {
return new DefaultExampleYamlValueSerializer(springwolfConfigProperties);
}

@Bean
public SchemaWalker yamlSchemaWalker(ExampleYamlValueSerializer exampleYamlValueSerializer) {
return new DefaultSchemaWalker<>(
new ExampleYamlValueGenerator(new ExampleJsonValueGenerator(), exampleYamlValueSerializer));
public SchemaWalker yamlSchemaWalker(
ExampleYamlValueSerializer exampleYamlValueSerializer,
SpringwolfConfigProperties springwolfConfigProperties) {
return new DefaultSchemaWalker<>(new ExampleYamlValueGenerator(
new ExampleJsonValueGenerator(), exampleYamlValueSerializer, springwolfConfigProperties));
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ public enum InitMode {
*/
private boolean useFqn = true;

/**
* Feature toggle to enable/disable all workarounds for AsyncApi Studio
* to ensure a best-effort out-of-the-box experience.
* @see https://studio.asyncapi.com/
*/
private boolean studioCompatibility = true;

@Deprecated(forRemoval = true)
private Paths paths = new Paths();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,18 @@ void asyncApiResourceArtifactTest() throws IOException {

assertEquals(expected, actualPatched);
}

@Test
void asyncApiResourceArtifactYamlTest() throws IOException {
String url = "/springwolf/docs.yaml";
String actual = restTemplate.getForObject(url, String.class);
// When running with EmbeddedKafka, the kafka bootstrap server does run on random ports
String actualPatched = actual.replace(bootstrapServers, "kafka:29092");
Files.writeString(Path.of("src", "test", "resources", "asyncapi.actual.yaml"), actualPatched);

InputStream s = this.getClass().getResourceAsStream("/asyncapi.yaml");
String expected = new String(s.readAllBytes(), StandardCharsets.UTF_8);

assertEquals(expected, actualPatched);
}
}
Loading

0 comments on commit 1ec4db0

Please sign in to comment.