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

info.bitrich.xchangestream.btcmarkets.BTCMarketsStreamingService Maven / Gradle / Ivy

There is a newer version: 5.2.0
Show newest version
package info.bitrich.xchangestream.btcmarkets;

import com.fasterxml.jackson.databind.JsonNode;
import info.bitrich.xchangestream.btcmarkets.dto.BTCMarketsWebSocketSubscriptionMessage;
import info.bitrich.xchangestream.service.netty.JsonNettyStreamingService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class BTCMarketsStreamingService extends JsonNettyStreamingService {
  //	TODO change to enumerator
  static final String CHANNEL_ORDERBOOK = "orderbook";
  static final String CHANNEL_HEARTBEAT = "heartbeat";
  static final String CHANNEL_TICKER = "tick";
  static final String CHANNEL_TRADE = "trade";

  private static final Logger LOG = LoggerFactory.getLogger(BTCMarketsStreamingService.class);
  private final ConcurrentHashMap> subscribedMarketIds =
      new ConcurrentHashMap>();

  public BTCMarketsStreamingService(String apiUrl) {
    super(apiUrl);
  }

  /*
   * Implementation renamed from BTCMarketsWebSocketSubscribeMessage to BTCMarketsWebSocketSubscriptionMessage to look after
   * more than just the OrderBook subscription. This new implementation also incorporates the use of adding subscriptions to an existing one
   * instead of having to resubscribing with all channels and all {@code marketIds} every time the data services calls the subscribe methods.
   */
  private BTCMarketsWebSocketSubscriptionMessage buildSubscribeMessage(
      String channelName, Set marketIds) {

    // Create the first subscription message
    if (!hasActiveSubscriptions()) {
      return BTCMarketsWebSocketSubscriptionMessage.getFirstSubscriptionMessage(
          new ArrayList(marketIds),
          Arrays.asList(channelName, CHANNEL_HEARTBEAT),
          null,
          null,
          null);
    } else {
      return BTCMarketsWebSocketSubscriptionMessage.getAddSubscriptionMessage(
          new ArrayList(marketIds), Arrays.asList(channelName), null, null, null);
    }
  }

  private BTCMarketsWebSocketSubscriptionMessage buildRemoveSubscriptionMessage(
      String channelName, Set marketIds) {

    return BTCMarketsWebSocketSubscriptionMessage.getRemoveSubcriptionMessage(
        marketIds == null ? new ArrayList() : new ArrayList(marketIds),
        Arrays.asList(channelName),
        null,
        null,
        null);
  }

  @Override
  protected String getChannelNameFromMessage(JsonNode message) {
    final String messageType = message.get("messageType").asText();
    if (messageType.startsWith(CHANNEL_ORDERBOOK)
        || messageType.startsWith(CHANNEL_TICKER)
        || messageType.startsWith(CHANNEL_TRADE)) {
      return messageType + ":" + message.get("marketId").asText();
    }
    return messageType;
  }

  @Override
  public String getSubscribeMessage(String channelName, Object... args) throws IOException {

    if (CHANNEL_ORDERBOOK.equals(channelName)
        || CHANNEL_TICKER.equals(channelName)
        || CHANNEL_TRADE.equals(channelName)) {

      LOG.debug("Now subscribing to {}:{}", channelName, args);
      Set newMarketIds = new HashSet();
      if (args != null) {
        for (Object marketId : args) {
          newMarketIds.add(marketId.toString());
        }
        // Add the marketIds to the Channel
        Set updateMarketIds = subscribedMarketIds.get(channelName);
        if (updateMarketIds != null) {
          updateMarketIds.addAll(newMarketIds);
          subscribedMarketIds.put(channelName, updateMarketIds);
        } else {
          subscribedMarketIds.put(channelName, newMarketIds);
        }
      }
      LOG.debug(
          "getSubscribeMessage: what is in subscribedMarketIds {} - {} / new marketIds {}",
          channelName,
          subscribedMarketIds.get(channelName),
          newMarketIds);
      return objectMapper.writeValueAsString(buildSubscribeMessage(channelName, newMarketIds));
    } else {
      throw new IllegalArgumentException(
          "Can't create subscribe messsage for channel " + channelName);
    }
  }

  @Override
  public String getSubscriptionUniqueId(String channelName, Object... args) {
    LOG.debug("Returning unique id {}", channelName + ":" + args[0].toString());
    return channelName + ":" + args[0].toString();
  }

  @Override
  public String getUnsubscribeMessage(String channelName, Object... args) throws IOException {
    if (channelName.startsWith(CHANNEL_ORDERBOOK)
        || channelName.startsWith(CHANNEL_TICKER)
        || channelName.startsWith(CHANNEL_TRADE)) {
      LOG.debug(
          "getUnsubscribeMessage: what is in subscribedMarketIds {}:{}",
          channelName,
          subscribedMarketIds.get(channelName));
      return objectMapper.writeValueAsString(
          buildRemoveSubscriptionMessage(channelName, subscribedMarketIds.remove(channelName)));
    } else {
      return null;
    }
  }

  private Boolean hasActiveSubscriptions() {
    return !channels.isEmpty();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy