scs-multiapi-plugin icon indicating copy to clipboard operation
scs-multiapi-plugin copied to clipboard

Sample of asyncApi not generated. End with java.util.regex.PatternSyntaxException: Stack overflow during pattern compilation near index 1 ([./])

Open devNbis opened this issue 2 years ago • 11 comments
trafficstars

I've try ed to use the original asyncApi sample from the editor as source and want to generate the code from it. Simple.txt

It stops with the rerror in maven: org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.sngular:scs-multiapi-maven-plugin:4.9.12:asyncapi-generation (default) on project consuming-retry: Execution default of goal com.sngular:scs-multiapi-maven-plugin:4.9.12:asyncapi-generation failed: Stack overflow during pattern compilation near index 1
([./])
^
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:375) at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171) at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81) at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128) at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:298) at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192) at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105) at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960) at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293) at org.apache.maven.cli.MavenCli.main (MavenCli.java:196) at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104) at java.lang.reflect.Method.invoke (Method.java:578) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283) at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407) at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348) Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default of goal com.sngular:scs-multiapi-maven-plugin:4.9.12:asyncapi-generation failed: Stack overflow during pattern compilation near index 1
([./])

I dig into the code a little bit and wondering of the regx private static final String DIVISOR = "([./])"; Would you like have every char as an array entry? Should the regx not be private static final String DIVISOR = "([./])";

devNbis avatar Sep 12 '23 05:09 devNbis

Thank you for collaborating with the project by giving us feedback! Cheers!

github-actions[bot] avatar Sep 12 '23 05:09 github-actions[bot]

Sorry the regx should be private static final String DIVISOR = "([\\./])";

devNbis avatar Sep 12 '23 06:09 devNbis

Hi @devNbis, you are right, apart of that I saw some features we are not supporting right now. I will try to make a first stage support on them, as traits and parameters for the channel.

Cheers.

jemacineiras avatar Sep 13 '23 06:09 jemacineiras

Thanks a lot, I've fired out that is also a problem on references !type:object . It creates always the object name like a class.

"EventDataDTO": {
    "name":" EventDataDTO",
     "$id":"EventDataDTO",
     "title": "Event",
     "type": "object",          
     "properties": {
          "name": {
            "type": "string"
          },
          "currency": {
                "$ref": "#/components/schemas/Currency"
           }
      }
 },
 "Currency": {
     "type": "string",
       "format": "currency",
 }

Will result as @JsonProperty(value ="leadingCurrency") private Currency leadingCurrency;

But it should be @JsonProperty(value ="leadingCurrency") private String leadingCurrency;

devNbis avatar Sep 13 '23 06:09 devNbis

Ok, I think I still need to review that $ref resolution. Can you please open another issue? We need to review if the same happens in the openapi part. We still need to do a refactor to bring that to a common ground. Cheers

jemacineiras avatar Sep 13 '23 07:09 jemacineiras

After a small review, the regex was ok, problem came about how we were solving the reference. It found the same element always, the parameter definition, so start to walk through the Ref every time. But I´m use this task to implement the support for parameters in the Stream Bridge implementation. If it fit your use case, please test it. Regarding traits I´ll leave it for another issue, if you don´t mind.

Cheers

jemacineiras avatar Sep 13 '23 14:09 jemacineiras

I've test it and it would work on the Stream Bridge. I suggest that this will be also added for producer and supplier. Traits for the topic are not really usefully for us. On spring and Kubernetes it is solved via configuration. Cheers

devNbis avatar Sep 14 '23 12:09 devNbis

Hi @devNbis,

Consumer and supplier is another war, base on how Spring Cloud Stream works, defining functions (beans) by topics in the configuration part... I need to investigate how parameters work in this environment. Cheers

jemacineiras avatar Sep 14 '23 12:09 jemacineiras

@jemacineiras There are 2 different ways, via config or annotation, on the consumer side there is a need for multiple parameters. Also things like retry and dead letter. From point of view a schema can't handle this because it depends on data and functionality.

@RetryableTopic(attempts = "2",
  include = {MyRetryException.class}, 
  topicSuffixingStrategy=TopicSuffixingStrategy.SUFFIX_WITH_INDEX_VALUE,
  backoff = @Backoff(delay = 1000, multiplier = 2, maxDelay = 50000))
@KafkaListener(topics = "test-topic-retry", groupId="myPojo-listener",
	 properties={"spring.json.value.default.type=de.n-bis.consuming.retry.kafka.MyPojo",
		    "spring.kafka.consumer.properties.partition.assignment.strategy=org.apache.kafka.clients.consumer.CooperativeStickyAssignor,org.apache.kafka.clients.consumer.StickyAssignor",
	 "spring.json.type.mapping=MyPojo:de.n-bis.consuming.retry.kafka.MyPojo",
	 "spring.kafka.listener.ack-mode=MAUAL",
	"spring.json.use.type.headersS=false",
	"spring.json.remove.type.headers=false",
	"spring.json.trusted.packages=*",
	"value.deserializer=org.springframework.kafka.support.serializer.ErrorHandlingDeserializer",
	"spring.message.value.parser=org.springframework.kafka.support.serializer.JsonDeserializer",
	"spring.deserializer.value.delegate.class=org.springframework.kafka.support.serializer.JsonDeserializer"
 }
				)
public void processMessage(ConsumerRecord<String, MyPojo> rec, Acknowledgment ack) {
}

When you need something like this it is very hard to use auto generated classes. But they are there and also @Configuration or @Bean annotations and they will be resolved on startup

devNbis avatar Sep 14 '23 12:09 devNbis

Hi @devNbis,

We have another issue to support Kafka Listeners, so we are gonna implement something for it. If you want to collaborate, please add here your expected behaviour.

Cheers

jemacineiras avatar Oct 30 '23 08:10 jemacineiras

Hi @jemacineiras , From my point of view there should only interfaces available for a consumer or producer so that everyone can implement the config when it is necessary. All auto generated Config files would lead to errors and when you generate code inside /target/generated-sources and use it. A property for generate config files could do the work also Cheers

devNbis avatar Nov 02 '23 12:11 devNbis