/*******************************************************************************
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2013,2014 by Peter Pilgrim, Addiscombe, Surrey, XeNoNiQUe UK
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU GPL v3.0
* which accompanies this distribution, and is available at:
* http://www.gnu.org/licenses/gpl-3.0.txt
*
* Developers:
* Peter Pilgrim -- design, development and implementation
* -- Blog: http://www.xenonique.co.uk/blog/
* -- Twitter: @peter_pilgrim
*
* Contributors:
*
*******************************************************************************/
package je7hb.jaxrs.basic;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* The type RestfulBookService
*
* @author Peter Pilgrim (peter)
*/
@Path("/async/books")
@Stateless
public class RestfulBookAsyncService {
private ExecutorService executor = Executors.newFixedThreadPool(2);
private List<Book> products = Arrays.asList(
new Book("Miguel De Cervantes", "Don Quixote"),
new Book("Daniel Defoe", "Robinson Crusoe"),
new Book("Jonathan Swift", "Gulliver's Travels"),
new Book("Mary Shelley", "Frankenstein"),
new Book("Charlotte Bronte", "Jane Eyre"));
// Replace with Lambdas in Java 8
class MyAsyncTask implements Runnable {
final private AsyncResponse asyncResponse;
public MyAsyncTask(AsyncResponse asyncResponse) {
this.asyncResponse = asyncResponse;
}
@Override
public void run() {
System.out.printf("%s.run() thread: [%s]\n",
getClass().getSimpleName(), Thread.currentThread());
final long SLEEP=500;
final int N=10;
asyncResponse.setTimeout( (N+1)*SLEEP, TimeUnit.MILLISECONDS );
System.out.printf("retrieve list asynchronously ");
try {
for (int j=0; j<N; ++j ) {
System.out.print(".");
System.out.flush();
Thread.sleep(SLEEP);
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(".\n");
StringBuffer buf = new StringBuffer();
for (Book b: products) { buf.append(b.title); buf.append('\n'); }
Response response = Response.ok(buf.toString()).build();
System.out.printf("sending data back now on thread: [%s]\n",
Thread.currentThread());
asyncResponse.resume(response);
}
}
@GET
@Produces(MediaType.TEXT_PLAIN)
public void getList( @Suspended AsyncResponse asyncResponse) {
System.out.printf("%s.getList() thread: [%s]\n",
getClass().getSimpleName(), Thread.currentThread());
executor.submit( new MyAsyncTask(asyncResponse));
}
@PostConstruct
public void acquireResource() {
System.out.println( this.getClass().getSimpleName()+"#acquireResource()" );
}
@PreDestroy
public void releaseResource() {
System.out.println( this.getClass().getSimpleName()+"#releaseResource()" );
}
static class Book {
public final String author;
public final String title;
Book(String author, String title) {
this.author = author;
this.title = title;
}
}
}