eu.redzoo.article.planetcassandra.reactive.service.completable.HotelService.java Source code

Java tutorial

Introduction

Here is the source code for eu.redzoo.article.planetcassandra.reactive.service.completable.HotelService.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.completable;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

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.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.MediaType;

import org.glassfish.jersey.client.rx.Rx;
import org.glassfish.jersey.client.rx.RxClient;
import org.glassfish.jersey.client.rx.java8.RxCompletionStageInvoker;
import org.imgscalr.Scalr;
import org.imgscalr.Scalr.Mode;

import net.oneandone.reactive.rest.container.ResultConsumer;
import net.oneandone.troilus.Dao;

import com.datastax.driver.core.ConsistencyLevel;
import com.google.common.io.Resources;

import eu.redzoo.article.planetcassandra.reactive.service.Hotel;
import eu.redzoo.article.planetcassandra.reactive.service.HotelRepresentation;

@Path("/hotels")
public class HotelService implements Closeable {

    private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    private final RxClient<RxCompletionStageInvoker> restClient = Rx.newClient(RxCompletionStageInvoker.class);

    private final byte[] defaultPicture;

    private final Dao hotelsDao;

    public HotelService(Dao hotelsDao) throws IOException {
        this.hotelsDao = hotelsDao;
        defaultPicture = Resources.toByteArray(Resources.getResource("error.jpg"));
    }

    @Override
    public void close() throws IOException {
        executor.shutdown();
    }

    @Path("/{id}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public void getHotelsAsync(@PathParam("id") String hotelId, @Suspended AsyncResponse resp) {

        hotelsDao.readWithKey("id", hotelId).asEntity(Hotel.class).withConsistency(ConsistencyLevel.QUORUM)
                .executeAsync()
                .thenApply(optionalHotel -> optionalHotel.<NotFoundException>orElseThrow(NotFoundException::new))
                .thenApply(hotel -> new HotelRepresentation(hotel.getId(), hotel.getName(), hotel.getRoomIds()))
                .whenComplete(ResultConsumer.writeTo(resp));
    }

    @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) {

        hotelsDao.readWithKey("id", hotelId).asEntity(Hotel.class).executeAsync()
                .thenApply(optionalHotel -> optionalHotel.<NotFoundException>orElseThrow(NotFoundException::new))
                .thenCompose(hotel -> restClient.target(hotel.getPictureUri()).request().rx().get(byte[].class)
                        .exceptionally(error -> defaultPicture))
                .thenApply(picture -> resize(picture, height, width, "png"))
                .whenComplete(ResultConsumer.writeTo(resp));
    }

    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);
        }
    }
}