view common/core/src/main/java/com/redhat/thermostat/gateway/common/db/servlet/AbstractHttpHandlerHelper.java @ 281:fdd31cc5e164

Make Auth implementation more generic and improve structure of code Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-October/025347.html
author Miloslav Zezulka <mzezulka@redhat.com>
date Tue, 17 Oct 2017 11:11:23 +0200
parents
children
line wrap: on
line source

/*
 * Copyright 2012-2017 Red Hat, Inc.
 *
 * This file is part of Thermostat.
 *
 * Thermostat is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2, or (at your
 * option) any later version.
 *
 * Thermostat is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Thermostat; see the file COPYING.  If not see
 * <http://www.gnu.org/licenses/>.
 *
 * Linking this code with other modules is making a combined work
 * based on this code.  Thus, the terms and conditions of the GNU
 * General Public License cover the whole combination.
 *
 * As a special exception, the copyright holders of this code give
 * you permission to link this code with independent modules to
 * produce an executable, regardless of the license terms of these
 * independent modules, and to copy and distribute the resulting
 * executable under terms of your choice, provided that you also
 * meet, for each linked independent module, the terms and conditions
 * of the license of that module.  An independent module is a module
 * which is not derived from or based on this code.  If you modify
 * this code, you may extend this exception to your version of the
 * library, but you are not obligated to do so.  If you do not wish
 * to do so, delete this exception statement from your version.
 */

package com.redhat.thermostat.gateway.common.db.servlet;

import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
import com.redhat.thermostat.gateway.common.core.servlet.CommonQueryParams;
import com.redhat.thermostat.gateway.common.db.Pair;
import com.redhat.thermostat.gateway.common.util.HttpResponseExceptionHandler;
import com.redhat.thermostat.gateway.common.util.ServiceException;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;

public abstract class AbstractHttpHandlerHelper implements HttpHandlerHelper {

    private final String collectionName;
    private final HttpResponseExceptionHandler exceptionHandler = new HttpResponseExceptionHandler();

    public AbstractHttpHandlerHelper(String collectionName) {
        this.collectionName = collectionName;
        exceptionHandler
                .add(UnsupportedOperationException.class, ServiceException.MALFORMED_CLIENT_REQUEST)
                .add(ClassCastException.class, ServiceException.EXPECTED_JSON_ARRAY)
                .add(IOException.class, ServiceException.CANNOT_QUERY_REALMS_PROPERTY)
                .add(NullPointerException.class, ServiceException.UNEXPECTED_ERROR);
        addAllImplSpecificHandlers();
    }

    protected abstract List<Pair<Class<? extends Exception>, ServiceException>> getImplSpecificHandlers();

    private void addAllImplSpecificHandlers() {
        for (Pair<Class<? extends Exception>, ServiceException> pair : getImplSpecificHandlers()) {
            exceptionHandler.add(pair.getFirst(), pair.getSecond());
        }
    }

    protected String getCollectionName() {
        return collectionName;
    }

    @Override
    public final Response handleGetWithSystemID(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, CommonQueryParams params) {
        return handleGet(httpServletRequest, context, andSystemIdQuery(params.getQueries(), systemId), params);
    }

    @Override
    public final Response handleGetWithJvmID(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, String jvmId, CommonQueryParams params) {
        return handleGet(httpServletRequest, context, andSystemIdJvmIdQuery(params.getQueries(), systemId, jvmId), params);
    }

    @Override
    public final Response handleGet(HttpServletRequest httpServletRequest,
            ServletContext context, CommonQueryParams params) {
        return handleGet(httpServletRequest, context, params.getQueries(), params);
    }

    @Override
    public final Response handleGet(HttpServletRequest httpServletRequest,
            ServletContext context, String queries, CommonQueryParams params) {

        try {
            return handleGetImpl(getRealmAuthorizer(httpServletRequest), httpServletRequest, context, queries, params);
        } catch (Exception e) {
            return exceptionHandler.generateResponseForException(e);
        }
    }

