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

com.sportradar.unifiedodds.sdk.OddsFeedRoutingKeyBuilder Maven / Gradle / Ivy

/*
 * Copyright (C) Sportradar AG. See LICENSE for full license governing this code
 */

package com.sportradar.unifiedodds.sdk;

import com.google.common.base.Preconditions;
import com.sportradar.unifiedodds.sdk.exceptions.UnsupportedMessageInterestCombination;
import com.sportradar.utils.URN;

import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

/**
 * An utility class that handles session routing key assignment
 */
class OddsFeedRoutingKeyBuilder {
    /**
     * The routing key pattern used to receive snapshot complete messages
     */
    private static final String SNAPSHOT_COMPLETE_ROUTING_KEY_TEMPLATE = "-.-.-.snapshot_complete.-.-.-.%s";

    /**
     * Private constructor, since this is a static utility class
     */
    private OddsFeedRoutingKeyBuilder() {}

    /**
     * Builds a valid list of routing keys for the provided sessions
     * k -> session identifier
     * v -> a {@link List} of routing keys for the associated session
     *
     * @param sessionsData - a {@link Map} describing the feed sessions
     * @param oddsFeedConfiguration - the associated feed SDK configuration instance
     * @return - a collection of session identifiers associated with a valid list of valid routing keys
     */
    static Map> generateKeys(Map>> sessionsData, SDKInternalConfiguration oddsFeedConfiguration) {
        Preconditions.checkNotNull(sessionsData);
        Preconditions.checkArgument(!sessionsData.isEmpty());
        Preconditions.checkNotNull(oddsFeedConfiguration);

        validateInterestCombination(sessionsData);

        boolean bothLowAndHigh = haveBothLowAndHigh(sessionsData);

        String snapshotRoutingKey = String.format(SNAPSHOT_COMPLETE_ROUTING_KEY_TEMPLATE,
                oddsFeedConfiguration.getSdkNodeId() == null ? "-" : oddsFeedConfiguration.getSdkNodeId());

        Map> result = new HashMap<>(sessionsData.size());
        sessionsData.forEach((k, v) -> {
            List sessionRoutingKeys = new ArrayList<>();

            List basicRoutingKeys = getBasicRoutingKeys(v.getKey(), v.getValue());
            for (String basicRoutingKey: basicRoutingKeys) {
                if (oddsFeedConfiguration.getSdkNodeId() != null) {
                    sessionRoutingKeys.add(basicRoutingKey + "." + oddsFeedConfiguration.getSdkNodeId() + ".#");
                    basicRoutingKey = basicRoutingKey + ".-.#";
                } else {
                    basicRoutingKey = basicRoutingKey + ".#";
                }

                if (bothLowAndHigh && v.getKey() == MessageInterest.LoPrioMessagesOnly) {
                    sessionRoutingKeys.add(basicRoutingKey);
                } else {
                    sessionRoutingKeys.add(snapshotRoutingKey);
                    sessionRoutingKeys.add(basicRoutingKey);
                }
            }
            if (v.getKey() != MessageInterest.SystemAliveMessages) {
                sessionRoutingKeys.add(MessageInterest.SystemAliveMessages.getRoutingKeys().get(0));
            }
            result.put(k, sessionRoutingKeys.stream().distinct().collect(Collectors.toList()));
        });

        return result;
    }

    private static List getBasicRoutingKeys(MessageInterest messageInterest, Set eventIds) {
        return messageInterest != MessageInterest.SpecifiedMatchesOnly ?
                messageInterest.getRoutingKeys() :
                eventIds.stream().map(e -> String.format("#.%s:%s.%d", e.getPrefix(), e.getType(), e.getId())).collect(Collectors.toList());
    }

    private static void validateInterestCombination(Map>> sessionsData) {
        Preconditions.checkNotNull(sessionsData);

        if (sessionsData.isEmpty()) {
            throw new UnsupportedMessageInterestCombination("There must be at least one session per SDK instance");
        }

        if (sessionsData.size() == 1) {
            return;
        }

        Collection>> allUserValues = sessionsData.values();
        Set>> uniqueValues = new HashSet<>(allUserValues);
        if (allUserValues.size() != uniqueValues.size()) {
            throw new UnsupportedMessageInterestCombination("Session message interest must be unique per SDK instance, found duplicates. " + allUserValues);
        }

        if (allUserValues.stream().anyMatch(v -> v.getKey() == MessageInterest.AllMessages)) {
            throw new UnsupportedMessageInterestCombination("The AllMessages message interest can only be used in a single session setup. " + allUserValues);
        }

        if (sessionsData.size() > 1 && (containsLowOrHigh(sessionsData) && containsMessageTypeInterest(sessionsData))) {
            String errorMsg = "Combination of session message interests not supported." + allUserValues;
            throw new UnsupportedMessageInterestCombination(errorMsg);
        }
    }

    private static boolean containsLowOrHigh(Map>> sessionsData) {
        Preconditions.checkNotNull(sessionsData);
        List messageInterests = sessionsData.values().stream().map(Entry::getKey).collect(Collectors.toList());

        return messageInterests.contains(MessageInterest.HiPrioMessagesOnly) ||
                messageInterests.contains(MessageInterest.LoPrioMessagesOnly);
    }

    private static boolean containsMessageTypeInterest(Map>> sessionsData) {
        Preconditions.checkNotNull(sessionsData);
        List messageInterests = sessionsData.values().stream().map(Entry::getKey).collect(Collectors.toList());

        return messageInterests.contains(MessageInterest.PrematchMessagesOnly) ||
                messageInterests.contains(MessageInterest.LiveMessagesOnly) ||
                messageInterests.contains(MessageInterest.VirtualSports);
    }

    private static boolean haveBothLowAndHigh(Map>> sessionsData) {
        Preconditions.checkNotNull(sessionsData);
        List messageInterests = sessionsData.values().stream().map(Entry::getKey).collect(Collectors.toList());

        return messageInterests.contains(MessageInterest.LoPrioMessagesOnly) &&
                messageInterests.contains(MessageInterest.HiPrioMessagesOnly);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy