com.cloudbees.api.BeesClientBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cloudbees-api-client-nodeps Show documentation
Show all versions of cloudbees-api-client-nodeps Show documentation
The CloudBees API Client library for Java (Third party dependencies shaded)
/*
* Copyright 2010-2011, CloudBees 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 com.cloudbees.api;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.params.HttpParams;
public class BeesClientBase {
Logger logger = Logger.getLogger(getClass().getSimpleName());
protected String format = "xml";
private String serverApiUrl = "http://localhost:8080/api";
private String api_key;
private String secret;
private String version = "1.0";
private String sigVersion = "1";
private boolean verbose = true;
private BeesClientConfiguration beesClientConfiguration;
public BeesClientBase(BeesClientConfiguration beesClientConfiguration ) {
if (beesClientConfiguration==null) {
throw new IllegalArgumentException("BeesClientConfiguration cannot be null");
}
this.beesClientConfiguration = beesClientConfiguration;
if (beesClientConfiguration.getServerApiUrl() != null) {
this.serverApiUrl = beesClientConfiguration.getServerApiUrl();
}
if (beesClientConfiguration.getApiKey() != null) {
this.api_key = beesClientConfiguration.getApiKey();
}
if (beesClientConfiguration.getSecret() != null) {
this.secret = beesClientConfiguration.getSecret();
}
if (beesClientConfiguration.getFormat() != null) {
this.format = beesClientConfiguration.getFormat();
}
if (beesClientConfiguration.getVersion() != null) {
this.version = beesClientConfiguration.getVersion();
}
}
public BeesClientBase(String serverApiUrl, String apiKey, String secret,
String format, String version) {
this(new BeesClientConfiguration( serverApiUrl, apiKey, secret, format, version ));
}
public boolean isVerbose() {
return verbose;
}
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
public String getRequestURL(String method, Map methodParams)
throws Exception {
return getRequestURL(method, methodParams, true);
}
public String getRequestURL(String method, Map methodParams, boolean asActionParam)
throws Exception {
HashMap urlParams = getDefaultParameters();
StringBuilder requestURL = getApiUrl(asActionParam ? null : method);
requestURL.append("?");
for (Map.Entry entry : methodParams.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
urlParams.put(key, value);
}
if(asActionParam)
urlParams.put("action", method);
String signature = calculateSignature(urlParams);
Iterator> it = urlParams.entrySet().iterator();
for (int i=0; it.hasNext(); i++) {
Map.Entry entry = it.next();
String key = entry.getKey();
String value = entry.getValue();
if (i > 0)
requestURL.append("&");
requestURL.append(URLEncoder.encode(key, "UTF-8"));
requestURL.append("=");
requestURL.append(URLEncoder.encode(value, "UTF-8"));
}
requestURL.append("&");
requestURL.append("sig");
requestURL.append("=");
requestURL.append(signature);
return requestURL.toString();
}
private String calculateSignature(Map entries) throws Exception
{
StringBuilder sigData = new StringBuilder();
ArrayList> sortedParams = new ArrayList>(entries.entrySet());
Collections.sort(sortedParams, new Comparator>(){
public int compare(Entry e1,
Entry e2) {
return e1.getKey().compareTo(e2.getKey());
}
});
for (Map.Entry entry : sortedParams) {
String key = entry.getKey();
String value = entry.getValue();
sigData.append(key);
sigData.append(value);
}
// append the signature
String signature = getSignature(sigData.toString(), secret);
return signature;
}
protected StringBuilder getApiUrl(String method) {
StringBuilder requestURL = new StringBuilder();
requestURL.append(serverApiUrl);
if(method != null)
{
requestURL.append("/");
requestURL.append(method);
}
return requestURL;
}
private HashMap getDefaultParameters() {
HashMap urlParams = new HashMap();
urlParams.put("format", format);
urlParams.put("v", version);
urlParams.put("api_key", api_key);
urlParams.put("timestamp", new Long(System.currentTimeMillis() / 1000)
.toString());
urlParams.put("sig_version", sigVersion);
return urlParams;
}
public static String getSignature(String data, String secret)
throws Exception {
String s = data + secret;
String sig = md5(s);
return sig;
}
public static String md5(String message) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md5.digest(message.getBytes("CP1252"));
StringBuffer hex = new StringBuffer();
for (int i = 0; i < md5Bytes.length; ++i) {
hex.append(Integer.toHexString((md5Bytes[i] & 0xFF) | 0x100)
.substring(1, 3));
}
return hex.toString();
} catch (NoSuchAlgorithmException e) {
} catch (UnsupportedEncodingException e) {
}
return null;
}
public String executeRequest(String url) throws Exception {
HttpClient httpClient = HttpClientHelper.createClient(this.beesClientConfiguration);
GetMethod getMethod = new GetMethod(url);
int code = httpClient.executeMethod(getMethod);
String response = getResponseString(getMethod.getResponseBodyAsStream());
if (code >= 300) {
processError(response, code);
}
return response;
}
private String getResponseString(InputStream ins) throws IOException {
StringBuffer response = new StringBuffer();
try {
InputStreamReader isr = new InputStreamReader(ins);
char[] chars = new char[1024];
int numRead = isr.read(chars, 0, chars.length);
while (numRead != -1) {
response.append(new String(chars, 0, numRead));
numRead = isr.read(chars, 0, chars.length);
}
} finally {
ins.close();
}
return response.toString();
}
public InputStream executeCometRequest(String url) throws Exception {
HttpClient httpClient = HttpClientHelper.createClient(this.beesClientConfiguration);
HttpParams params = httpClient.getParams();
params.setIntParameter(HttpConnectionParams.SO_TIMEOUT, 0);
GetMethod getMethod = new GetMethod(url);
int code = httpClient.executeMethod(getMethod);
if (code >= 300) {
processError(getResponseString(getMethod.getResponseBodyAsStream()), code);
}
return getMethod.getResponseBodyAsStream();
}
protected void processError(String response, int code) throws BeesClientException {
ErrorResponse er = new ErrorResponse();
er.errorCode = "" + code;
if (isVerbose())
er.message = response;
else
er.message = HttpStatus.getStatusText(code);
throw new BeesClientException(er);
}
protected void trace(String message)
{
if (verbose) {
System.out.println(message);
}
}
protected void traceResponse(String message)
{
if (verbose) System.out.println("xml response: " + message);
}
protected String executeUpload(String uploadURL, Map params,
Map files, UploadProgress writeListener)
throws Exception {
HashMap clientParams = getDefaultParameters();
clientParams.putAll(params);
PostMethod filePost = new PostMethod(uploadURL);
try {
ArrayList parts = new ArrayList();
int fileUploadSize = 0;
for (Map.Entry fileEntry : files.entrySet()) {
FilePart filePart = new FilePart(fileEntry.getKey(), fileEntry
.getValue());
parts.add(filePart);
fileUploadSize += filePart.length();
//TODO: file params are not currently included in the signature,
// we should hash the file contents so we can verify them
}
for (Map.Entry entry : clientParams.entrySet()) {
parts.add(new StringPart(entry.getKey(), entry.getValue()));
}
// add the signature
String signature = calculateSignature(clientParams);
parts.add(new StringPart("sig", signature));
ProgressUploadEntity uploadEntity = new ProgressUploadEntity(parts
.toArray(new Part[parts.size()]), filePost.getParams(),
writeListener, fileUploadSize);
filePost.setRequestEntity(uploadEntity);
HttpClient client = HttpClientHelper.createClient(this.beesClientConfiguration);
client.getHttpConnectionManager().getParams().setConnectionTimeout(
10000);
int status = client.executeMethod(filePost);
String response = getResponseString(filePost.getResponseBodyAsStream());
if (status == HttpStatus.SC_OK) {
trace("upload complete, response=" + response);
} else {
trace("upload failed, response=" + HttpStatus.getStatusText(status));
processError(response, status);
}
return response;
} finally {
filePost.releaseConnection();
}
}
class ProgressUploadEntity extends MultipartRequestEntity {
private UploadProgress listener;
long length;
public ProgressUploadEntity(Part[] parts, HttpMethodParams params,
UploadProgress listener, long length) {
super(parts, params);
this.listener = listener;
this.length = length;
}
@Override
public void writeRequest(OutputStream out) throws IOException {
WriteListenerOutputStream listenStream = new WriteListenerOutputStream(
out, listener, length);
super.writeRequest(listenStream);
}
}
class WriteListenerOutputStream extends OutputStream {
private OutputStream targetStream;
private long bytesWritten;
private boolean isClosed;
private long bytesToSend;
private UploadProgress writeListener;
public WriteListenerOutputStream(OutputStream targetStream,
UploadProgress writeListener, long length) {
super();
this.targetStream = targetStream;
this.writeListener = writeListener;
this.bytesToSend = length;
}
public void close() throws IOException {
isClosed = true;
targetStream.close();
}
public void flush() throws IOException {
targetStream.flush();
}
public void write(byte[] b, int off, int len) throws IOException {
targetStream.write(b, off, len);
trackBytesWritten(len);
}
public void write(byte[] b) throws IOException {
targetStream.write(b);
trackBytesWritten(b.length);
}
public void write(int b) throws IOException {
targetStream.write(b);
trackBytesWritten(1);
}
public boolean isClosed() {
return isClosed;
}
public long getBytesWritten() {
return bytesWritten;
}
private void trackBytesWritten(long count) {
bytesWritten += count;
if (writeListener != null) {
writeListener.handleBytesWritten(count, bytesWritten,
bytesToSend);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy