co.cask.cdap.passport.http.client.PassportClient.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.passport.http.client.PassportClient.java

Source

/*
 * Copyright  2014 Cask Data, 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 co.cask.cdap.passport.http.client;

import co.cask.cdap.common.conf.Constants;
import co.cask.cdap.passport.meta.Account;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Client to communicate to the passport service.
 */

public class PassportClient {
    private static final Logger LOG = LoggerFactory.getLogger(PassportClient.class);
    private static Cache<String, String> responseCache = null;
    private static Cache<String, Account> accountCache = null;
    private final URI baseUri;
    private static final String API_BASE = "/api/";

    public PassportClient() {
        this(URI.create("http://localhost"));
    }

    private PassportClient(URI baseUri) {
        Preconditions.checkNotNull(baseUri);
        this.baseUri = baseUri;
        //Cache valid responses from Servers for 10 mins
        responseCache = CacheBuilder.newBuilder().maximumSize(10000).expireAfterAccess(10, TimeUnit.MINUTES)
                .build();
        accountCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(10, TimeUnit.MINUTES).build();
    }

    public static PassportClient create(String uri) {
        Preconditions.checkNotNull(uri);
        return new PassportClient(URI.create(uri));
    }

    /**
     * Get List of VPC for the apiKey.
     * @return List of VPC Names
     */
    public List<String> getVPCList(String apiKey) {
        Preconditions.checkNotNull(apiKey, "ApiKey cannot be null");
        List<String> vpcList = Lists.newArrayList();

        try {
            String data = responseCache.getIfPresent(apiKey);

            if (data == null) {
                data = httpGet(API_BASE + "vpc/list", apiKey);
                if (data != null) {
                    responseCache.put(apiKey, data);
                }
            }

            if (data != null) {
                JsonParser parser = new JsonParser();
                JsonElement element = parser.parse(data);
                JsonArray jsonArray = element.getAsJsonArray();

                for (JsonElement elements : jsonArray) {
                    JsonObject vpc = elements.getAsJsonObject();
                    if (vpc.get("vpc_name") != null) {
                        vpcList.add(vpc.get("vpc_name").getAsString());
                    }
                }
            }
        } catch (Exception e) {
            throw Throwables.propagate(e);
        }
        return vpcList;
    }

    /**
     * Get List of VPC for the apiKey.
     * @return Instance of {@code AccountProvider}
     * */
    public AccountProvider<Account> getAccount(String apiKey) {
        Preconditions.checkNotNull(apiKey, "ApiKey cannot be null");

        try {
            Account account = accountCache.getIfPresent(apiKey);
            if (account == null) {
                String data = httpGet(API_BASE + "whois", apiKey);
                if (data != null) {
                    Gson gson = new GsonBuilder()
                            .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
                    account = gson.fromJson(data, Account.class);
                    accountCache.put(apiKey, account);
                    return new AccountProvider<Account>(account);
                }
            } else {
                return new AccountProvider<Account>(account);
            }
            // This is a hack for overriding accountId type to String.
            // Ideally Account should use String type for account id instead
            return new AccountProvider<Account>(null);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private String httpGet(String api, String apiKey) {
        URI uri = URI.create(String.format("%s/%s/%s", baseUri.toASCIIString(), api, apiKey));
        HttpGet get = new HttpGet(uri);
        get.addHeader(Constants.Gateway.API_KEY, apiKey);
        return request(get);
    }

    private String request(HttpUriRequest uri) {
        LOG.trace("Requesting " + uri.getURI().toASCIIString());
        HttpClient client = new DefaultHttpClient();
        try {
            HttpResponse response = client.execute(uri);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException(
                        String.format("Call failed with status : %d", response.getStatusLine().getStatusCode()));
            }
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ByteStreams.copy(response.getEntity().getContent(), bos);
            return bos.toString("UTF-8");
        } catch (IOException e) {
            LOG.warn("Failed to retrieve data from " + uri.getURI().toASCIIString(), e);
            return null;
        } finally {
            client.getConnectionManager().shutdown();
        }
    }
}