package com.sigmaflare.binancej; 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.BinanceServiceException; import com.sigmaflare.binancej.exceptions.BinanceServiceUnreachableException; import com.sigmaflare.binancej.exceptions.UnexpectedErrorException; import lombok.Builder; 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.NO_RESPONSE_TEXT_FORMATTED; import static com.sigmaflare.binancej.HttpRequests.buildGetRequestFromEndpoint; /** * 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. */ 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 * @throws com.sigmaflare.binancej.exceptions.IpBannedException If the IP is banned * @throws com.sigmaflare.binancej.exceptions.RateLimitExceededException If the rate limit is exceeded * @throws com.sigmaflare.binancej.exceptions.MalformedRequestException If the user's request is malformed * @throws com.sigmaflare.binancej.exceptions.InternalServiceErrorException If the error occurs on Binance's side * @throws com.sigmaflare.binancej.exceptions.BinanceServiceUnreachableException If the service is unreachable * @throws UnexpectedErrorException If an unexpected exception occurs */ public Ping ping() throws BinanceServiceException { final HttpGet request = buildGetRequestFromEndpoint(PING_URL, apiKey); try { try (CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(request)) { StatusLine sl = closeableHttpResponse.getStatusLine(); HttpEntity httpEntity = closeableHttpResponse.getEntity(); if (httpEntity == null) { throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, request.getURI().toASCIIString()), null); } String response = EntityUtils.toString(httpEntity); if (!HttpRequests.statusCodeIsOk(sl.getStatusCode())) { ServiceError error = mapper.readValue(response, ServiceError.class); throw HttpRequests.buildHttpException(sl.getStatusCode(), error); } return new Ping(); } } catch (IOException e) { throw new UnexpectedErrorException(e.getMessage(), e.getCause()); } } /** * Gets the current server time on Binance's servers * * @return A Time object populated with the current server time * @throws com.sigmaflare.binancej.exceptions.IpBannedException If the IP is banned * @throws com.sigmaflare.binancej.exceptions.RateLimitExceededException If the rate limit is exceeded * @throws com.sigmaflare.binancej.exceptions.MalformedRequestException If the user's request is malformed * @throws com.sigmaflare.binancej.exceptions.InternalServiceErrorException If the error occurs on Binance's side * @throws com.sigmaflare.binancej.exceptions.BinanceServiceUnreachableException If the service is unreachable * @throws UnexpectedErrorException If an unexpected exception occurs */ public Time getServerTime() throws BinanceServiceException { final HttpGet request = buildGetRequestFromEndpoint(TIME_URL, apiKey); try { try (CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(request)) { StatusLine sl = closeableHttpResponse.getStatusLine(); HttpEntity httpEntity = closeableHttpResponse.getEntity(); if (httpEntity == null) { throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, request.getURI().toASCIIString()), null); } String response = EntityUtils.toString(httpEntity); if (!HttpRequests.statusCodeIsOk(sl.getStatusCode())) { ServiceError error = mapper.readValue(response, ServiceError.class); throw HttpRequests.buildHttpException(sl.getStatusCode(), error); } return mapper.readValue(response, Time.class); } } catch (IOException e) { throw new UnexpectedErrorException(e.getMessage(), e.getCause()); } } /** * Retrieves exchange information * * @return An ExchangeInfo populated with exchange information * @throws com.sigmaflare.binancej.exceptions.IpBannedException If the IP is banned * @throws com.sigmaflare.binancej.exceptions.RateLimitExceededException If the rate limit is exceeded * @throws com.sigmaflare.binancej.exceptions.MalformedRequestException If the user's request is malformed * @throws com.sigmaflare.binancej.exceptions.InternalServiceErrorException If the error occurs on Binance's side * @throws com.sigmaflare.binancej.exceptions.BinanceServiceUnreachableException If the service is unreachable * @throws UnexpectedErrorException If an unexpected exception occurs */ public ExchangeInfo getExchangeInfo() throws BinanceServiceException { final HttpGet request = buildGetRequestFromEndpoint(EXCHANGE_INFO_URL, apiKey); try { try (CloseableHttpResponse closeableHttpResponse = closeableHttpClient.execute(request)) { StatusLine sl = closeableHttpResponse.getStatusLine(); HttpEntity httpEntity = closeableHttpResponse.getEntity(); if (httpEntity == null) { throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, request.getURI().toASCIIString()), null); } String response = EntityUtils.toString(httpEntity); if (!HttpRequests.statusCodeIsOk(sl.getStatusCode())) { ServiceError error = mapper.readValue(response, ServiceError.class); throw HttpRequests.buildHttpException(sl.getStatusCode(), error); } return mapper.readValue(response, ExchangeInfo.class); } } catch (IOException e) { throw new UnexpectedErrorException(e.getMessage(), e.getCause()); } } }