Skip to content

fix: make usefqn threadsafe#1709

Open
tvahrst wants to merge 13 commits intospringwolf:mainfrom
tvahrst:fix-usefqn-threadsafe
Open

fix: make usefqn threadsafe#1709
tvahrst wants to merge 13 commits intospringwolf:mainfrom
tvahrst:fix-usefqn-threadsafe

Conversation

@tvahrst
Copy link
Copy Markdown
Contributor

@tvahrst tvahrst commented Apr 19, 2026

Unfortunately, using the static 'std' instance of Swagger's TypeNameResolver is not thread-safe. This can lead to unwanted race conditions and side effects (see Issue #635).

To fix this, code sections using TypeNameResolver must utilize a dedicated, properly configured instance (with usefqn set correctly). This requires the ability to create a custom instance of TypeNameResolver. Since the constructor is protected, a simple subclass SpringWolfTypeNameResolver was introduced to make the constructor public.

A custom TypeNameResolver must be implemented in the following locations:

  • SwaggerSchemaService: Two TypeNameResolver instances are required—one to generate simple names and a second instance based on the 'useFqn' property.
  • Swagger ModelConverters: Internally, this uses a ModelResolver, which in turn relies on the global, static instance of TypeNameResolver. To correct this, the internal ModelResolver instance must be replaced with a properly initialized one during the creation of ModelConverters. See ModelConvertersProvider.

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 19, 2026

Deploy Preview for springwolf-ui canceled.

Name Link
🔨 Latest commit 8969af7
🔍 Latest deploy log https://app.netlify.com/projects/springwolf-ui/deploys/69f273479f505300080fb9a1

@tvahrst tvahrst force-pushed the fix-usefqn-threadsafe branch from 9667b9e to 6f9a757 Compare April 19, 2026 14:11
@tvahrst tvahrst force-pushed the fix-usefqn-threadsafe branch from 6f9a757 to d21c260 Compare April 19, 2026 14:39
@timonback
Copy link
Copy Markdown
Member

I took a look, there is something wrong in combination with Protobuf or how the ObjectMapper is used to generated the examples.
I looks better now or it seems there was a bug before for the openapi31 format output. But for some reason, the ConsumerRecordMetadata schema has no type and therefore the example is empty / throws an exception.

@tvahrst Can you confirm, that the updated schema with openapi31 matches your expectation?
Any thoughts on the ConsumerRecordMetadata?

@tvahrst
Copy link
Copy Markdown
Contributor Author

tvahrst commented Apr 26, 2026

Hi @timonback , the Spring class ConsumerRecordMetaData, which is used as a @Header in the Kafka tests, doesn't conform to Java Bean conventions, so Swagger ModelConverters can't generate a correct schema from it. While ModelConverters 3.0 at least defined type=object, ModelConverters 3.1 generates an empty schema with type=null, which leads to the current result.

I've provided a separate, small ModelConverter class for the Kafka test suite that explicitly reacts to ConsumerRecordMetaData and provides a simple, empty object-schema. With this, the result of the PayloadSchemaFormatIntegrationTest for OpenAPI 3.1 looks quite similar to OpenAPI 3.0.

While I was at it, I also made a small adjustment to the error output during example schema generation to display the name of the schema in case of exceptions.

I was wondering why the test for OpenAPI 3.1 changed so much compared to the master version due to this pull request. The reason was this: On the master version, a ModelConverter bean, specifically a ModelResolver, is created in the ProtobufStandAloneConfiguration.

Firstly, this is internally set to OpenAPI 3.0. Secondly, this is an 'additionalModelConverter', which is collected in the ModelConvertersProvider and assigned to both internal ModelConverters instances (3.0 and 3.1). Therefore, the 3.1 ModelConverter contained two ModelResolver instances and was inadvertently converted into a 3.0 ModelConverters bean.

@timonback
Copy link
Copy Markdown
Member

Good catch, so adding the ConsumerMetaData in general could be seen as wrong and could be omitted (in a future adjustment).

Adding more debug output is good. Ill have to check that that cannot raise a nullpointer exception.

Thank you for the explanation. Just to confirm, there was a bug before and it is corrected now? Or do you see another issue with the modelresolvers for protobuf?

@tvahrst
Copy link
Copy Markdown
Contributor Author

tvahrst commented Apr 27, 2026

Yes, the new ProtobufConfiguration without providing a ModelResolvers bean looks good for me.

One example is ConsumerRecordMetadata in kafka, which contains metadata via the @Header annotation. But it is not part of the transport protocol and should not be part of AsyncApi
@timonback timonback marked this pull request as ready for review April 29, 2026 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants