quarkiverse / quarkus-cxf

Quarkus CXF Extension to support SOAP based web services.
Apache License 2.0
77 stars 60 forks source link

Need Support for Async implimentation for SOAP calls. #636

Open sreekar12 opened 1 year ago

sreekar12 commented 1 year ago

SOAP calls are not accepting as Uni as return type. Could you please help us any approach to make SOAP calls as Async.

For now i was using return type as Java class instead of Uni. For converting Uni to Java class i was using join() OR get().

Note: Join() and get() blocks until it gives response.

Could you please suggest any approach instead of above note....

shumonsharif commented 1 year ago

@sreekar12 Not sure if it may be helpful, but have a look at the code posted here: https://github.com/quarkiverse/quarkus-cxf/issues/4#issuecomment-1106487964

sreekar12 commented 1 year ago

@shumonsharif How to extract an object from Uni without blocking method (ex: Without join() or get())

shumonsharif commented 1 year ago

Hi @sreekar12 - Your question is unrelated to the extension, but I believe you may be able to find some answers on SO, for example here.

tbkahuna48 commented 1 year ago

@shumonshariff Sorry, some additional context may help. The code is attempting to make several asynchronous parallel backend calls and aggregate the results. The current cxf SOAP implementation seems to require a join on the completion stages which is a blocking implementation. So the question is , how can the calls be made without blocking. Sreekar referred to Uni because most quarkus extensions work with Unis, the question though is how can the SOAP calls be made in parallel in a non-blocking way. This is specific to CXF SOAP as it is , among the many other implementations of parallel asynchronous calls using quarkus extension libraries, the only we as yet aren't able to figure out how to make in a non-blocking manner. bryan.g.mclane@kp.org

linktech1 commented 1 year ago

Here's another description of the problem. The Quarkus CXF extension does not currently support asynchronous response types in the service interface and need to convert async types (Uni, Completion or Future) to standard response types. This conversion results in the async type to block until backside responses are returned.

linktech1 commented 1 year ago

I tried using the @UseAsyncMethod annotation, https://cxf.apache.org/javadoc/latest-3.2.x/org/apache/cxf/annotations/UseAsyncMethod.html

The async methods I have implemented per the link above are not called. If the async methods were called I would also expect them to be called on the event-loop-thread

@WebService(endpointInterface = "io.quarkiverse.cxf.it.server.GreetingWebService", serviceName = "GreetingWebService")
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public class GreetingWebServiceImpl implements GreetingWebService {

    private static final Logger LOG = LoggerFactory.getLogger(GreetingWebServiceImpl.class);

    @Inject
    HelloBean helloResource;

    @Override
    @UseAsyncMethod
    public String reply(@WebParam(name = "text") String text) {
        LOG.info("Calling reply ");
        return helloResource.getHello() + text;
    }

    @Override
    @UseAsyncMethod
    public String ping(@WebParam(name = "text") String text) throws GreetingException {
        if (text.equals("error")) {
            throw new GreetingException("foo", "bar");
        }
        LOG.info("Calling reply ");
        return helloResource.getHello() + text;
    }

    public Future<?> replyAsync(@WebParam(name = "text") String text,
            final AsyncHandler<GreetMeSometimeResponse> asyncHandler) {
        LOG.info("Calling replyAsync ");

        final ServerAsyncResponse<GreetMeSometimeResponse> response = new ServerAsyncResponse<GreetMeSometimeResponse>();
        GreetMeSometimeResponse tempResponse = new GreetMeSometimeResponse("Hello " + text);
        tempResponse.setResponseType(text);

        response.set(tempResponse);
        return response;
    }

    public Future<?> pingAsync(@WebParam(name = "text") String text,
            final AsyncHandler<GreetMeSometimeResponse> asyncHandler) throws GreetingException {
        LOG.info("Calling pingAsync ");
        if (text.equals("error")) {
            throw new GreetingException("foo", "bar");
        }
        final ServerAsyncResponse<GreetMeSometimeResponse> response = new ServerAsyncResponse<GreetMeSometimeResponse>();
        GreetMeSometimeResponse tempResponse = new GreetMeSometimeResponse("Hello " + text);
        tempResponse.setResponseType(text);
        response.set(tempResponse);
        return response;
    }

}
shumonsharif commented 1 year ago

