org.apache.manifoldcf.crawler.connectors.jira.JiraSession.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.manifoldcf.crawler.connectors.jira.JiraSession.java

Source

/* $Id: JiraSession.java 1490586 2013-06-07 11:14:52Z kwright $ */
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You 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 org.apache.manifoldcf.crawler.connectors.jira;

import org.apache.manifoldcf.core.common.*;
import org.apache.manifoldcf.connectorcommon.common.*;
import org.apache.manifoldcf.connectorcommon.interfaces.KeystoreManagerFactory;
import org.apache.manifoldcf.core.interfaces.ManifoldCFException;

import java.io.Reader;
import java.io.Writer;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.manifoldcf.core.util.URLEncoder;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;

import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.config.SocketConfig;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultRedirectStrategy;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.protocol.HttpContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.client.AuthCache;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.ParseException;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.JSONArray;

/**
 *
 * @author andrew
 */
public class JiraSession {

    private final HttpHost host;
    private final String path;
    private final String clientId;
    private final String clientSecret;
    private String baseUrl;

    private HttpClientConnectionManager connectionManager;
    private HttpClient httpClient;

    // Current host name
    private static String currentHost = null;
    static {
        // Find the current host name
        try {
            java.net.InetAddress addr = java.net.InetAddress.getLocalHost();

            // Get hostname
            currentHost = addr.getHostName();
        } catch (java.net.UnknownHostException e) {
        }
    }

    /**
     * Constructor. Create a session.
     */
    public JiraSession(String clientId, String clientSecret, String protocol, String host, int port, String path,
            String proxyHost, int proxyPort, String proxyDomain, String proxyUsername, String proxyPassword)
            throws ManifoldCFException {
        this.host = new HttpHost(host, port, protocol);
        this.path = path;
        this.clientId = clientId;
        this.clientSecret = clientSecret;

        int socketTimeout = 900000;
        int connectionTimeout = 60000;

        javax.net.ssl.SSLSocketFactory httpsSocketFactory = KeystoreManagerFactory.getTrustingSecureSocketFactory();
        SSLConnectionSocketFactory myFactory = new SSLConnectionSocketFactory(
                new InterruptibleSocketFactory(httpsSocketFactory, connectionTimeout),
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        connectionManager = new PoolingHttpClientConnectionManager();

        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

        // If authentication needed, set that
        if (clientId != null) {
            credentialsProvider.setCredentials(AuthScope.ANY,
                    new UsernamePasswordCredentials(clientId, clientSecret));
        }

        RequestConfig.Builder requestBuilder = RequestConfig.custom().setCircularRedirectsAllowed(true)
                .setSocketTimeout(socketTimeout).setStaleConnectionCheckEnabled(true).setExpectContinueEnabled(true)
                .setConnectTimeout(connectionTimeout).setConnectionRequestTimeout(socketTimeout);

        // If there's a proxy, set that too.
        if (proxyHost != null && proxyHost.length() > 0) {

            // Configure proxy authentication
            if (proxyUsername != null && proxyUsername.length() > 0) {
                if (proxyPassword == null)
                    proxyPassword = "";
                if (proxyDomain == null)
                    proxyDomain = "";

                credentialsProvider.setCredentials(new AuthScope(proxyHost, proxyPort),
                        new NTCredentials(proxyUsername, proxyPassword, currentHost, proxyDomain));
            }

            HttpHost proxy = new HttpHost(proxyHost, proxyPort);
            requestBuilder.setProxy(proxy);
        }

        httpClient = HttpClients.custom().setConnectionManager(connectionManager).setMaxConnTotal(1)
                .disableAutomaticRetries().setDefaultRequestConfig(requestBuilder.build())
                .setDefaultSocketConfig(
                        SocketConfig.custom().setTcpNoDelay(true).setSoTimeout(socketTimeout).build())
                .setDefaultCredentialsProvider(credentialsProvider).setSSLSocketFactory(myFactory)
                .setRequestExecutor(new HttpRequestExecutor(socketTimeout))
                .setRedirectStrategy(new DefaultRedirectStrategy()).build();

    }

    /**
     * Close session.
     */
    public void close() {
        httpClient = null;
        if (connectionManager != null)
            connectionManager.shutdown();
        connectionManager = null;
    }

    private static Object convertToJSON(HttpResponse httpResponse) throws IOException {
        HttpEntity entity = httpResponse.getEntity();
        if (entity != null) {
            InputStream is = entity.getContent();
            try {
                Reader r = new InputStreamReader(is, getCharSet(entity));
                return JSONValue.parse(r);
            } finally {
                is.close();
            }
        }
        return null;
    }

    private static String convertToString(HttpResponse httpResponse) throws IOException {
        HttpEntity entity = httpResponse.getEntity();
        if (entity != null) {
            InputStream is = entity.getContent();
            try {
                char[] buffer = new char[65536];
                Reader r = new InputStreamReader(is, getCharSet(entity));
                Writer w = new StringWriter();
                try {
                    while (true) {
                        int amt = r.read(buffer);
                        if (amt == -1)
                            break;
                        w.write(buffer, 0, amt);
                    }
                } finally {
                    w.flush();
                }
                return w.toString();
            } finally {
                is.close();
            }
        }
        return "";
    }

    private static Charset getCharSet(HttpEntity entity) {
        Charset charSet;
        try {
            ContentType ct = ContentType.get(entity);
            if (ct == null)
                charSet = StandardCharsets.UTF_8;
            else
                charSet = ct.getCharset();
        } catch (ParseException e) {
            charSet = StandardCharsets.UTF_8;
        }
        return charSet;
    }

    private void getRest(String rightside, JiraJSONResponse response) throws IOException, ResponseException {

        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();
        // Generate BASIC scheme object and add it to the local
        // auth cache
        BasicScheme basicAuth = new BasicScheme();
        authCache.put(host, basicAuth);

        // Add AuthCache to the execution context
        HttpClientContext localContext = HttpClientContext.create();
        localContext.setAuthCache(authCache);

        final HttpRequestBase method = new HttpGet(host.toURI() + path + rightside);
        method.addHeader("Accept", "application/json");

        try {
            HttpResponse httpResponse = httpClient.execute(method, localContext);
            int resultCode = httpResponse.getStatusLine().getStatusCode();
            if (resultCode != 200)
                throw new IOException(
                        "Unexpected result code " + resultCode + ": " + convertToString(httpResponse));
            Object jo = convertToJSON(httpResponse);
            response.acceptJSONObject(jo);
        } finally {
            method.abort();
        }
    }

    /**
     * Obtain repository information.
     */
    public Map<String, String> getRepositoryInfo() throws IOException, ResponseException {
        HashMap<String, String> statistics = new HashMap<String, String>();
        JiraQueryResults qr = new JiraQueryResults();
        getRest("search?maxResults=1&jql=", qr);
        statistics.put("Total Issues", qr.getTotal().toString());
        return statistics;
    }

    /**
     * Get baseUrl via serverInfo API call
     * @return
     * @throws IOException
     * @throws ResponseException
     */
    public String getBaseUrl() throws IOException, ResponseException {
        if (this.baseUrl == null) {
            JiraServerInfo jiraServerInfo = new JiraServerInfo();
            getRest("serverInfo", jiraServerInfo);
            this.baseUrl = jiraServerInfo.getBaseUrl();
        }
        return this.baseUrl;
    }

    /**
     * Get the list of matching root documents, e.g. seeds.
     */
    public void getSeeds(XThreadStringBuffer idBuffer, String jiraDriveQuery)
            throws IOException, ResponseException, InterruptedException, ManifoldCFException {
        long startAt = 0L;
        long setSize = 800L;
        long totalAmt = 0L;
        do {
            JiraQueryResults qr = new JiraQueryResults();
            getRest("search?maxResults=" + setSize + "&startAt=" + startAt + "&jql="
                    + URLEncoder.encode(jiraDriveQuery), qr);
            Long total = qr.getTotal();
            if (total == null)
                return;
            totalAmt = total.longValue();
            qr.pushIds(idBuffer);
            startAt += setSize;
        } while (startAt < totalAmt);
    }

    /**
    * Get the list of users that can see the specified issue.
    */
    public List<String> getUsers(String issueKey) throws IOException, ResponseException, ManifoldCFException {
        List<String> rval = new ArrayList<String>();
        long startAt = 0L;
        long setSize = 800L;
        while (true) {
            JiraUserQueryResults qr = new JiraUserQueryResults();
            getRest("user/viewissue/search?username=&issueKey=" + URLEncoder.encode(issueKey) + "&maxResults="
                    + setSize + "&startAt=" + startAt, qr);
            qr.getNames(rval);
            startAt += setSize;
            if (rval.size() < startAt)
                break;
        }
        return rval;
    }

    /**
     * Get an individual issue.
     */
    public JiraIssue getIssue(String issueKey) throws IOException, ResponseException, ManifoldCFException {
        JiraIssue ji = new JiraIssue();
        getRest("issue/" + URLEncoder.encode(issueKey), ji);
        return ji;
    }

}