    protected abstract Response handleGetImpl(RealmAuthorizer realmAuthorizer, 
            HttpServletRequest httpServletRequest, ServletContext context, 
            String queries, CommonQueryParams params) throws Exception;

    /*
     *  HTTP POST handling
     */
    @Override
    public final Response handlePostWithSystemID(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, boolean returnMetadata, String body) {
        return handlePost(httpServletRequest, context, systemId, null, returnMetadata, body);
    }

    @Override
    public final Response handlePostWithJvmID(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, String jvmId, boolean returnMetadata, String body) {
        return handlePost(httpServletRequest, context, systemId, jvmId, returnMetadata, body);
    }

    /*
     *  HTTP PUT handling
     */
    @Override
    public final Response handlePutWithSystemId(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, String queries, boolean metadata, String body) {
        return handlePut(httpServletRequest, context, systemId, null, queries, metadata, body);
    }

    @Override
    public final Response handlePutWithJvmId(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, String jvmId, String queries, boolean metadata, String body) {
        return handlePut(httpServletRequest, context, systemId, jvmId, queries, metadata, body);
    }

    @Override
    public final Response handlePut(HttpServletRequest httpServletRequest, ServletContext context,
            String systemId, String jvmId, String queries, boolean returnMetadata, String body) {

        try {
            return handlePutImpl(getRealmAuthorizer(httpServletRequest), context, systemId, jvmId,
                    queries, returnMetadata, body);
        } catch (Exception e) {
            return exceptionHandler.generateResponseForException(e);
        }
    }

    protected abstract Response handlePutImpl(RealmAuthorizer realmAuthorizer,
            ServletContext context, String systemId, String jvmId, String queries,
            boolean returnMetadata, String body) throws Exception;

    @Override
    public final Response handlePost(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, String jvmId,
            boolean returnMetadata, String body) {

        try {
            return handlePostImpl(getRealmAuthorizer(httpServletRequest),
                    context, systemId, jvmId, returnMetadata, body);
        } catch (Exception e) {
            return exceptionHandler.generateResponseForException(e);
        }
    }

    /*
     *  HTTP DELETE handling
     */
    @Override
    public final Response handleDeleteWithSystemID(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, String queries, boolean returnMetadata) {
        return handleDelete(httpServletRequest, context, andSystemIdQuery(queries, systemId), returnMetadata);
    }

    @Override
    public final Response handleDeleteWithJvmID(HttpServletRequest httpServletRequest,
            ServletContext context, String systemId, String jvmId, String queries, boolean returnMetadata) {
        return handleDelete(httpServletRequest, context,
                andSystemIdJvmIdQuery(queries, systemId, jvmId), returnMetadata);
    }

    protected abstract Response handlePostImpl(RealmAuthorizer realmAuthorizer,
            ServletContext context, String systemId, String jvmId,
            boolean returnMetadata, String body) throws Exception;

    @Override
    public final Response handleDelete(HttpServletRequest httpServletRequest,
            ServletContext context, String queries, boolean returnMetadata) {
        try {
            return handleDeleteImpl(getRealmAuthorizer(httpServletRequest), context, queries, returnMetadata);
        } catch (Exception e) {
            return exceptionHandler.generateResponseForException(e);
        }
    }

    protected abstract Response handleDeleteImpl(RealmAuthorizer realmAuthorizer,
            ServletContext context, String queries, boolean returnMetadata) throws Exception;

    /* Utility methods we do not want to expose to public API */
    protected abstract String andSystemIdQuery(final String originalQuery,
            final String systemId);

    protected abstract String andSystemIdJvmIdQuery(final String originalQuery,
            final String systemId, final String jvmId);

    protected final boolean isNullOrEmpty(final String s) {
        return s == null || s.isEmpty();
    }

    private RealmAuthorizer getRealmAuthorizer(HttpServletRequest httpServletRequest) {
        return (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
    }
}