blob: e0be291f7fc86c2274584ba8f4e502b48d0c1bb7 [file] [log] [blame]
// Copyright (C) 2017 The Android Open Source Project
//
// 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 com.googlesource.gerrit.plugins.its.jira.restapi;
import com.google.gson.Gson;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.ArrayUtils;
import org.eclipse.jgit.util.HttpSupport;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URL;
/**
* Jira Rest Client.
*/
public class JiraRestApi<T> {
private static final String BASE_PREFIX = "/rest/api/2";
private final URL baseUrl;
private final String auth;
private final Gson gson;
private final Class<T> classOfT;
private final String classPrefix;
private T data;
private int responseCode;
/**
* @param url jira url
* @param user username of the jira user
* @param pass password of the jira user
*/
JiraRestApi(URL url, String user, String pass, Class<T> classOfT,
String classPrefix) {
String auth = user + ":" + pass;
this.auth = new String(Base64.encodeBase64(auth.getBytes()));
this.baseUrl = url;
this.gson = new Gson();
this.classOfT = classOfT;
this.classPrefix = classPrefix;
}
public int getResponseCode() {
return responseCode;
}
/**
* Do a simple GET request. Object of type 'T' is returned containing the
* parsed JSON data
*
* @param passCode HTTP response code required to mark this GET as success
* @param failCodes HTTP response codes allowed and not fail on unexcepted
* response
* @throws IOException generated if unexpected failCode is returned
*/
public T doGet(String spec, int passCode, int[] failCodes)
throws IOException {
HttpURLConnection conn = prepHttpConnection(spec, false);
try {
if (validateResponse(conn, passCode, failCodes)) {
readIncomingData(conn);
}
return data;
} finally {
conn.disconnect();
}
}
public T doGet(String spec, int passCode) throws IOException {
return doGet(spec, passCode, null);
}
/**
* Do a simple POST request.
*/
public boolean doPost(String spec, String jsonInput, int passCode)
throws IOException {
HttpURLConnection conn = prepHttpConnection(spec, true);
try {
writePostData(jsonInput, conn);
return validateResponse(conn, passCode, null);
} finally {
conn.disconnect();
}
}
private HttpURLConnection prepHttpConnection(String spec,
boolean isPostRequest) throws IOException {
URL url = new URL(baseUrl, BASE_PREFIX + classPrefix + spec);
ProxySelector proxySelector = ProxySelector.getDefault();
Proxy proxy = HttpSupport.proxyFor(proxySelector, url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
conn.setRequestProperty("Authorization", "Basic " + auth);
conn.setRequestProperty("Content-Type", "application/json");
if (isPostRequest) {
conn.setRequestMethod("POST");
conn.setDoOutput(true);
} else {
conn.setRequestMethod("GET");
}
return conn;
}
/**
* Write the Read the returned data from the HTTP connection.
*/
private void writePostData(String postData, HttpURLConnection conn)
throws IOException {
if (postData != null) {
try (OutputStream os = conn.getOutputStream()) {
os.write(postData.getBytes());
os.flush();
}
}
}
/**
* Read the returned data from the HTTP connection.
*/
private void readIncomingData(HttpURLConnection conn) throws IOException {
try (InputStreamReader isr = new InputStreamReader(conn.getInputStream())) {
data = gson.fromJson(isr, classOfT);
}
}
/**
* Checks if the connection returned one of the provides pass or fail Codes.
* If not, an IOException exception is thrown. If it was part of the list,
* then the actual response code is returned. returns true if valid response
* is returned, otherwise false
*/
private boolean validateResponse(HttpURLConnection conn, int passCode,
int[] failCodes) throws IOException {
responseCode = conn.getResponseCode();
if (responseCode == passCode) {
return true;
}
if ((failCodes == null)
|| (!ArrayUtils.contains(failCodes, responseCode))) {
throw new IOException("Request failed");
}
return false;
}
}