Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.3k stars 1.96k forks source link

[BUG] Unable to create ASB subsctiption with azure-messaging-servicebus 7.16.0 #39853

Closed blackr1234 closed 5 months ago

blackr1234 commented 5 months ago

Issue description

With the latest version, 7.16.0, of azure-messaging-servicebus, I am not able to create subscription with admin client in a Spring Boot web app.


Project source code

Download project source code here: GitHub - blackr1234/spring-boot-servicebus-7.16.0-bug


Steps to reproduce

  1. Clone the project.
  2. Replace the ASB endpoint connection string in src/main/java/code/MyController.java.
  3. Perform a Maven build using mvn clean package.
  4. Go into the target folder and run java -jar spring-boot-servicebus-7.16.0-bug-1.0.0.jar.
  5. Execute curl localhost:8080/greet in a separate terminal.
  6. Observe logs for error and Azure Portal for any new subscription.

Notes:

  1. The topic must exist before the test begins.
  2. The subscription must NOT exist before the test begins.

Expected behavior

Using the same project, if we remove the overriding explicit version of azure-messaging-servicebus, it will use version 7.15.2.

With this version, it is able to create subscription using the same Java source code. No error is logged.

image


Error log

11:23:57.031 [http-nio-8080-exec-2] INFO  code.MyController (MyController.java:27) - Called /greet.
11:23:57.161 [http-nio-8080-exec-2] WARN  c.a.m.s.a.i.ServiceBusManagementSerializer (ClientLogger.java:524) - Could not find xmlns:(?<namespace>\w+)="http://schemas\.microsoft\.com/netservices/2010/10/servicebus/connect" in <?xml version='1.0' encoding='UTF-8'?><CreateSubscriptionBodyImpl><content><type>application/xml</type><subscriptionDescription><lockDuration>PT1M</lockDuration><requiresSession>false</requiresSession><defaultMessageTimeToLive>P10675199DT2H48M5.477S</defaultMessageTimeToLive><deadLetteringOnMessageExpiration>false</deadLetteringOnMessageExpiration><deadLetteringOnFilterEvaluationExceptions>true</deadLetteringOnFilterEvaluationExceptions><maxDeliveryCount>3</maxDeliveryCount><enableBatchedOperations>true</enableBatchedOperations><status>Active</status><autoDeleteOnIdle>PT5M</autoDeleteOnIdle><defaultRuleDescription><filter><sqlExpression>1=1</sqlExpression></filter><name>default-filter</name></defaultRuleDescription></subscriptionDescription></content></CreateSubscriptionBodyImpl>
11:23:59.164 [http-nio-8080-exec-2] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] (DirectJDKLog.java:175) - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: com.azure.core.exception.HttpResponseException: Status code 400, "<Error><Code>400</Code><Detail>The specified resource description is invalid. TrackingId:5321c713-a256-4aa4-9cb3-357ba8a474e3_G22, SystemTracker:xxxxxxxxx:Topic:existing-topic, Timestamp:2024-04-23T03:23:57</Detail></Error>"] with root cause
com.azure.messaging.servicebus.administration.implementation.models.ServiceBusManagementErrorException: Status code 400, "<Error><Code>400</Code><Detail>The specified resource description is invalid. TrackingId:5321c713-a256-4aa4-9cb3-357ba8a474e3_G22, SystemTracker:xxxxxxxxx:Topic:existing-topic, Timestamp:2024-04-23T03:23:57</Detail></Error>"
    at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
    at com.azure.core.implementation.MethodHandleReflectiveInvoker.invokeWithArguments(MethodHandleReflectiveInvoker.java:39)
    at com.azure.core.implementation.http.rest.ResponseExceptionConstructorCache.invoke(ResponseExceptionConstructorCache.java:53)
    at com.azure.core.implementation.http.rest.RestProxyBase.instantiateUnexpectedException(RestProxyBase.java:411)
    at com.azure.core.implementation.http.rest.SyncRestProxy.ensureExpectedStatus(SyncRestProxy.java:129)
    at com.azure.core.implementation.http.rest.SyncRestProxy.handleRestReturnType(SyncRestProxy.java:206)
    at com.azure.core.implementation.http.rest.SyncRestProxy.invoke(SyncRestProxy.java:82)
    at com.azure.core.implementation.http.rest.RestProxyBase.invoke(RestProxyBase.java:128)
    at com.azure.core.http.rest.RestProxy.invoke(RestProxy.java:97)
    at jdk.proxy2/jdk.proxy2.$Proxy105.putSync(Unknown Source)
    at com.azure.messaging.servicebus.administration.implementation.SubscriptionsImpl.putWithResponse(SubscriptionsImpl.java:349)
    at com.azure.messaging.servicebus.administration.ServiceBusAdministrationClient.lambda$createSubscriptionWithResponse$2(ServiceBusAdministrationClient.java:462)
    at com.azure.messaging.servicebus.administration.ServiceBusAdministrationClient.executeAndThrowException(ServiceBusAdministrationClient.java:1762)
    at com.azure.messaging.servicebus.administration.ServiceBusAdministrationClient.createSubscriptionWithResponse(ServiceBusAdministrationClient.java:461)
    at com.azure.messaging.servicebus.administration.ServiceBusAdministrationClient.createSubscription(ServiceBusAdministrationClient.java:396)
    at code.MyController.greet(MyController.java:31)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:925)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:830)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
    at java.base/java.lang.Thread.run(Thread.java:833)

Library versions


Environment

github-actions[bot] commented 5 months ago

@anuchandy @conniey @lmolkova

github-actions[bot] commented 5 months ago

Thank you for your feedback. Tagging and routing to the team member best able to assist.

anuchandy commented 5 months ago

Hi @blackr1234, thanks for reaching out. The upgrade of spring libraries to the latest azure-core-* and azure-messaging-servicebus for April cadence is yet to happen, this dependency conflict will be resolved once April release of all packages are completed.

At the moment you need to override the core packages at the top of your pom file

<dependencies>
    <dependency>
       <groupId>com.azure</groupId>
       <artifactId>azure-core</artifactId>
       <version>1.48.0</version> 
    </dependency>
    <dependency>
       <groupId>com.azure</groupId>
       <artifactId>azure-xml</artifactId>
       <version>1.0.0</version> 
    </dependency>
    <dependency>
       <groupId>com.azure</groupId>
       <artifactId>azure-core-amqp</artifactId>
       <version>2.9.3</version> 
    </dependency>
    <dependency>
       <groupId>com.azure</groupId>
       <artifactId>azure-messaging-servicebus</artifactId>
       <version>7.16.0</version>
    </dependency>
  …..
blackr1234 commented 5 months ago

Thanks a lot for your help @anuchandy . I've added those dependencies to override existing versions, now subscription creation is working fine.

I guess the key takeway here is, as a normal SDK user, it isn't a good practice (and it is risky) to manually override the version of individual Azure modules, or I may face compatibililty issues like azure-messaging-servicebus in this case, and instead, I should only be using different versions of spring-cloud-azure-stream-binder-servicebus?

anuchandy commented 5 months ago

Hi @blackr1234, glad that the workaround unblocked you. Yes, agree with you, it is a good practice not to pull individual dependencies in the application as it may cause dependency conflicts. If BOM or top-level library aggregating and aligning all dependency versions are available, we should delegate versioning to it. Aligning the dependencies manually was a workaround, which can be removed once all Azure SDK libraries and spring release followed by that, for this April cadence is complete.