All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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