com.jingtum.net.APIResource Maven / Gradle / Ivy
/*
* Copyright www.jingtum.com Inc.
*
* 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 com.jingtum.net;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.jingtum.JingtumMessage;
import com.jingtum.model.EffectCollection;
import com.jingtum.model.FinGate;
import com.jingtum.model.JingtumObject;
import com.jingtum.model.OrderBookResult;
import com.jingtum.model.PaymentCollection;
import com.jingtum.model.Wallet;
import com.jingtum.util.Utility;
import com.jingtum.exception.APIConnectionException;
import com.jingtum.exception.InvalidRequestException;
import com.jingtum.exception.APIException;
import com.jingtum.exception.AuthenticationException;
import com.jingtum.exception.ChannelException;
import com.jingtum.exception.FailedException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import javax.net.ssl.HttpsURLConnection;
/**
* @author jzhao
* @version 1.0
*/
/**
* Extends the abstract class when you need request anything from jingtum
*/
public abstract class APIResource extends JingtumObject {
private static final String VERSION_URL = String.format("/%s/accounts",FinGate.getInstance().getApiVersion());
/**
* URLEncoder charset
*/
public static final String CHARSET = "UTF-8";
/**
* Http request method:
* Get, Post and Delete
*/
public enum RequestMethod {
GET, POST, DELETE, POST_FORM
}
/**
* Gson object use to transform json string to Jingtum object
*/
public static final Gson GSON = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapter(Wallet.class, new WalletDeserializer())
.registerTypeAdapter(OrderBookResult.class, new OrderBookResultDeserializer())
.registerTypeAdapter(PaymentCollection.class, new PaymentCollectionDeserializer())
.registerTypeAdapter(EffectCollection.class, new EffectCollectionDeserializer())
.create();
/**
* Based on class name to built the string needed in URL
* @param clazz
* @return clazz
*/
private static String className(Class> clazz) {
String className = clazz.getSimpleName().toLowerCase().replace("$", " ");
if (className.equals("orderbook")){
className = "order_book";
}
else {
className = className.concat("s");
}
return className;
}
/**
* Built base URL
* @return class URL
*/
protected static String classURL() {
return FinGate.getInstance().getServer().concat(VERSION_URL);
}
/**
* @param param
* @return formed URL
*/
protected static String formatURL(String param){
return String.format("%s/%s/%s", FinGate.getInstance().getServer(),FinGate.getInstance().getApiVersion(), param);
}
/**
* @param clazz
* @param parm
* @return formed URL
* @throws InvalidRequestException
*/
protected static String formatURL(Class> clazz, String address, String parm) throws InvalidRequestException {
return String.format("%s/%s/%s%s", classURL(), address, className(clazz),parm);
}
/**
* Get http connection instance
* @param url
* @return conn
* @throws IOException
*/
private static java.net.HttpURLConnection createJingtumConnection(String url)
throws IOException {
URL jingtumURL = null;
HttpURLConnection conn;
jingtumURL = new URL(url);
if(url.startsWith("https")){
conn = (HttpsURLConnection)jingtumURL.openConnection();
}else{
conn = (HttpURLConnection) jingtumURL.openConnection();
}
conn.setConnectTimeout(30 * 1000);
conn.setReadTimeout(80 * 1000);
conn.setUseCaches(false);
return conn;
}
/**
* @param url
* @param query
* @return url
*/
private static String formatURL(String url, String query) {
if (query == null || query.isEmpty()) {
return url;
} else {
String separator = url.contains("?") ? "&" : "?";
return String.format("%s%s%s", url, separator, query);
}
}
/**
* Get a http Get request connection
* @param url
* @param query
* @return conn
* @throws IOException
* @throws APIConnectionException
*/
private static java.net.HttpURLConnection createGetConnection(
String url, String query) throws IOException, APIConnectionException {
String getURL = formatURL(url, query);
java.net.HttpURLConnection conn = createJingtumConnection(getURL);
conn.setRequestMethod(RequestMethod.GET.toString());
return conn;
}
/**
* Get a http delete connection
* @param url
* @param query
* @param method
* @return http connection
* @throws IOException
* @throws APIConnectionException
*/
private static java.net.HttpURLConnection createDeleteConnection(
String url, String query, APIResource.RequestMethod method) throws IOException, APIConnectionException {
java.net.HttpURLConnection conn = createJingtumConnection(url);
conn.setDoOutput(true);
conn.setRequestMethod(method.toString());
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Content-Length", String.valueOf(query.getBytes().length));
OutputStream output = null;
try {
output = conn.getOutputStream();
output.write(query.getBytes());
output.flush();
} finally {
if (output != null) {
output.close();
}
}
return conn;
}
/**
* Get a http post connection
* @param url
* @param query
* @return conn
* @throws IOException
* @throws APIConnectionException
*/
private static java.net.HttpURLConnection createPostConnection(
String url, String query, APIResource.RequestMethod method) throws IOException, APIConnectionException {
java.net.HttpURLConnection conn = createJingtumConnection(url);
conn.setDoOutput(true);
conn.setRequestMethod(RequestMethod.POST.toString());
if(method.equals(RequestMethod.POST)){
conn.setRequestProperty("Content-Type", "application/json");
}
conn.setRequestProperty("Content-Length", String.valueOf(query.getBytes().length));
OutputStream output = null;
try {
output = conn.getOutputStream();
output.write(query.getBytes());
output.flush();
} finally {
if (output != null) {
output.close();
}
}
return conn;
}
/**
* Error class
*/
private static class Error {
private String error_type;
private String error;
private String message;
private String r1_code;
private String r3_error_msg;
private String ra_error_msg;
private String ri_error_msg;
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
if (Utility.isNotEmpty(error_type)) {
sb.append("Error type: ");
sb.append(error_type);
sb.append("\n");
}
if (Utility.isNotEmpty(error) || Utility.isNotEmpty(error_type)) {
sb.append("\t ");
sb.append(JingtumMessage.ERROR_MESSAGE);
if(JingtumMessage.ACCOUNT_NOT_FOUND.equals(message)){
sb.append(JingtumMessage.INACTIVATED_ACCOUNT);
}
sb.append(message);
sb.append("\n");
}
if(Utility.isNotEmpty(r1_code)){
sb.append("\t ");
sb.append(JingtumMessage.ERROR_CODE);
sb.append(r1_code);
sb.append("\n");
}
if(Utility.isNotEmpty(r3_error_msg)){
sb.append("\t ");
sb.append(JingtumMessage.ERROR_MESSAGE);
sb.append(r3_error_msg);
sb.append("\n");
}
if(Utility.isNotEmpty(ra_error_msg)){
sb.append("\t ");
sb.append(JingtumMessage.ERROR_MESSAGE);
sb.append(ra_error_msg);
sb.append("\n");
}
if(Utility.isNotEmpty(ri_error_msg)){
sb.append("\t ");
sb.append(JingtumMessage.ERROR_MESSAGE);
sb.append(ri_error_msg);
sb.append("\n");
}
return sb.toString();
}
}
/**
* Get the response body, in jason format
* @param responseStream
* @return rBody
* @throws IOException
*/
private static String getResponseBody(InputStream responseStream)
throws IOException {
@SuppressWarnings("resource")
String rBody = new Scanner(responseStream, CHARSET)
.useDelimiter("\\A")
.next();
responseStream.close();
return rBody;
}
/**
* @param method
* @param url
* @param query
* @return JingtumResponse
* @throws APIConnectionException
*/
private static JingtumResponse makeURLConnectionRequest(
APIResource.RequestMethod method, String url, String query)
throws APIConnectionException {
java.net.HttpURLConnection conn = null;
try {
switch (method) {
case GET:
conn = createGetConnection(url, query);
break;
case POST:
case POST_FORM:
conn = createPostConnection(url, query, method);
break;
case DELETE:
conn = createDeleteConnection(url,query, method);
break;
default:
throw new APIConnectionException(
String.format(JingtumMessage.UNRECOGNIZED_HTTP_METHOD, method));
}
// trigger the request
int rCode = conn.getResponseCode();
String rBody = null;
if (rCode >= 200 && rCode < 300) {
rBody = getResponseBody(conn.getInputStream());
} else {
rBody = getResponseBody(conn.getErrorStream());
}
return new JingtumResponse(rCode, rBody);
} catch (IOException e) {
throw new APIConnectionException(
String.format(
JingtumMessage.SERVER_ERROR,
FinGate.getInstance().getServer(), e.getMessage()), e);
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
/**
* Build class instance from jason format http response
* @param method
* @param url
* @param params
* @param clazz
* @param
* @return class instance
* @throws AuthenticationException
* @throws InvalidRequestException
* @throws APIConnectionException
* @throws APIException
* @throws FailedException
*/
protected static T request(APIResource.RequestMethod method, String url, String params, Class clazz) throws AuthenticationException,
InvalidRequestException, APIConnectionException,ChannelException,APIException, FailedException {
JingtumResponse response;
try {
response = makeURLConnectionRequest(method, url, params);
} catch (ClassCastException ce) {
throw ce;
}
int rCode = response.getResponseCode();
String rBody = response.getResponseBody();
if (rCode < 200 || rCode >= 300) {
handleAPIError(rBody, rCode, params);
}
return GSON.fromJson(rBody, clazz);
}
/**
* Error handling
* @param rBody
* @param rCode
* @throws InvalidRequestException
* @throws AuthenticationException
* @throws APIException
* @throws FailedException
*/
private static void handleAPIError(String rBody, int rCode, String query)
throws InvalidRequestException, AuthenticationException,
APIException, ChannelException, FailedException {
APIResource.Error error;
switch (rCode) {
case 400:
error = GSON.fromJson(rBody,
APIResource.Error.class);
throw new InvalidRequestException(error.toString(), query, null);
case 404:
error = GSON.fromJson(rBody,
APIResource.Error.class);
throw new InvalidRequestException(error.toString(), query, null);
case 403:
error = GSON.fromJson(rBody,
APIResource.Error.class);
throw new ChannelException(error.toString(), query, null);
case 401:
error = GSON.fromJson(rBody,
APIResource.Error.class);
throw new AuthenticationException(error.toString());
case 500:
error = GSON.fromJson(rBody,
APIResource.Error.class);
throw new FailedException(error.toString());
default:
throw new APIException(rBody.toString(),null);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy