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.NO_RESPONSE_TEXT; import static com.sigmaflare.binancej.Constant.NO_RESPONSE_TEXT_FORMATTED; import static com.sigmaflare.binancej.Helpers.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. */ @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 HttpGet request = buildGetRequestFromEndpoint(PING_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, request.getURI().toASCIIString()); throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, request.getURI().toASCIIString()), 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 HttpGet request = buildGetRequestFromEndpoint(TIME_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, request.getURI().toASCIIString()); throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, request.getURI().toASCIIString()), 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 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) { log.error(NO_RESPONSE_TEXT, request.getURI().toASCIIString()); throw new BinanceServiceUnreachableException( String.format(NO_RESPONSE_TEXT_FORMATTED, request.getURI().toASCIIString()), 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()); } } }