@shumonshariff Sorry, some additional context may help. The code is attempting to make several asynchronous parallel backend calls and aggregate the results. The current cxf SOAP implementation seems to require a join on the completion stages which is a blocking implementation. So the question is , how can the calls be made without blocking. Sreekar referred to Uni because most quarkus extensions work with Unis, the question though is how can the SOAP calls be made in parallel in a non-blocking way. This is specific to CXF SOAP as it is , among the many other implementations of parallel asynchronous calls using quarkus extension libraries, the only we as yet aren't able to figure out how to make in a non-blocking manner. bryan.g.mclane@kp.org

@tbkahuna48 Did you or Sreekar look at the example provided in my first comment? That example demonstrates exactly what you are describing? In case it doesn't address your use cases appropriately, could you kindly provide a small reproducer that shows the issue you are facing?

shumonsharif commented 1 year ago

I tried using the @UseAsyncMethod annotation, https://cxf.apache.org/javadoc/latest-3.2.x/org/apache/cxf/annotations/UseAsyncMethod.html

The async methods I have implemented per the link above are not called. If the async methods were called I would also expect them to be called on the event-loop-thread

@linktech1 The @UseAsyncMethod as I understand is for CXF service providers, not consumers. Are you all trying to consume a web service (that's the impression I get from all the comments by @sreekar12 and @tbkahuna48) or provide a CXF service for others to consume?

I don't believe we've ever tested the @UseAsyncMethod successfully - in any case, I believe it's is a separate issue from what is being discussed here - would you mind opening a new issue and attaching a small reproducer?

linktech1 commented 1 year ago

Yes. We are providing a service that calls other services. We have the the backend service clients being called asynchronously (they return Futures) but we also want the frontside service implementation to also be non-blocking. Looking for the same support as the Quarkus Rest services where the service is completely non-blocking and runs entirely on the vertex-event-loop.

linktech1 commented 1 year ago

Anything on Quarkus CXF supporting service provider interfaces with non-blocking async behavior that runs on the vertex-io-thread?

shumonsharif commented 1 year ago

@linktech1 I haven't had much time to look into this, and likely won't any time soon ... My take is that this is going to be a fairly major effort, and I don't believe the JAX-WS spec will allow us to mimic the same features / patterns as the Quarkus REST services. We may at most be able to possibly integrate the @UseAsyncMethod functionality offered in CXF.

@ppalaga @famod Any thoughts on this issue?

linktech1 commented 1 year ago

I think the @UseAsyncMethod feature would work if the event-loop-thread is used. Async should be disabled if Quarkus detects other blocking code.

ppalaga commented 1 year ago

Thanks for reaching out, @sreekar12, @linktech1 and @tbkahuna48.

Would adding a proper support for @UseAsyncMethod solve your needs?

linktech1 commented 1 year ago

The requirement is to enable Quarkus reactive capability and not spin up any additional worker threads (run on the event loop) if the operation flow is non blocking. It looks like the current implementation creates a new Thread for the ServerAsyncResponse in this example: https://cxf.apache.org/javadoc/latest/org/apache/cxf/annotations/UseAsyncMethod.html

We would like to see a Uni or CompletionStage be used to be consistent with Quarkus reactive return types.

Cheers,

Keith Link @.***

On Aug 9, 2023, at 4:03 PM, Peter Palaga @.***> wrote:

Thanks for reaching out, @sreekar12 https://github.com/sreekar12, @linktech1 https://github.com/linktech1 and @tbkahuna48 https://github.com/tbkahuna48.

Would adding a proper support for @UseAsyncMethod solve your needs?

— Reply to this email directly, view it on GitHub https://github.com/quarkiverse/quarkus-cxf/issues/636#issuecomment-1672068183, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADSXQG547UTTM5ZGJR6XTXTXUPUI3ANCNFSM6AAAAAASVYY6DA. You are receiving this because you were mentioned.