DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • The Bill You Didn't See Coming
  • Jakarta EE Glossary: The Terms Every Java Engineer Should Actually Understand
  • Automating FastAPI Deployments With a GitHub Actions Pipeline
  • The Next Evolution of Java: Faster Innovation, Simpler Adoption

Trending

  • Closing the Drift Loop: An AI Agent That Drafts Terraform Fixes
  • AI Agents Need an Identity Plane: Rethinking Enterprise Authorization for Autonomous Software
  • Delta Lake UniForm to Snowflake: Cross-Platform Table Access Without a Second Copy
  • Google Cloud KMS vs. AWS KMS: Java Encryption Guide

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Testing, Deployment, and Maintenance
  3. DevOps and CI/CD
  4. CompletionStage Support in Server-Side JAX-RS

CompletionStage Support in Server-Side JAX-RS

JAX-RS 2.1 offers new support for asynchronous processing. Let's see how CompletionStage works with a sample app and a corresponding code breakdown.

By 
Abhishek Gupta
DZone Core CORE ·
Aug. 08, 17 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
9.4K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

JAX-RS 2.1 (part of Java EE 8) now supports returning a CompletionStage to mark a request as eligible for asynchronous processing. This is in addition to the AsyncResponse API, which has been available since JAX-RS 2.0 (Java EE 7)

Even the Client API has added support for reactive-style programming by providing support for CompletionStage API, but this blog will focus on the server-side support

The advantage this approach has over the AsyncResponse-based API is that it is richer and allows you to create asynchronous pipelines. Let’s look at an example — available on GitHub. It is simple and slightly contrived, but hopefully, it should help get the point across:

@Path("cabs")
public class CabBookingResource {

    @Resource
    ManagedExecutorService mes;

    @GET
    @Path("{id}")
    public CompletionStage<String> getCab(@PathParam("id") final String name) {
        System.out.println("HTTP request handled by thread " + Thread.currentThread().getName());

        final CompletableFuture<Boolean> validateUserTask = new CompletableFuture<>();

        CompletableFuture<String> searchDriverTask = validateUserTask.thenComposeAsync(
                new Function<Boolean, CompletionStage<String>>() {
            @Override
            public CompletionStage<String> apply(Boolean t) {

                System.out.println("User validated ? " + t);
                return CompletableFuture.supplyAsync(() -> searchDriver(), mes);
            }
        }, mes);
        final CompletableFuture<String> notifyUserTask = searchDriverTask.thenApplyAsync(
                (driver) -> notifyUser(driver), mes);

        mes.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    validateUserTask.complete(validateUser(name));
                } catch (Exception ex) {
                    Logger.getLogger(CabBookingResource.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

        return notifyUserTask;
    }

    boolean validateUser(String id) {
        System.out.println("searchDriverTask handled by thread " + Thread.currentThread().getName());
        System.out.println("validating user " + id);
        try {
            Thread.sleep(1500);
        } catch (InterruptedException ex) {
            Logger.getLogger(CabBookingResource.class.getName()).log(Level.SEVERE, null, ex);
        }
        return true;
    }

    String searchDriver() {
        System.out.println("searchDriverTask handled by thread " + Thread.currentThread().getName());

        try {
            Thread.sleep(2500);
        } catch (InterruptedException ex) {
            Logger.getLogger(CabBookingResource.class.getName()).log(Level.SEVERE, null, ex);
        }
        return "abhishek";
    }

    String notifyUser(String info) {
        System.out.println("searchDriverTask handled by thread " + Thread.currentThread().getName());

        return "Your driver is " + info + " and the OTP is " + (new Random().nextInt(999) + 1000);
    }


}


  • It starts with an HTTP GET to /booking/cabs/<user>, which invokes the getCab method:
    • The method returns a CompletionStage and returns immediately
    • The thread which served the request is now freed up
  • And then it's about creating the asynchronous pipeline:
    • We orchestrate the tasks for user validation and driver search using thenComposeAsync – this gives a CompletableFuture i.e. the searchDriverTask
    • We then supply a Function which takes the driver (returned by the above step) and invokes the notifyUser method – this is the CompletionStage which we actually return i.e. notifyUserTask – this is obviously executed later on, all we did was compose the sequence
  • Once the process is completed (delays are introduced using Thread.sleep()), the response is sent back to the user – internally, our CompletableFuture completes

To Run Using Docker

Refer to the README.

Further Reading

  • Java EE 8 blogs
  • JAX-RS eBook
Java EE API Requests Pipeline (software) Java (programming language) Driver (software) Blog Advantage (cryptography) GitHub IT

Published at DZone with permission of Abhishek Gupta. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • The Bill You Didn't See Coming
  • Jakarta EE Glossary: The Terms Every Java Engineer Should Actually Understand
  • Automating FastAPI Deployments With a GitHub Actions Pipeline
  • The Next Evolution of Java: Faster Innovation, Simpler Adoption

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook