com.ibm.streamsx.topology.internal.streaminganalytics.RestUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.ibm.streamsx.topology.internal.streaminganalytics.RestUtils.java

Source

/*
# Licensed Materials - Property of IBM
# Copyright IBM Corp. 2016,2017  
 */
package com.ibm.streamsx.topology.internal.streaminganalytics;

import static com.ibm.streamsx.topology.internal.gson.GsonUtilities.jstring;
import static com.ibm.streamsx.topology.internal.streaminganalytics.VcapServices.getVCAPService;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import javax.xml.bind.DatatypeConverter;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AUTH;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.ibm.streamsx.topology.context.remote.RemoteContext;
import com.ibm.streamsx.topology.internal.context.remote.DeployKeys;

public class RestUtils {

    public static String getStatusURL(JsonObject credentials) {
        StringBuilder sb = new StringBuilder(500);
        sb.append(jstring(credentials, "rest_url"));
        sb.append(jstring(credentials, "status_path"));
        return sb.toString();
    }

    public static String getJobSubmitURL(JsonObject credentials, File bundle) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder(500);
        sb.append(jstring(credentials, "rest_url"));
        sb.append(jstring(credentials, "jobs_path"));
        sb.append("?");
        sb.append("bundle_id=");
        sb.append(URLEncoder.encode(bundle.getName(), StandardCharsets.UTF_8.name()));
        return sb.toString();
    }

    public static void checkInstanceStatus(CloseableHttpClient httpClient, JsonObject service)
            throws ClientProtocolException, IOException {
        final String serviceName = jstring(service, "name");
        final JsonObject credentials = service.getAsJsonObject("credentials");

        String url = getStatusURL(credentials);

        String apiKey = getAPIKey(credentials);

        HttpGet getStatus = new HttpGet(url);
        getStatus.addHeader(AUTH.WWW_AUTH_RESP, apiKey);

        JsonObject jsonResponse = getGsonResponse(httpClient, getStatus);

        RemoteContext.REMOTE_LOGGER.info("Streaming Analytics service (" + serviceName
                + "): instance status response:" + jsonResponse.toString());

        if (!"true".equals(jstring(jsonResponse, "enabled")))
            throw new IllegalStateException("Service is not enabled!");

        if (!"running".equals(jstring(jsonResponse, "status")))
            throw new IllegalStateException("Service is not running!");
    }

    public static String getAPIKey(JsonObject credentials) {
        String userid = jstring(credentials, "userid");
        String password = jstring(credentials, "password");

        String api_creds = userid + ":" + password;
        String apiKey = "Basic " + DatatypeConverter.printBase64Binary(api_creds.getBytes(StandardCharsets.UTF_8));
        return apiKey;
    }

    public static JsonObject getGsonResponse(CloseableHttpClient httpClient, HttpRequestBase request)
            throws IOException, ClientProtocolException {
        request.addHeader("accept", ContentType.APPLICATION_JSON.getMimeType());

        CloseableHttpResponse response = httpClient.execute(request);
        JsonObject jsonResponse;
        try {
            HttpEntity entity = response.getEntity();
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                final String errorInfo;
                if (entity != null)
                    errorInfo = " -- " + EntityUtils.toString(entity);
                else
                    errorInfo = "";
                throw new IllegalStateException(
                        "Unexpected HTTP resource from service:" + response.getStatusLine().getStatusCode() + ":"
                                + response.getStatusLine().getReasonPhrase() + errorInfo);
            }

            if (entity == null)
                throw new IllegalStateException("No HTTP resource from service");

            Reader r = new InputStreamReader(entity.getContent());
            jsonResponse = new Gson().fromJson(r, JsonObject.class);
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
        return jsonResponse;
    }

    /**
     * Submit an application bundle to execute as a job.
     */
    public static JsonObject postJob(CloseableHttpClient httpClient, JsonObject service, File bundle,
            JsonObject jobConfigOverlay) throws ClientProtocolException, IOException {

        final String serviceName = jstring(service, "name");
        final JsonObject credentials = service.getAsJsonObject("credentials");

        String url = getJobSubmitURL(credentials, bundle);

        HttpPost postJobWithConfig = new HttpPost(url);
        postJobWithConfig.addHeader("accept", ContentType.APPLICATION_JSON.getMimeType());
        postJobWithConfig.addHeader(AUTH.WWW_AUTH_RESP, getAPIKey(credentials));
        FileBody bundleBody = new FileBody(bundle, ContentType.APPLICATION_OCTET_STREAM);
        StringBody configBody = new StringBody(jobConfigOverlay.toString(), ContentType.APPLICATION_JSON);

        HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("sab", bundleBody)
                .addPart(DeployKeys.JOB_CONFIG_OVERLAYS, configBody).build();

        postJobWithConfig.setEntity(reqEntity);

        JsonObject jsonResponse = getGsonResponse(httpClient, postJobWithConfig);

        RemoteContext.REMOTE_LOGGER.info("Streaming Analytics service (" + serviceName + "): submit job response:"
                + jsonResponse.toString());

        return jsonResponse;
    }
}