io.apiman.gateway.platforms.vertx3.http.HttpApiFactory.java Source code

Java tutorial

Introduction

Here is the source code for io.apiman.gateway.platforms.vertx3.http.HttpApiFactory.java

Source

/*
 * Copyright 2014 JBoss Inc
 *
 * 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 io.apiman.gateway.platforms.vertx3.http;

import io.apiman.common.util.ApimanPathUtils;
import io.apiman.common.util.ApimanPathUtils.ApiRequestPathInfo;
import io.apiman.gateway.engine.IApiRequestPathParser;
import io.apiman.gateway.engine.beans.ApiRequest;
import io.apiman.gateway.engine.beans.ApiResponse;
import io.apiman.gateway.engine.beans.util.CaseInsensitiveStringMultiMap;
import io.apiman.gateway.engine.beans.util.HeaderMap;
import io.vertx.core.MultiMap;
import io.vertx.core.http.HttpClientResponse;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.http.HttpVersion;

import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Construct {@link ApiRequest} and {@link ApiResponse} objects from {@link HttpServerRequest},
 * {@link HttpServerResponse} and {@link HttpClientResponse}
 *
 * @author Marc Savy {@literal <msavy@redhat.com>}
 */
@SuppressWarnings("nls")
public class HttpApiFactory {

    private final static Set<String> IGNORESET = new HashSet<>();
    static {
        IGNORESET.add(ApimanPathUtils.X_API_VERSION_HEADER);
        IGNORESET.add("Host");
    }

    private static IApiRequestPathParser requestPathParser;

    public static void init(IApiRequestPathParser requestPathParser) {
        HttpApiFactory.requestPathParser = requestPathParser;
    }

    public static ApiResponse buildResponse(HttpClientResponse response, Set<String> suppressHeaders) {
        ApiResponse apimanResponse = new ApiResponse();
        apimanResponse.setCode(response.statusCode());
        apimanResponse.setMessage(response.statusMessage());
        multimapToMap(apimanResponse.getHeaders(), response.headers(), suppressHeaders);
        return apimanResponse;
    }

    public static void buildResponse(HttpServerResponse httpServerResponse, ApiResponse amanResponse,
            HttpVersion httpVersion) {
        amanResponse.getHeaders().forEach(e -> {
            if (httpVersion == HttpVersion.HTTP_1_0 || httpVersion == HttpVersion.HTTP_1_1
                    || !e.getKey().equals("Connection")) {
                httpServerResponse.headers().add(e.getKey(), e.getValue());
            }
        });
        httpServerResponse.setStatusCode(amanResponse.getCode());
        httpServerResponse.setStatusMessage(amanResponse.getMessage());
    }

    public static ApiRequest buildRequest(HttpServerRequest req, boolean isTransportSecure) {
        ApiRequest apimanRequest = new ApiRequest();
        apimanRequest.setApiKey(parseApiKey(req));
        apimanRequest.setRemoteAddr(req.remoteAddress().host());
        apimanRequest.setType(req.method().toString());
        apimanRequest.setTransportSecure(isTransportSecure);
        multimapToMap(apimanRequest.getHeaders(), req.headers(), IGNORESET);
        multimapToMap(apimanRequest.getQueryParams(), req.params(), Collections.<String>emptySet());
        parsePath(req, apimanRequest);
        return apimanRequest;
    }

    private static void parsePath(HttpServerRequest request, ApiRequest apimanRequest) {
        // NB: The apiman version of the headers has already been parsed, so the headers have already been filtered/modified.
        // Therefore we wrap the original inbound headers (just get) to efficiently access the necessary data.
        ApiRequestPathInfo parsedPath = requestPathParser.parseEndpoint(request.path(),
                wrapMultiMap(request.headers()));
        apimanRequest.setApiOrgId(parsedPath.orgId);
        apimanRequest.setApiId(parsedPath.apiId);
        apimanRequest.setApiVersion(parsedPath.apiVersion);
        apimanRequest.setUrl(request.absoluteURI());
        apimanRequest.setDestination(parsedPath.resource);
    }

    // TODO hacky...
    private static HeaderMap wrapMultiMap(MultiMap headers) {
        return new HeaderMap() {
            private static final long serialVersionUID = -1406124274678587935L;

            @Override()
            public String get(String key) {
                return headers.get(key);
            }
        };
    }

    private static void multimapToMap(CaseInsensitiveStringMultiMap map, MultiMap multimap,
            Set<String> suppressHeaders) {
        for (Map.Entry<String, String> entry : multimap) {
            if (!suppressHeaders.contains(entry.getKey())) {
                String key = entry.getKey();
                String val = entry.getValue();

                if (key != null && key.equalsIgnoreCase("accept") && val != null
                        && val.startsWith("application/apiman.")) { //$NON-NLS-1$
                    if (val.contains("+json")) { //$NON-NLS-1$
                        val = "application/json"; //$NON-NLS-1$
                    } else if (val.contains("+xml")) { //$NON-NLS-1$
                        val = "text/xml"; //$NON-NLS-1$
                    }
                }

                map.add(key, val);
            }
        }
    }

    private static String parseApiKey(HttpServerRequest req) {
        String headerKey = req.headers().get("X-API-Key");
        if (headerKey == null || headerKey.trim().length() == 0) {
            headerKey = req.getParam("apikey");
        }
        return headerKey;
    }
}