package com.sigmaflare.binancej; import com.codepoetics.ambivalence.Either; import com.sigmaflare.binancej.entities.ExchangeInfo; import com.sigmaflare.binancej.entities.Ping; import com.sigmaflare.binancej.entities.ServiceError; import com.sigmaflare.binancej.entities.Time; import com.sigmaflare.binancej.exceptions.BinanceServiceUnreachableException; import lombok.Builder; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; import java.io.IOException; import static com.sigmaflare.binancej.Constant.BASE_ENDPOINT; import static com.sigmaflare.binancej.Constant.NO_RESPONSE_TEXT; import static com.sigmaflare.binancej.Constant.NO_RESPONSE_TEXT_FORMATTED; /** * GeneralUtilities is a container class for methods that interact with the infrastructure * on the Binance side. Methods like server health and exchange information are found here. */ @Slf4j public class GeneralUtilities extends BaseBinanceApi { private static final String PING_URL = "/api/v1/ping"; private static final String TIME_URL = "/api/v1/time"; private static final String EXCHANGE_INFO_URL = "/api/v1/exchangeInfo"; @Builder public GeneralUtilities(String apiKey, String secretKey) { super(apiKey, secretKey); } GeneralUtilities(String apiKey, String secretKey, CloseableHttpClient closeableHttpClient) { super(apiKey, secretKey, closeableHttpClient); } /** * Hits the ping endpoint to check if the service is alive. * * @return empty Ping object if it returned 200, otherwise ServiceError */ public Either ping() throws BinanceServiceUnreachableException { final String url = String.format("%s%s", BASE_ENDPOINT, PING_URL); final HttpGet request = Helpers.getBuilder(url, apiKey); try { try (CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(request)) { StatusLine sl = closeableHttpResponse.getStatusLine(); HttpEntity httpEntity = closeableHttpResponse.getEntity(); if (httpEntity == null) { log.error(NO_RESPONSE_TEXT, url); throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, url), null); } String response = EntityUtils.toString(httpEntity); if (!Helpers.statusCodeIsOk(sl.getStatusCode())) { return Either.ofLeft(mapper.readValue(response, ServiceError.class)); } return Either.ofRight(new Ping()); } } catch (IOException e) { throw new BinanceServiceUnreachableException(e.getMessage(), e.getCause()); } } /** * Gets the current server time on Binance's servers * * @return A Time object if successful, otherwise an ServiceError object * @throws BinanceServiceUnreachableException Throws when the request fails */ public Either getServerTime() throws BinanceServiceUnreachableException { final String url = String.format("%s%s", BASE_ENDPOINT, TIME_URL); final HttpGet request = Helpers.getBuilder(url, apiKey); try { try (CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(request)) { StatusLine sl = closeableHttpResponse.getStatusLine(); HttpEntity httpEntity = closeableHttpResponse.getEntity(); if (httpEntity == null) { log.error(NO_RESPONSE_TEXT, url); throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, url), null); } String response = EntityUtils.toString(httpEntity); if (!Helpers.statusCodeIsOk(sl.getStatusCode())) { return Either.ofLeft(mapper.readValue(response, ServiceError.class)); } return Either.ofRight(mapper.readValue(response, Time.class)); } } catch (IOException e) { throw new BinanceServiceUnreachableException(e.getMessage(), e.getCause()); } } /** * Retrieves exchange information * * @return An ExchangeInfo when successful, otherwise an ServiceError * @throws BinanceServiceUnreachableException If the service cannot be reached */ public Either getExchangeInfo() throws BinanceServiceUnreachableException { final String url = String.format("%s%s", BASE_ENDPOINT, EXCHANGE_INFO_URL); final HttpGet request = Helpers.getBuilder(url, apiKey); try { try (CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(request)) { StatusLine sl = closeableHttpResponse.getStatusLine(); HttpEntity httpEntity = closeableHttpResponse.getEntity(); if (httpEntity == null) { log.error(NO_RESPONSE_TEXT, url); throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, url), null); } String response = EntityUtils.toString(httpEntity); if (!Helpers.statusCodeIsOk(sl.getStatusCode())) { return Either.ofLeft(mapper.readValue(response, ServiceError.class)); } return Either.ofRight(mapper.readValue(response, ExchangeInfo.class)); } } catch (IOException e) { throw new BinanceServiceUnreachableException(e.getMessage(), e.getCause()); } } }