patricklucas commented on issue #9700:
URL: https://github.com/apache/pulsar/issues/9700#issuecomment-786533307


   @WJL3333 I can confirm this happens calling the REST API directly too 
(output below). pulsar-manager proxies the request `PUT 
/admin/v2/persistent/${tenant}/${namespace}/${topic}/offload` directly from the 
frontend.
   
   Looking at Pulsar itself where this API is defined, at 
[PersistentTopics.java:2059](https://github.com/apache/pulsar/blob/v2.7.0/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/PersistentTopics.java#L2059),
 it's unclear to me where the method argument `MessageIdImpl messageId` comes 
from, which gets passed along to where the NPE occurs. It is not annotated with 
`@QueryParam`, and I'm not sure if any dependency injection would occur to 
populate it.
   
   _... a few moments later ..._
   
   Aha, I looked at how the `pulsar-admin` tool does this, and it seems that it 
does the work to determine the message ID, aborting if the topic has no data or 
there is no data to offload 
([CmdTopics.Offload](https://github.com/apache/pulsar/blob/v2.7.0/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdTopics.java#L889-L901)),
 else passing the message ID in the PUT body of the request.
   
   Assuming this is work the client has to do, I think there are two tasks here:
   - Add validation in the admin API to ensure the `messageId` parameter is 
non-null
   - Add code to pulsar-manager to determine the correct `messageId` to include 
in the request, and handling it gracefully when there is no data to offload
   
   I'd be happy to look into the first one, but I would leave the second to 
someone with more frontend/Vue experience. If you agree, I can open an issue on 
pulsar-manager.
   
   ```
   $ curl -v -X PUT 
localhost:6080/admin/v2/persistent/public/default/test/offload
   *   Trying ::1:6080...
   * connect to ::1 port 6080 failed: Connection refused
   *   Trying 127.0.0.1:6080...
   * Connected to localhost (127.0.0.1) port 6080 (#0)
   > PUT /admin/v2/persistent/public/default/test/offload HTTP/1.1
   > Host: localhost:6080
   > User-Agent: curl/7.75.0
   > Accept: */*
   > 
   * Mark bundle as not supporting multiuse
   < HTTP/1.1 500 Internal Server Error
   < Date: Fri, 26 Feb 2021 09:11:59 GMT
   < Content-Type: text/plain
   < Content-Length: 5897
   < Server: Jetty(9.4.33.v20201020)
   < 
   
    --- An unexpected error occurred in the server ---
   
   Message: null
   
   Stacktrace:
   
   java.lang.NullPointerException
           at 
org.apache.pulsar.broker.service.persistent.PersistentTopic.triggerOffload(PersistentTopic.java:2263)
           at 
org.apache.pulsar.broker.admin.impl.PersistentTopicsBase.internalTriggerOffload(PersistentTopicsBase.java:2976)
           at 
org.apache.pulsar.broker.admin.v2.PersistentTopics.triggerOffload(PersistentTopics.java:2061)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
           at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
           at java.lang.reflect.Method.invoke(Method.java:498)
           at 
org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
           at 
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
           at 
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
           at 
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:159)
           at 
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
           at 
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469)
           at 
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391)
           at 
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80)
           at 
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:253)
           at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
           at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
           at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
           at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
           at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
           at 
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
           at 
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)
           at 
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
           at 
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
           at 
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
           at 
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)
           at 
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)
           at 
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
           at 
org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:763)
           at 
org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1633)
           at 
org.apache.pulsar.broker.web.ResponseHandlerFilter.doFilter(ResponseHandlerFilter.java:58)
           at 
org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
           at 
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1609)
           at 
org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:561)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
           at 
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1612)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
           at 
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
           at 
org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
           at 
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1582)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
           at 
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
           at 
org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:234)
           at 
org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
           at 
org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:179)
           at 
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
           at org.eclipse.jetty.server.Server.handle(Server.java:516)
           at 
org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)
           at 
org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:556)
           at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)
           at 
org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)
           at 
org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
           at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
           at 
org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
           at 
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
           at 
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
           at 
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
           at 
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
           at 
org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:375)
           at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
           at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
           at 
io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
           at java.lang.Thread.run(Thread.java:748)
   * Connection #0 to host localhost left intact
   ```


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to