org.springframework.ide.eclipse.boot.dash.ngrok.NGROKClient.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.boot.dash.ngrok.NGROKClient.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Pivotal Software, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Pivotal Software, Inc. - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.ngrok;

import java.io.IOException;
import java.net.URLEncoder;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Request;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 * @author Martin Lippert
 */
public class NGROKClient {

    private static int CREATE_TUNNEL_TIMEOUT_SECONDS = 6;

    private String path;

    private NGROKProcess process;
    private NGROKTunnel tunnel;

    public NGROKClient(String path) {
        this.path = path;

        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                if (process != null) {
                    process.terminate();
                }
            }
        }));
    }

    public NGROKTunnel getTunnel() {
        return tunnel;
    }

    public String getURL() {
        return process != null ? process.getApiURL() : null;
    }

    public NGROKTunnel startTunnel(String proto, String addr) throws Exception {
        process = NGROKProcess.startNGROK(path, proto, addr);
        if (process != null) {

            boolean success = false;
            int seconds = 0;

            while (!success && seconds < CREATE_TUNNEL_TIMEOUT_SECONDS) {
                NGROKTunnel[] tunnels = retrieveTunnels();
                if (tunnels != null && tunnels.length > 0) {
                    for (int i = 0; i < tunnels.length; i++) {
                        if (tunnels[i].getAddr().endsWith(addr) && tunnels[i].getProto().equals(proto)) {
                            tunnel = tunnels[i];
                            return tunnel;
                        }
                    }
                }
                seconds++;
                Thread.sleep(1000);
            }
        }

        return null;
    }

    public void shutdown() {
        if (tunnel != null) {
            shutdownTunnel(tunnel);
            tunnel = null;
        }

        if (process != null) {
            process.terminate();
            process = null;
        }
    }

    private NGROKTunnel[] retrieveTunnels() {
        NGROKTunnel[] result = null;
        try {
            String response = Request.Get(process.getApiURL() + "/api/tunnels").execute().returnContent()
                    .asString();

            JSONObject jsonResponse = new JSONObject(response);

            JSONArray tunnels = jsonResponse.getJSONArray("tunnels");
            if (tunnels != null) {
                result = new NGROKTunnel[tunnels.length()];
                for (int i = 0; i < result.length; i++) {
                    JSONObject tunnel = tunnels.getJSONObject(i);
                    String name = tunnel.getString("name");
                    String proto = tunnel.getString("proto");
                    String public_url = tunnel.getString("public_url");
                    String addr = tunnel.getJSONObject("config").getString("addr");

                    result[i] = new NGROKTunnel(name, proto, public_url, addr);
                }
            }
        } catch (Exception e) {
            System.out.println(e);
            // do nothing, might be the case that the ngrok process is not yet up
        }

        return result;
    }

    private void shutdownTunnel(NGROKTunnel ngrokTunnel) {
        try {
            String deleteURL = process.getApiURL() + "/api/tunnels/"
                    + URLEncoder.encode(ngrokTunnel.getName(), "UTF-8");
            HttpResponse response = Request.Delete(deleteURL).execute().returnResponse();
            if (response.getStatusLine().getStatusCode() != 204) {
                System.err.println("errro closing tunnel");
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}