org.betaconceptframework.astroboa.console.security.ResourceApiProxy.java Source code

Java tutorial

Introduction

Here is the source code for org.betaconceptframework.astroboa.console.security.ResourceApiProxy.java

Source

/*
 * Copyright (C) 2005-2012 BetaCONCEPT Limited
 *
 * This file is part of Astroboa.
 *
 * Astroboa is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Astroboa 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Astroboa.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.betaconceptframework.astroboa.console.security;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.apache.commons.lang.StringUtils;
import org.betaconceptframework.astroboa.api.model.CmsRepository;
import org.betaconceptframework.astroboa.context.AstroboaClientContextHolder;
import org.betaconceptframework.astroboa.context.SecurityContext;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.util.Base64;
import org.jboss.resteasy.util.GenericType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Resource locator representing the main entry of all 
 * requests for one or more resources from a Astroboa repository.
 * 
 * This class is responsible to login to the provided repository id
 * and then to forward request to the appropriate sub resource.
 * 
 * @author Gregory Chomatas (gchomatas@betaconcept.com)
 * @author Savvas Triantafyllou (striantafyllou@betaconcept.com)
 * 
 */
@ApplicationPath("/")
@Path("/")
public class ResourceApiProxy {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @GET
    @PUT
    @POST
    @DELETE
    @Path("{resourceApiPath:.*}")
    @Produces("*/*")
    public Response dispatchToAstroboaRepository(@PathParam("resourceApiPath") String resourceApiPath,
            @Context UriInfo uriInfo, @Context HttpServletRequest httpServletRequest) {

        try {

            String repositoryId = AstroboaClientContextHolder.getActiveRepositoryId();
            if (StringUtils.isBlank(repositoryId)) {
                throw new WebApplicationException(HttpURLConnection.HTTP_NOT_FOUND);
            }

            CmsRepository activeCmsRepository = AstroboaClientContextHolder.getActiveCmsRepository();
            if (activeCmsRepository == null) {
                throw new WebApplicationException(HttpURLConnection.HTTP_NOT_FOUND);
            }

            SecurityContext securityContext = AstroboaClientContextHolder.getActiveSecurityContext();
            if (securityContext == null) {
                throw new WebApplicationException(HttpURLConnection.HTTP_NOT_FOUND);
            }

            String username = securityContext.getIdentity();

            if (StringUtils.isBlank(username)) {
                throw new WebApplicationException(HttpURLConnection.HTTP_NOT_FOUND);
            }

            String resourceApiBasePath = activeCmsRepository.getRestfulApiBasePath();

            if (StringUtils.isBlank(resourceApiBasePath)) {
                throw new WebApplicationException(HttpURLConnection.HTTP_NOT_FOUND);
            }

            HttpSession httpSession = httpServletRequest.getSession();
            String password = (String) httpSession.getAttribute("repositoryPassword");

            if (StringUtils.isBlank(password)) {
                throw new WebApplicationException(HttpURLConnection.HTTP_NOT_FOUND);
            }

            String httpMethod = httpServletRequest.getMethod();

            String requestPath = uriInfo.getPath();
            MultivaluedMap<String, String> queryParameters = uriInfo.getQueryParameters();

            ClientRequest request = new ClientRequest(
                    "http://localhost:8080" + resourceApiBasePath + "/" + repositoryId + requestPath);

            // read the payload if the http method is put or post
            if (httpMethod.equals("POST") || httpMethod.equals("PUT")) {
                request.body(httpServletRequest.getContentType(), getBody(httpServletRequest));
            }

            // add authorization header (BASIC AUTH)
            String basicAuthString = username + ":" + password;
            String authorization = "BASIC " + Base64.encodeBytes(basicAuthString.getBytes());
            request.header(HttpHeaders.AUTHORIZATION, authorization);

            // add headers
            Enumeration headerNames = httpServletRequest.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String headerName = (String) headerNames.nextElement();
                request.header(headerName, httpServletRequest.getHeader(headerName));
            }

            // add query parameters
            for (Map.Entry queryParamEntry : queryParameters.entrySet()) {
                String parameterValue = ((List<String>) queryParamEntry.getValue()).get(0);

                //ClientRequest (request) encodes the values before the execution of the request.
                //Therefore we need to decode the values before we feed them to the ClientRequest instance
                request.queryParameter((String) queryParamEntry.getKey(),
                        URLDecoder.decode(parameterValue, "UTF-8"));
            }

            String uri = request.getUri();

            ClientResponse clientResponse = request.httpMethod(httpMethod, new GenericType<InputStream>() {
            });

            return clientResponse;

        } catch (WebApplicationException e) {
            throw e;
        } catch (Exception e) {
            logger.error("A problem occured while sending request to Astroboa Repository", e);
            throw new WebApplicationException(HttpURLConnection.HTTP_INTERNAL_ERROR);
        }
    }

    private String getBody(HttpServletRequest httpServletRequest) throws Exception {

        BufferedReader bufferedReader = null;
        StringBuilder stringBuilder = new StringBuilder();

        try {
            bufferedReader = httpServletRequest.getReader();

            char[] buffer = new char[4 * 1024]; // 4 KB char buffer  

            int len;

            while ((len = bufferedReader.read(buffer, 0, buffer.length)) != -1) {
                stringBuilder.append(buffer, 0, len);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    throw e;
                }
            }
        }

        return stringBuilder.toString();
    }

}