eu.redzoo.article.planetcassandra.reactive.service.callback.ClassicHotelService.java Source code

Java tutorial

Introduction

Here is the source code for eu.redzoo.article.planetcassandra.reactive.service.callback.ClassicHotelService.java

Source

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package eu.redzoo.article.planetcassandra.reactive.service.callback;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;

import javax.imageio.ImageIO;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.InvocationCallback;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;

import org.imgscalr.Scalr;
import org.imgscalr.Scalr.Mode;

import net.oneandone.reactive.rest.client.RxClient;

import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.ResultSetFuture;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.google.common.io.Resources;

@Path("/classic/hotels")
public class ClassicHotelService {

    private final RxClient restClient = new RxClient(ClientBuilder.newClient());
    private final byte[] defaultPicture;

    private final Session session;
    private final PreparedStatement preparedSelectStmt;

    public ClassicHotelService(Session session) throws IOException {
        this.session = session;
        defaultPicture = Resources.toByteArray(Resources.getResource("error.jpg"));
        preparedSelectStmt = session.prepare(
                "select id, name, description, classification, picture_uri, room_ids from hotels where id = ?");
        preparedSelectStmt.setConsistencyLevel(ConsistencyLevel.QUORUM);
    }

    @Path("/{id}/thumbnail")
    @GET
    @Produces("image/png")
    public void getHotelThumbnailAsync(@PathParam("id") String hotelId,
            @PathParam("height") @DefaultValue("80") int height, @PathParam("width") @DefaultValue("80") int width,
            @Suspended AsyncResponse resp) {

        // (1) call the database
        ResultSetFuture databaseResponseFuture = session.executeAsync(preparedSelectStmt.bind(hotelId));
        databaseResponseFuture.addListener(new Runnable() {

            public void run() {
                try {
                    Row row = databaseResponseFuture.get().one();
                    if (row == null) {
                        resp.resume(new NotFoundException());

                    } else {

                        // (2) call the rest service to get the hotel picture
                        restClient.target(row.getString("picture_uri")).request().async()
                                .get(new InvocationCallback<byte[]>() {

                                    public void failed(Throwable throwable) {
                                        completed(defaultPicture);
                                    }

                                    public void completed(byte[] picture) {

                                        // (3) call the thumbnail library to reduce the  size
                                        try {
                                            byte[] thumbnail = resize(picture, height, width, "png");
                                            resp.resume(thumbnail);
                                        } catch (RuntimeException e) {
                                            resp.resume(e);
                                        }
                                    }
                                });

                    }
                } catch (ExecutionException | InterruptedException | RuntimeException e) {
                    resp.resume(e);
                }
            }
        }, ForkJoinPool.commonPool());
    }

    private byte[] resize(byte[] picture, int height, int width, String format) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            BufferedImage img = ImageIO.read(new ByteArrayInputStream(picture));
            BufferedImage scaledImg = Scalr.resize(img, Mode.AUTOMATIC, height, width);

            ImageIO.write(scaledImg, format, bos);
            return bos.toByteArray();
        } catch (IOException | RuntimeException e) {
            throw new RuntimeException(e);
        }
    }

}