com.examples.abelanav2.BucketNotificationServlet.java Source code

Java tutorial

Introduction

Here is the source code for com.examples.abelanav2.BucketNotificationServlet.java

Source

/*
 * Copyright 2015 Google, Inc. All Rights Reserved.
 *
 * 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 com.examples.abelanav2;

import com.google.api.client.http.HttpStatusCodes;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.stdimpl.GCacheFactory;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.gson.Gson;

import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheFactory;
import javax.cache.CacheManager;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * This class receives notifications from the GCS bucket, the Task Queue and the Image Resizer.
 */
public class BucketNotificationServlet extends HttpServlet {

    @Override
    public final void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
        // Decode the name and bucket of the notification
        BucketNotification notification;
        try {
            String jsonString = IOUtils.toString(req.getInputStream());
            notification = new Gson().fromJson(jsonString, BucketNotification.class);
        } catch (IOException e) {
            log("Failed to decode the notification: " + e.getMessage());
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }

        try {
            if (!req.getHeader("X-Goog-Channel-Token").equals(ConfigurationConstants.SECRET_NOTIF_TOKEN)) {
                resp.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN);
                return;
            }

            if (!req.getHeader("X-Goog-Resource-State").equals("exists")) {
                resp.getWriter().write("This is not a new photo addition.");
                resp.setStatus(HttpStatusCodes.STATUS_CODE_OK);
                return;
            }

            // Handle duplicated notifications, drop keys after 5 minutes
            Boolean inCache = false;
            Cache cache = null;
            try {
                CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
                Map<Object, Object> properties = new HashMap<>();
                properties.put(GCacheFactory.EXPIRATION_DELTA, TimeUnit.MINUTES.toSeconds(5));
                properties.put(MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT, true);
                cache = cacheFactory.createCache(properties);
                inCache = (Boolean) cache.get(notification.getName());
            } catch (CacheException e) {
                log("Failed to instantiate the Memcache, risk of duplicate notifications: " + e.getMessage());
            }

            if (inCache == null || !inCache) {
                // Add a new task to the queue
                Queue queue = QueueFactory.getDefaultQueue();
                queue.add(TaskOptions.Builder.withUrl("/notice/incoming-image")
                        .param("bucket", notification.getBucket()).param("name", notification.getName()));
                if (cache != null) {
                    cache.put(notification.getName(), true);
                }
                resp.getWriter().write("Task added to the queue");
                log("Task created for bucket " + notification.getBucket() + " and file " + notification.getName());
            } else {
                resp.getWriter().write("This is a duplicate notification");
                log("Duplicate notification for bucket " + notification.getBucket() + " and file "
                        + notification.getName());
            }
            resp.setStatus(HttpStatusCodes.STATUS_CODE_OK);

        } catch (IOException e) {
            log("Error while writing the response");
            resp.setStatus(HttpStatusCodes.STATUS_CODE_SERVER_ERROR);
        }
    }
}