Java tutorial
/* * Copyright (C) 2015 Nu Development Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package com.nubits.nubot.trading.wrappers; import com.nubits.nubot.bot.Global; import com.nubits.nubot.exchanges.Exchange; import com.nubits.nubot.exchanges.ExchangeFacade; import com.nubits.nubot.global.Constant; import com.nubits.nubot.global.Settings; import com.nubits.nubot.models.*; import com.nubits.nubot.models.Currency; import com.nubits.nubot.trading.*; import com.nubits.nubot.trading.keys.ApiKeys; import com.nubits.nubot.utils.Utils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.HttpsURLConnection; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.NoRouteToHostException; import java.net.URL; import java.net.UnknownHostException; import java.util.*; public class CcedkWrapper implements TradeInterface { //Class fields private ApiKeys keys; protected CcedkService service; private Exchange exchange; private final int SPACING_BETWEEN_CALLS = 1100; private final int TIME_OUT = 15000; private long lastSentTonce = 0L; private static int offset = -1000000000; private String checkConnectionUrl = "http://www.ccedk.com"; private boolean apiBusy = false; private final String SIGN_HASH_FUNCTION = "HmacSHA512"; private final String ENCODING = "UTF-8"; private final String API_BASE_URL = "https://www.ccedk.com/api/v1/"; private final String API_GET_INFO = "balance/list"; //post private final String API_TRADE = "order/new"; //post private final String API_GET_TRADES = "trade/list"; //post private final String API_ACTIVE_ORDERS = "order/list"; private final String API_ORDER = "order/info"; private final String API_CANCEL_ORDER = "order/cancel"; private final String API_LAST_PRICE = "stats/marketdepthbtcav"; //For the ticker entry point, use getTicketPath(CurrencyPair pair) // Errors private ErrorManager errors = new ErrorManager(); private final String TOKEN_ERR = "errors"; private final String TOKEN_BAD_RETURN = "No Connection With Exchange"; private static final Logger LOG = LoggerFactory.getLogger(CcedkWrapper.class.getName()); private static final String INVALID_NONCE_ERROR = "Invalid Nonce value detected"; private static final int ROUND_CUTOFF = 99; private static int INVALID_NONCE_COUNT = 1; public CcedkWrapper(ApiKeys keys, Exchange exchange) { this.keys = keys; this.exchange = exchange; service = new CcedkService(keys); setupErrors(); } public String createNonce(String requester) { //This is a workaround waiting for clarifications from CCEDK team int lastdigit; String validNonce; int numericalNonce; String startvalid = " till"; int indexStart; int upperEdge; String nonceError; if (offset == -1000000000) { JSONParser parser = new JSONParser(); try { String htmlString = Utils.getHTML("https://www.ccedk.com/api/v1/currency/list?nonce=1234567891", false); //{"errors":{"nonce":"incorrect range `nonce`=`1234567891`, must be from `1411036100` till `1411036141`"} JSONObject httpAnswerJson = (JSONObject) (parser.parse(htmlString)); JSONObject errors = (JSONObject) httpAnswerJson.get("errors"); nonceError = (String) errors.get("nonce"); indexStart = nonceError.lastIndexOf(startvalid) + startvalid.length() + 2; upperEdge = Integer.parseInt(nonceError.substring(indexStart, indexStart + 10)); offset = upperEdge - (int) (System.currentTimeMillis() / 1000L); } catch (ParseException ex) { LOG.error(ex.toString()); } catch (IOException io) { LOG.error(io.toString()); } } if (offset != -1000000000) { numericalNonce = (int) (System.currentTimeMillis() / 1000L) + offset; validNonce = Objects.toString(numericalNonce); //LOG.warn("validNonce = " + validNonce); } else { LOG.error("Error calculating nonce"); validNonce = "1234567891"; } return validNonce; } private void setupErrors() { errors.setExchangeName(exchange); } private ApiResponse getQuery(String url, String method, HashMap<String, String> query_args, boolean needAuth, boolean isGet) { ApiResponse apiResponse = new ApiResponse(); String queryResult = query(url, method, query_args, needAuth, isGet); if (queryResult == null) { apiResponse.setError(errors.nullReturnError); return apiResponse; } if (queryResult.equals(TOKEN_BAD_RETURN)) { apiResponse.setError(errors.noConnectionError); return apiResponse; } if (queryResult.contains(INVALID_NONCE_ERROR)) { ApiError error = errors.genericError; error.setDescription(queryResult); apiResponse.setError(error); if (INVALID_NONCE_COUNT < 5) { getQuery(url, method, query_args, needAuth, isGet); INVALID_NONCE_COUNT++; } return apiResponse; } INVALID_NONCE_COUNT = 1; JSONParser parser = new JSONParser(); try { JSONObject httpAnswerJson = (JSONObject) (parser.parse(queryResult)); boolean hasErrors; try { hasErrors = (boolean) httpAnswerJson.get(TOKEN_ERR); } catch (ClassCastException e) { hasErrors = true; } if (hasErrors) { JSONObject errorMessage = (JSONObject) httpAnswerJson.get(TOKEN_ERR); ApiError apiErr = errors.apiReturnError; apiErr.setDescription(errorMessage.toJSONString()); LOG.error("Ccedk API returned an error: " + errorMessage); apiResponse.setError(apiErr); } else { apiResponse.setResponseObject(httpAnswerJson); } } catch (ClassCastException cce) { //if casting to a JSON object failed, try a JSON Array try { JSONArray httpAnswerJson = (JSONArray) (parser.parse(queryResult)); apiResponse.setResponseObject(httpAnswerJson); } catch (ParseException pe) { LOG.error("httpResponse: " + queryResult + " \n" + pe.toString()); apiResponse.setError(errors.parseError); } } catch (ParseException ex) { LOG.error("httpresponse: " + queryResult + " \n" + ex.toString()); apiResponse.setError(errors.parseError); return apiResponse; } return apiResponse; } @Override public ApiResponse getAvailableBalances(CurrencyPair pair) { return getBalanceImpl(null, pair); } @Override public ApiResponse getAvailableBalance(Currency currency) { return getBalanceImpl(currency, null); } private ApiResponse getBalanceImpl(Currency currency, CurrencyPair pair) { ApiResponse apiResponse = new ApiResponse(); String url = API_BASE_URL; String method = API_GET_INFO; boolean isGet = false; HashMap<String, String> query_args = new HashMap<>(); ApiResponse response = getQuery(url, method, query_args, true, isGet); if (response.isPositive()) { JSONObject httpAnswerJson = (JSONObject) response.getResponseObject(); JSONObject dataJson = (JSONObject) httpAnswerJson.get("response"); JSONArray entities = (JSONArray) dataJson.get("entities"); if (currency == null) { //Get all balances long NBTid = TradeUtilsCCEDK.getCCDKECurrencyId(pair.getOrderCurrency().getCode().toUpperCase()); long PEGid = TradeUtilsCCEDK.getCCDKECurrencyId(pair.getPaymentCurrency().getCode().toUpperCase()); Amount NBTAvail = new Amount(0, pair.getOrderCurrency()); Amount PEGAvail = new Amount(0, pair.getPaymentCurrency()); for (Iterator<JSONObject> entity = entities.iterator(); entity.hasNext();) { JSONObject thisEntity = entity.next(); long entityId = (Long) thisEntity.get("currency_id"); if (entityId == NBTid) { NBTAvail.setQuantity(Utils.getDouble(thisEntity.get("balance"))); } if (entityId == PEGid) { PEGAvail.setQuantity(Utils.getDouble(thisEntity.get("balance"))); } } //Get balance on Order by counting active orders ApiResponse activeOrdersResponse = getActiveOrders(pair); //Initialize Amounts double NBTonOrder = 0; double PEGonOrder = 0; Amount NBTOnOrderAmount = new Amount(NBTonOrder, pair.getOrderCurrency()); Amount PEGOnOrderAmount = new Amount(PEGonOrder, pair.getPaymentCurrency()); if (activeOrdersResponse.isPositive()) { ArrayList<Order> orderList = (ArrayList<Order>) activeOrdersResponse.getResponseObject(); for (int i = 0; i < orderList.size(); i++) { Order tempOrder = orderList.get(i); if (tempOrder.getType().equalsIgnoreCase(Constant.SELL)) { NBTonOrder += tempOrder.getAmount().getQuantity(); } else { PEGonOrder += tempOrder.getAmount().getQuantity() * tempOrder.getPrice().getQuantity(); } } NBTOnOrderAmount = new Amount(NBTonOrder, pair.getOrderCurrency()); PEGOnOrderAmount = new Amount(PEGonOrder, pair.getPaymentCurrency()); } else { return activeOrdersResponse; } PairBalance balance = new PairBalance(PEGAvail, NBTAvail, PEGOnOrderAmount, NBTOnOrderAmount); apiResponse.setResponseObject(balance); } else { //Specific currency requested long id = TradeUtilsCCEDK.getCCDKECurrencyId(currency.getCode().toUpperCase()); Amount total = new Amount(0, currency); for (Iterator<JSONObject> entity = entities.iterator(); entity.hasNext();) { JSONObject thisEntity = entity.next(); long entityId = (Long) thisEntity.get("currency_id"); if (entityId == id) { total.setQuantity(Utils.getDouble(thisEntity.get("balance"))); } } apiResponse.setResponseObject(total); } } else { apiResponse = response; } return apiResponse; } @Override public ApiResponse getLastPrice(CurrencyPair pair) { ApiResponse apiResponse = new ApiResponse(); String url = API_BASE_URL; String method = API_LAST_PRICE; HashMap<String, String> args = new HashMap<>(); boolean needAuth = false; boolean isGet = true; int pairId = TradeUtilsCCEDK.getCCDKECurrencyPairId(pair); args.put("pair_id", Integer.toString(pairId)); ApiResponse response = getQuery(url, method, args, needAuth, isGet); if (response.isPositive()) { JSONObject httpAnswerJson = (JSONObject) response.getResponseObject(); JSONObject dataJson = (JSONObject) httpAnswerJson.get("response"); JSONObject entity = (JSONObject) dataJson.get("entity"); Ticker ticker = new Ticker(0, 0, 0); ticker.setAsk(Utils.getDouble(entity.get("min_ask"))); ticker.setBid(Utils.getDouble(entity.get("max_bid"))); ticker.setLast(Utils.getDouble(entity.get("last_price"))); apiResponse.setResponseObject(ticker); } else { apiResponse = response; } return apiResponse; } @Override public ApiResponse sell(CurrencyPair pair, double amount, double rate) { return enterOrder(Constant.SELL.toLowerCase(), pair, amount, rate); } @Override public ApiResponse buy(CurrencyPair pair, double amount, double rate) { return enterOrder(Constant.BUY.toLowerCase(), pair, amount, rate); } private ApiResponse enterOrder(String type, CurrencyPair pair, double amount, double price) { ApiResponse apiResponse = new ApiResponse(); String url = API_BASE_URL; String method = API_TRADE; boolean isGet = false; boolean needAuth = true; HashMap<String, String> query_args = new HashMap<>(); query_args.put("pair_id", Integer.toString(TradeUtilsCCEDK.getCCDKECurrencyPairId(pair))); query_args.put("type", type); query_args.put("price", Double.toString(price)); query_args.put("amount", Double.toString(amount)); ApiResponse response = getQuery(url, method, query_args, needAuth, isGet); if (response.isPositive()) { JSONObject httpAnswerJson = (JSONObject) response.getResponseObject(); JSONObject dataJson = (JSONObject) httpAnswerJson.get("response"); JSONObject entity = (JSONObject) dataJson.get("entity"); Long order_id = (Long) entity.get("order_id"); apiResponse.setResponseObject(Long.toString(order_id)); } else { apiResponse = response; } return apiResponse; } @Override public ApiResponse getActiveOrders() { return getActiveOrdersImpl(null); } @Override public ApiResponse getActiveOrders(CurrencyPair pair) { return getActiveOrdersImpl(pair); } private ApiResponse getActiveOrdersImpl(CurrencyPair pair) { ApiResponse apiResponse = new ApiResponse(); ArrayList<Order> orderList = new ArrayList<Order>(); String url = API_BASE_URL; String method = API_ACTIVE_ORDERS; boolean isGet = false; ; HashMap<String, String> query_args = new HashMap<>(); if (pair != null) { String pair_id = Integer.toString(TradeUtilsCCEDK.getCCDKECurrencyPairId(pair)); query_args.put("pair_id", pair_id); } ApiResponse response = getQuery(url, method, query_args, true, isGet); if (response.isPositive()) { JSONObject httpAnswerJson = (JSONObject) response.getResponseObject(); JSONObject dataJson = (JSONObject) httpAnswerJson.get("response"); JSONArray entities = (JSONArray) dataJson.get("entities"); for (Iterator<JSONObject> entity = entities.iterator(); entity.hasNext();) { JSONObject orderObject = entity.next(); Order tempOrder = parseOrder(orderObject); if (!tempOrder.isCompleted()) //Do not add executed orders { orderList.add(tempOrder); } } apiResponse.setResponseObject(orderList); } else { apiResponse = response; } return apiResponse; } @Override public ApiResponse getOrderDetail(String orderID) { ApiResponse apiResponse = new ApiResponse(); ApiResponse getActiveOrders = getActiveOrders(); boolean found = false; if (getActiveOrders.isPositive()) { apiResponse.setResponseObject(false); ArrayList<Order> orderList = (ArrayList) getActiveOrders.getResponseObject(); for (Iterator<Order> order = orderList.iterator(); order.hasNext();) { Order thisOrder = order.next(); if (thisOrder.getId().equals(orderID)) { apiResponse.setResponseObject(thisOrder); found = true; break; } } if (!found) apiResponse.setError(errors.orderNotFound); } else { apiResponse = getActiveOrders; } return apiResponse; } @Override public ApiResponse cancelOrder(String orderID, CurrencyPair pair) { ApiResponse apiResponse = new ApiResponse(); String url = API_BASE_URL; String method = API_CANCEL_ORDER; boolean isGet = false; boolean needAuth = true; HashMap<String, String> query_args = new HashMap<>(); query_args.put("order_id", orderID); ApiResponse response = getQuery(url, method, query_args, needAuth, isGet); if (response.isPositive()) { apiResponse.setResponseObject(true); } else { apiResponse = response; } return apiResponse; } @Override public ApiResponse getTxFee() { return new ApiResponse(true, Global.options.getTxFee(), null); } @Override public ApiResponse getTxFee(CurrencyPair pair) { LOG.debug("CCEDK uses global TX fee, currency pair not supported." + "now calling getTxFee()"); return getTxFee(); } @Override public ApiResponse isOrderActive(String orderID) { ApiResponse apiResponse = new ApiResponse(); ApiResponse getActiveOrders = getActiveOrders(); if (getActiveOrders.isPositive()) { ArrayList<Order> orderList = (ArrayList) getActiveOrders.getResponseObject(); apiResponse.setResponseObject(false); for (Iterator<Order> order = orderList.iterator(); order.hasNext();) { Order thisOrder = order.next(); if (thisOrder.getId().equals(orderID)) { apiResponse.setResponseObject(true); } } } else { apiResponse = getActiveOrders; } return apiResponse; } @Override public ApiResponse clearOrders(CurrencyPair pair) { //Since there is no API entry point for that, this call will iterate over active ApiResponse apiResponse = new ApiResponse(); ArrayList<String> errorIds = new ArrayList<>(); ApiResponse activeOrdersResponse = getActiveOrders(); if (activeOrdersResponse.isPositive()) { apiResponse.setResponseObject(true); ArrayList<Order> orderList = (ArrayList) activeOrdersResponse.getResponseObject(); String errorString = ""; boolean ok = true; for (Iterator<Order> order = orderList.iterator(); order.hasNext();) { Order thisOrder = order.next(); if (!pair.equals(thisOrder.getPair())) { continue; } ApiResponse deleteOrderResponse = cancelOrder(thisOrder.getId(), null); if (deleteOrderResponse.isPositive()) { continue; } else { errorIds.add(thisOrder.getId()); } } if (!errorIds.isEmpty()) { ApiError error = errors.genericError; error.setDescription(errorIds.toString()); apiResponse.setError(error); apiResponse.setResponseObject(false); } } else { apiResponse = activeOrdersResponse; } return apiResponse; } @Override public ApiError getErrorByCode(int code) { return null; } @Override public String getUrlConnectionCheck() { return checkConnectionUrl; } @Override public String query(String base, String method, AbstractMap<String, String> args, boolean needAuth, boolean isGet) { String queryResult = TOKEN_BAD_RETURN; //Will return this string in case it fails if (exchange.getLiveData().isConnected()) { if (exchange.isFree()) { exchange.setBusy(); queryResult = service.executeQuery(base, method, args, needAuth, isGet); exchange.setFree(); } else { //Another thread is probably executing a query. Init the retry procedure long sleeptime = Settings.RETRY_SLEEP_INCREMENT * 1; int counter = 0; long startTimeStamp = System.currentTimeMillis(); LOG.debug(method + " blocked, another call is being processed "); boolean exit = false; do { counter++; sleeptime = counter * Settings.RETRY_SLEEP_INCREMENT; //Increase sleep time sleeptime += (int) (Math.random() * 200) - 100;// Add +- 100 ms random to facilitate competition LOG.debug( "Retrying for the " + counter + " time. Sleep for " + sleeptime + "; Method=" + method); try { Thread.sleep(sleeptime); } catch (InterruptedException e) { LOG.error(e.toString()); } //Try executing the call if (exchange.isFree()) { LOG.debug("Finally the exchange is free, executing query after " + counter + " attempt. Method=" + method); exchange.setBusy(); queryResult = service.executeQuery(base, method, args, needAuth, isGet); exchange.setFree(); break; //Exit loop } else { LOG.debug("Exchange still busy : " + counter + " .Will retry soon; Method=" + method); exit = false; } if (System.currentTimeMillis() - startTimeStamp >= Settings.TIMEOUT_QUERY_RETRY) { exit = true; LOG.error( "Method=" + method + " failed too many times and timed out. attempts = " + counter); } } while (!exit); } } else { LOG.error("The bot will not execute the query, there is no connection with" + exchange.getName()); queryResult = TOKEN_BAD_RETURN; } return queryResult; } private Order parseOrder(JSONObject orderObject) { Order order = new Order(); /* * "order_id":"1617","pair_id":"3", * "type":"sell","volume":"48.00000000", * "price":"9.50000000","fee":"0. 91200000", * "active":"1","created":"1406098537"} */ order.setId(Long.toString((Long) orderObject.get("order_id"))); long currencyPairID = (Long) orderObject.get("pair_id"); CurrencyPair cp = TradeUtilsCCEDK.getCCEDKPairFromID(currencyPairID); order.setPair(cp); order.setType(orderObject.get("type").toString()); order.setAmount(new Amount(Utils.getDouble(orderObject.get("volume")), cp.getOrderCurrency())); order.setPrice(new Amount(Utils.getDouble(orderObject.get("price")), cp.getPaymentCurrency())); long active = (Long) orderObject.get("active"); if (active == 0) { order.setCompleted(true); } else { order.setCompleted(false); } long created = (Long) orderObject.get("created") * 1000; order.setInsertedDate(new Date(created)); return order; } private Trade parseTrade(JSONObject orderObject) { //hotfix for Ben request //FilesystemUtils.writeToFile(orderObject.toJSONString(), "raw-trades.json", true); Trade trade = new Trade(); /* "id":<\d+> AS "trade_id", "pair_id":<\d+>, "type":<buy|sell>, "is_buyer":<0|1>, "is_seller":<0|1>, "price":<\d{1,8}\.d{0,8}>, "volume":<\d{1,8}\.d{0,8}>, "fee":<\d{1,8}\.d{0,8}>, "created":<\d{10}> */ trade.setId((String) orderObject.get("trade_id")); trade.setExchangeName(ExchangeFacade.CCEDK); int currencyPairID = Integer.parseInt((String) orderObject.get("pair_id")); CurrencyPair cp = TradeUtilsCCEDK.getCCEDKPairFromID(currencyPairID); trade.setPair(cp); trade.setType(orderObject.get("is_seller").equals("1") ? Constant.SELL : Constant.BUY); trade.setAmount(new Amount(Double.parseDouble((String) orderObject.get("volume")), cp.getOrderCurrency())); trade.setPrice(new Amount(Double.parseDouble((String) orderObject.get("price")), cp.getPaymentCurrency())); trade.setFee(new Amount(Double.parseDouble((String) orderObject.get("fee")), cp.getPaymentCurrency())); long date = Long.parseLong(((String) orderObject.get("created")) + "000"); trade.setDate(new Date(date)); return trade; } @Override public void setKeys(ApiKeys keys) { this.keys = keys; } @Override public void setExchange(Exchange exchange) { this.exchange = exchange; } @Override public void setApiBaseUrl(String apiBaseUrl) { throw new UnsupportedOperationException("Not supported yet."); } @Override public ApiResponse getLastTrades(CurrencyPair pair) { return getLastTradesImpl(pair, 0); } @Override public ApiResponse getLastTrades(CurrencyPair pair, long startTime) { return getLastTradesImpl(pair, startTime); } public ApiResponse getLastTradesImpl(CurrencyPair pair, long startTime) { ApiResponse apiResponse = new ApiResponse(); ArrayList<Trade> tradesList = new ArrayList<Trade>(); String url = API_BASE_URL; String method = API_GET_TRADES; boolean isGet = false; HashMap<String, String> query_args = new HashMap<>(); String pair_id = Integer.toString(TradeUtilsCCEDK.getCCDKECurrencyPairId(pair)); String startDateArg; if (startTime == 0) { long now = System.currentTimeMillis(); long yesterday = now - Utils.getOneDayInMillis(); startDateArg = Long.toString(yesterday); //24hours } else { startDateArg = Long.toString(startTime); } startDateArg = startDateArg.substring(0, 10); query_args.put("date_from", startDateArg); query_args.put("items_per_page", "100"); ApiResponse response = getQuery(url, method, query_args, true, isGet); if (response.isPositive()) { JSONObject httpAnswerJson = (JSONObject) response.getResponseObject(); JSONObject dataJson = (JSONObject) httpAnswerJson.get("response"); JSONArray entities; try { entities = (JSONArray) dataJson.get("entities"); } catch (ClassCastException e) { //Empty order list returns {"errors":false,"response":{"entities":false}, apiResponse.setResponseObject(tradesList); return apiResponse; } for (int i = 0; i < entities.size(); i++) { JSONObject tradeObject = (JSONObject) entities.get(i); Trade tempTrade = parseTrade(tradeObject); tradesList.add(tempTrade); } apiResponse.setResponseObject(tradesList); } else { apiResponse = response; } return apiResponse; } @Override public ApiResponse getOrderBook(CurrencyPair pair) { throw new UnsupportedOperationException("CcedkWrapper.getOrderBook() not implemented yet."); } private class CcedkService implements ServiceInterface { protected ApiKeys keys; //Parameters used to repeat an API call in case of wrong nonce error protected final int MAX_NUMBER_ATTEMPTS = 3; protected int wrongNonceCounter; protected String adjustedNonce; public CcedkService(ApiKeys keys) { this.keys = keys; this.wrongNonceCounter = 0; } private CcedkService() { //Used for ticker, does not require auth this.wrongNonceCounter = 0; } @Override public String executeQuery(String base, String method, AbstractMap<String, String> args, boolean needAuth, boolean isGet) { String answer = ""; String signature = ""; String post_data = ""; boolean httpError = false; HttpsURLConnection connection = null; try { // add nonce and build arg list if (needAuth) { args.put("nonce", Long.toString(System.currentTimeMillis())); post_data = TradeUtils.buildQueryString(args, ENCODING); String toHash = post_data; signature = TradeUtils.signRequest(keys.getPrivateKey(), toHash, SIGN_HASH_FUNCTION, ENCODING); } // build URL URL queryUrl; if (isGet) { queryUrl = new URL(base + method + "?" + post_data); } else { queryUrl = new URL(base + method); } LOG.trace(queryUrl.toString()); connection = (HttpsURLConnection) queryUrl.openConnection(); if (isGet) { connection.setRequestMethod("GET"); } else { connection.setRequestMethod("POST"); } // create and setup a HTTP connection connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; CCEDK PHP client; " + Settings.APP_NAME); if (needAuth) { connection.setRequestProperty("Key", keys.getApiKey()); connection.setRequestProperty("Sign", signature); } if (!isGet) { connection.setDoOutput(true); connection.setDoInput(true); DataOutputStream os = new DataOutputStream(connection.getOutputStream()); os.writeBytes(post_data); os.close(); } //Read the response BufferedReader br; if (connection.getResponseCode() >= 400) { LOG.info(connection.getRequestMethod() + " query to :" + base + " (method=" + method + ")" + " , HTTP response : " + connection.getResponseCode()); httpError = true; br = new BufferedReader(new InputStreamReader((connection.getErrorStream()))); } else { br = new BufferedReader(new InputStreamReader((connection.getInputStream()))); } String output; while ((output = br.readLine()) != null) { LOG.trace(output); answer += output; } if (httpError) { LOG.error("Http error - Post Data: " + post_data); JSONParser parser = new JSONParser(); try { JSONObject obj2 = (JSONObject) (parser.parse(answer)); answer = (String) obj2.get(TOKEN_ERR); } catch (ParseException ex) { LOG.error(ex.toString()); } } } //Capture Exceptions catch (IllegalStateException ex) { LOG.error(ex.toString()); return null; } catch (NoRouteToHostException | UnknownHostException ex) { //Global.BtceExchange.setConnected(false); LOG.error(ex.toString()); answer = TOKEN_BAD_RETURN; } catch (IOException ex) { LOG.error(ex.toString()); return null; } finally { //close the connection, set all objects to null connection.disconnect(); connection = null; } return answer; } } }