com.joyent.manta.http.MantaHttpRequestFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.joyent.manta.http.MantaHttpRequestFactory.java

Source

/*
 * Copyright (c) 2017, Joyent, Inc. All rights reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package com.joyent.manta.http;

import com.joyent.manta.config.AuthAwareConfigContext;
import com.joyent.manta.exception.ConfigurationException;
import com.joyent.manta.exception.MantaClientException;
import org.apache.commons.lang3.Validate;
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpMessage;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.message.BasicHeader;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;

/**
 * Helper class for creating {@link org.apache.http.client.methods.HttpRequestBase} objects,
 * a.k.a. {@link org.apache.http.client.methods.HttpUriRequest}.
 */
public class MantaHttpRequestFactory {

    /**
     * Default HTTP headers to attach to all requests.
     */
    private static final Header[] HEADERS = { new BasicHeader(MantaHttpHeaders.ACCEPT_VERSION, "~1.0"),
            new BasicHeader(HttpHeaders.ACCEPT, "application/json, */*") };

    /**
     * Interceptor which attaches unique IDs to requests.
     */
    private static final RequestIdInterceptor INTERCEPTOR_REQUEST_ID = new RequestIdInterceptor();

    /**
     * Configuration helper to provide to {@link #authInterceptor} and from which to read a base URL.
     */
    private final AuthAwareConfigContext authConfig;

    /**
     * Interceptor for signing requests than can dynamically react to modifications in the provided configuration.
     */
    private final DynamicHttpSignatureRequestInterceptor authInterceptor;

    /**
     * The base url when {@link AuthAwareConfigContext} is not provided.
     */
    private final String url;

    /**
     * Build a new request factory based on an {@link AuthAwareConfigContext}.
     *
     * @param authConfig the config from which to extract base a base URL and to provide to the interceptor
     */
    public MantaHttpRequestFactory(final AuthAwareConfigContext authConfig) {
        this.authConfig = Validate.notNull(authConfig, "AuthAwareConfigContext must not be null");
        this.authInterceptor = new DynamicHttpSignatureRequestInterceptor(authConfig);
        this.url = null;
    }

    /**
     * Create an instance of the request factory based on the provided url and no authentication.
     *
     * @param url the base url
     */
    public MantaHttpRequestFactory(final String url) {
        this.authConfig = null;
        this.authInterceptor = null;
        this.url = Validate.notNull(url, "URL must not be null");
    }

    /**
     * Convenience method used for building DELETE operations.
     * @param path path to resource
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpDelete delete(final String path) {
        final HttpDelete request = new HttpDelete(uriForPath(path));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building DELETE operations.
     * @param path path to resource
     * @param params list of query parameters to use in operation
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpDelete delete(final String path, final List<NameValuePair> params) {
        final HttpDelete request = new HttpDelete(uriForPath(path, params));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building GET operations.
     * @param path path to resource
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpGet get(final String path) {
        final HttpGet request = new HttpGet(uriForPath(path));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building GET operations.
     * @param path path to resource
     * @param params list of query parameters to use in operation
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpGet get(final String path, final List<NameValuePair> params) {
        final HttpGet request = new HttpGet(uriForPath(path, params));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building HEAD operations.
     * @param path path to resource
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpHead head(final String path) {
        final HttpHead request = new HttpHead(uriForPath(path));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building HEAD operations.
     * @param path path to resource
     * @param params list of query parameters to use in operation
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpHead head(final String path, final List<NameValuePair> params) {
        final HttpHead request = new HttpHead(uriForPath(path, params));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building POST operations.
     * @param path path to resource
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpPost post(final String path) {
        final HttpPost request = new HttpPost(uriForPath(path));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building POST operations.
     * @param path path to resource
     * @param params list of query parameters to use in operation
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpPost post(final String path, final List<NameValuePair> params) {
        final HttpPost request = new HttpPost(uriForPath(path, params));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building PUT operations.
     * @param path path to resource
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpPut put(final String path) {
        final HttpPut request = new HttpPut(uriForPath(path));
        prepare(request);
        return request;
    }

    /**
     * Convenience method used for building PUT operations.
     * @param path path to resource
     * @param params list of query parameters to use in operation
     * @return instance of configured {@link org.apache.http.client.methods.HttpRequestBase} object.
     */
    public HttpPut put(final String path, final List<NameValuePair> params) {
        final HttpPut request = new HttpPut(uriForPath(path, params));
        prepare(request);
        return request;
    }

    /**
     * Apply default headers and interceptors to the new request.
     *
     * @param request request object to prepare
     */
    private void prepare(final HttpRequest request) {
        request.setHeaders(HEADERS);

        try {
            INTERCEPTOR_REQUEST_ID.process(request, null);

            if (authInterceptor != null) {
                authInterceptor.process(request, null);
            }
        } catch (HttpException | IOException e) {
            throw new MantaClientException("Failed to prepare request", e);
        }
    }

    /**
     * Add headers to an {@link org.apache.http.client.methods.HttpUriRequest}. Never copies the request ID header.
     * If reusing a request ID is desired (which it should never be) it will need to be done manually.
     *
     * @param httpMessage request to attach headers to
     * @param headers headers to attach
     */
    public static void addHeaders(final HttpMessage httpMessage, final Header... headers) {
        Validate.notNull(httpMessage, "HttpMessage must not be null");
        for (final Header header : headers) {
            if (MantaHttpHeaders.REQUEST_ID.equals(header.getName())) {
                continue;
            }

            httpMessage.addHeader(header);
        }
    }

    /**
     * Derives Manta URI for a given path.
     *
     * @param path full path
     * @return full URI as string of resource
     */
    protected String uriForPath(final String path) {
        Validate.notNull(path, "Path must not be null");

        final String format;
        if (path.startsWith("/")) {
            format = "%s%s";
        } else {
            format = "%s/%s";
        }

        final String baseURL;
        if (authConfig != null) {
            baseURL = authConfig.getMantaURL();
        } else {
            baseURL = url;
        }

        return String.format(format, baseURL, path);
    }

    /**
     * Derives Manta URI for a given path with the passed query
     * parameters.
     *
     * @param path full path
     * @param params query parameters to add to the URI
     * @return full URI as string of resource
     */
    protected String uriForPath(final String path, final List<NameValuePair> params) {
        Validate.notNull(path, "Path must not be null");
        Validate.notNull(params, "Params must not be null");

        try {
            final URIBuilder uriBuilder = new URIBuilder(uriForPath(path));
            uriBuilder.addParameters(params);
            return uriBuilder.build().toString();
        } catch (final URISyntaxException e) {
            throw new ConfigurationException(String.format("Invalid path in URI: %s", path));
        }
    }
}