Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build example for schema: error with SpringWolf 1.4.0, but working fine with 1.2.0 #829

Closed
pdalfarr opened this issue Jul 2, 2024 · 6 comments
Assignees
Labels
bug Something isn't working staged for release

Comments

@pdalfarr
Copy link
Contributor

pdalfarr commented Jul 2, 2024

Describe the bug
Schema generation was working fine with SpringWolf 1.2.0.
I changed version from 1.2.0 to 1.4.0: as a result, my Spring app is working fine, but Springwolf does not work.
See log message and stack trace below.

Dependencies and versions used
SpringWolf 1.2.0 :

	<!-- Springwolf -->
	<dependency>
		<groupId>io.github.springwolf</groupId>
		<artifactId>springwolf-core</artifactId>
		<version>${version.springwolf}</version>
	</dependency>
	<dependency>
		<groupId>io.github.springwolf</groupId>
		<artifactId>springwolf-amqp</artifactId>
		<version>${version.springwolf}</version>
	</dependency>
	<dependency>
		<groupId>io.github.springwolf</groupId>
		<artifactId>springwolf-ui</artifactId>
		<version>${version.springwolf}</version>
	</dependency>
	<!-- Springwolf end -->

SpringWolf 1.4.0: same as above plus:

		<dependency>
			<groupId>io.github.springwolf</groupId>
			<artifactId>springwolf-amqp-binding</artifactId>
			<version>${version.springwolf}</version>
		</dependency>

Code example
No code example

Stack trace and error logs

I see multiple log messages like this :

2024-07-02 10:15:48.297  INFO [rapport-controle,,] 50188 --- [           main] i.g.s.c.a.c.e.w.DefaultSchemaWalker      : Failed to build example for schema: There is no name set for Schema: class StringSchema {
    class Schema {
        type: string
        format: null
        $ref: null
        description: null
        title: null
        multipleOf: null
        maximum: null
        exclusiveMaximum: null
        minimum: null
        exclusiveMinimum: null
        maxLength: null
        minLength: null
        pattern: null
        maxItems: null
        minItems: null
        uniqueItems: null
        maxProperties: null
        minProperties: null
        required: null
        not: null
        properties: null
        additionalProperties: null
        nullable: null
        readOnly: null
        writeOnly: null
        example: null
        externalDocs: null
        deprecated: null
        discriminator: null
        xml: null
    }
}

io.github.springwolf.core.asyncapi.components.examples.walkers.SchemaWalker$ExampleGeneratingException: There is no name set for Schema: class StringSchema {
    class Schema {
        type: string
        format: null
        $ref: null
        description: null
        title: null
        multipleOf: null
        maximum: null
        exclusiveMaximum: null
        minimum: null
        exclusiveMinimum: null
        maxLength: null
        minLength: null
        pattern: null
        maxItems: null
        minItems: null
        uniqueItems: null
        maxProperties: null
        minProperties: null
        required: null
        not: null
        properties: null
        additionalProperties: null
        nullable: null
        readOnly: null
        writeOnly: null
        example: null
        externalDocs: null
        deprecated: null
        discriminator: null
        xml: null
    }
}
	at io.github.springwolf.core.asyncapi.components.examples.walkers.DefaultSchemaWalker.lambda$fromSchema$0(DefaultSchemaWalker.java:60) ~[springwolf-core-1.4.0.jar:na]
	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
	at io.github.springwolf.core.asyncapi.components.examples.walkers.DefaultSchemaWalker.fromSchema(DefaultSchemaWalker.java:59) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.components.postprocessors.ExampleGeneratorPostProcessor.process(ExampleGeneratorPostProcessor.java:26) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.schemas.SwaggerSchemaService.postProcessSchema(SwaggerSchemaService.java:210) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.schemas.SwaggerSchemaService.extractSchema(SwaggerSchemaService.java:89) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.components.DefaultComponentsService.registerSchema(DefaultComponentsService.java:51) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.scanners.common.payload.internal.PayloadService.buildSchema(PayloadService.java:35) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.scanners.common.payload.internal.PayloadService.buildSchema(PayloadService.java:31) ~[springwolf-core-1.4.0.jar:na]
	at java.base/java.util.Optional.map(Optional.java:260) ~[na:na]
	at io.github.springwolf.core.asyncapi.scanners.common.payload.PayloadMethodParameterService.extractSchema(PayloadMethodParameterService.java:19) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.scanners.operations.annotations.SpringAnnotationMethodLevelOperationsScanner.mapMethodToOperation(SpringAnnotationMethodLevelOperationsScanner.java:77) ~[springwolf-core-1.4.0.jar:na]
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[na:na]
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276) ~[na:na]
	at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627) ~[na:na]
	at io.github.springwolf.core.asyncapi.scanners.operations.SpringAnnotationOperationsScanner.mapToOperations(SpringAnnotationOperationsScanner.java:31) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.scanners.operations.SpringAnnotationOperationsScanner.scan(SpringAnnotationOperationsScanner.java:25) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.operations.DefaultOperationsService.findOperations(DefaultOperationsService.java:34) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.DefaultAsyncApiService.initAsyncAPI(DefaultAsyncApiService.java:71) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.asyncapi.DefaultAsyncApiService.getAsyncAPI(DefaultAsyncApiService.java:42) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:31) ~[springwolf-core-1.4.0.jar:na]
	at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:17) ~[springwolf-core-1.4.0.jar:na]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-5.3.31.jar:5.3.31]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171) ~[spring-context-5.3.31.jar:5.3.31]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:145) ~[spring-context-5.3.31.jar:5.3.31]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:429) ~[spring-context-5.3.31.jar:5.3.31]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:386) ~[spring-context-5.3.31.jar:5.3.31]
	at org.springframework.boot.context.event.EventPublishingRunListener.ready(EventPublishingRunListener.java:114) ~[spring-boot-2.7.18.jar:2.7.18]
	at org.springframework.boot.SpringApplicationRunListeners.lambda$ready$6(SpringApplicationRunListeners.java:82) ~[spring-boot-2.7.18.jar:2.7.18]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120) ~[spring-boot-2.7.18.jar:2.7.18]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114) ~[spring-boot-2.7.18.jar:2.7.18]
	at org.springframework.boot.SpringApplicationRunListeners.ready(SpringApplicationRunListeners.java:82) ~[spring-boot-2.7.18.jar:2.7.18]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:323) ~[spring-boot-2.7.18.jar:2.7.18]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.7.18.jar:2.7.18]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289) ~[spring-boot-2.7.18.jar:2.7.18]
@pdalfarr pdalfarr added the bug Something isn't working label Jul 2, 2024
@sam0r040
Copy link
Collaborator

sam0r040 commented Jul 5, 2024

Hi @pdalfarr,
thank you for the report.
For us it is difficult to reproduce this without the class for the schema.
Please enable debug mode to finde the method that includes the problematic payload and share the code for the payload with us.

@sam0r040 sam0r040 added the waiting for feedback Waiting for user feedback/response label Jul 5, 2024
@ruskaof
Copy link

ruskaof commented Jul 27, 2024

Hello, @sam0r040
I've found code that can generate the problematic payload:

public record MyRootObject(
    MyEnumObject myEnumObject
) {
}
@Schema(enumAsRef = true)
public enum MyEnumObject {
    VALUE1,
    VALUE2
}
@Component
public class Producer {
    @AsyncPublisher(operation = @AsyncOperation(channelName = "mychannel"))
    public void produce(MyRootObject message) {
    }
}

The problem is that schema name for MyEnumObject is resolved to null and thus DefaultShemaWalker throws an exception here https://github.com/springwolf/springwolf-core/blob/master/springwolf-core/src/main/java/io/github/springwolf/core/asyncapi/components/examples/walkers/DefaultSchemaWalker.java#L61

Also, if you remove the wrapper class MyRootObject and return MyEnumObject itself in the produce() method no exception is thrown but no example for MyEnumObject is generated.

@github-actions github-actions bot removed the waiting for feedback Waiting for user feedback/response label Jul 27, 2024
timonback added a commit to timonback/springwolf-core that referenced this issue Jul 31, 2024
@timonback
Copy link
Member

timonback commented Jul 31, 2024

Hi @pdalfarr , @ruskaof,
I reproduced it with your code in #887

I do see the (unexpected) exception: There is no name set...
MyRootObject does have a valid example, MyEnumObject is missing one.

Do you expect an example for MyEnumObject and/or no exception?
Will keep looking into it.

@ruskaof
Copy link

ruskaof commented Aug 1, 2024

I think that there should not be an exception thrown because schema name should be generated from a class name if it is not defined explicitly in the @Schema annotation. Also, it would be nice to have the enum class with its values referenced in the Schemas section of the UI. Something like springdoc generates with REST endpoints:
image

@timonback timonback self-assigned this Aug 23, 2024
sam0r040 added a commit to sam0r040/springwolf-core that referenced this issue Aug 30, 2024
…springwolfGH-829

Co-authored-by: Timon Back <timonback@users.noreply.github.com>
timonback added a commit that referenced this issue Aug 30, 2024
#953)

* feat(common-model-converters): add model converter to handle enumAsRef GH-829

Co-authored-by: Timon Back <timonback@users.noreply.github.com>

* test(core): add integration test for enumAsRef

Co-authored-by: David Müller <david.mueller@codecentric.de>

---------

Co-authored-by: Timon Back <timonback@users.noreply.github.com>
Copy link

The change is staged for release and will be part of the next release.

If you want to try and verify it in your application today,
use the latest 1.X.0-SNAPSHOT build as described in our README.md > Testing SNAPSHOT version

Thank you for the report/contribution!

Copy link

The change is available in the latest release. 🎉

Thank you for the report/contribution and making Springwolf better!

ruskaof pushed a commit to ruskaof/springwolf-core that referenced this issue Nov 20, 2024
springwolf#953)

* feat(common-model-converters): add model converter to handle enumAsRef springwolfGH-829

Co-authored-by: Timon Back <timonback@users.noreply.github.com>

* test(core): add integration test for enumAsRef

Co-authored-by: David Müller <david.mueller@codecentric.de>

---------

Co-authored-by: Timon Back <timonback@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working staged for release
Projects
None yet
Development

No branches or pull requests

4 participants