コード例 #1
0
    private IEnumerator DownloadSDK(SdkInfo info)
    {
        var path = Path.Combine(downloadDir, info.Filename);

        activity = string.Format("Downloading {0}...", info.Filename);
        Debug.Log(activity);

        // Start the async download job.
        downloader = new UnityWebRequest(info.Url)
        {
            downloadHandler = new DownloadHandlerFile(path),
            timeout         = 60, // seconds
        };
        downloader.SendWebRequest();

        // Pause until download done/cancelled/fails, keeping progress bar up to date.
        while (!downloader.isDone)
        {
            yield return(null);

            var progress = Mathf.FloorToInt(downloader.downloadProgress * 100);
            if (EditorUtility.DisplayCancelableProgressBar("MoPub SDK Manager", activity, progress))
            {
                downloader.Abort();
            }
        }
        EditorUtility.ClearProgressBar();

        if (string.IsNullOrEmpty(downloader.error))
        {
            AssetDatabase.ImportPackage(path, true);  // OK, got the file, so let the user import it if they want.
        }
        else
        {
            var error = downloader.error;
            if (downloader.isNetworkError)
            {
                if (error.EndsWith("destination host"))
                {
                    error += ": " + info.Url;
                }
            }
            else if (downloader.isHttpError)
            {
                switch (downloader.responseCode)
                {
                case 404:
                    var file = Path.GetFileName(new Uri(info.Url).LocalPath);
                    error = string.Format("File {0} not found on server.", file);
                    break;

                default:
                    error = downloader.responseCode + "\n" + error;
                    break;
                }
            }

            Debug.LogError(error);
        }

        // Reset async state so the GUI is operational again.
        downloader.Dispose();
        downloader = null;
        coroutine  = null;
    }
コード例 #2
0
    private IEnumerator GetSDKVersions()
    {
        // Wait one frame so that we don't try to show the progress bar in the middle of OnGUI().
        yield return(null);

        activity = "Downloading SDK version manifest...";

        UnityWebRequest www = new UnityWebRequest(staging ? stagingURL : manifestURL)
        {
            downloadHandler = new DownloadHandlerBuffer(),
            timeout         = 10, // seconds
        };

        yield return(www.SendWebRequest());

        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.LogError(www.error);
            EditorUtility.DisplayDialog(
                "SDK Manager Service",
                "The services we need are not accessible. Please consider integrating manually.\n\n" +
                "For instructions, see " + helpLink,
                "OK");
        }

        var json = www.downloadHandler.text;

        if (string.IsNullOrEmpty(json))
        {
            json = "{}";
            Debug.LogError("Unable to retrieve SDK version manifest.  Showing installed SDKs only.");
        }
        www.Dispose();

        // Got the file.  Now extract info on latest SDKs available.
        mopubSdkInfo = new SdkInfo();
        sdkInfo.Clear();
        var dict = MJ.Json.Deserialize(json) as Dictionary <string, object>;

        if (dict != null)
        {
            object obj;
            if (dict.TryGetValue("mopubBaseConfig", out obj))
            {
                mopubSdkInfo.FromJson("Unity SDK", obj as Dictionary <string, object>);
                mopubSdkInfo.CurrentVersion = MoPub.MoPubSdkVersion;
            }
            if (dict.TryGetValue("releaseInfo", out obj))
            {
                foreach (var item in obj as Dictionary <string, object> )
                {
                    var info = new SdkInfo();
                    if (info.FromJson(item.Key, item.Value as Dictionary <string, object>))
                    {
                        sdkInfo[info.Key] = info;
                    }
                }
            }
        }

        // Figure out what versions of SDKs are currently installed.
        var baseType = typeof(PackageConfig);
        var configs  = from t in Assembly.GetExecutingAssembly().GetTypes()
                       where t.IsSubclassOf(baseType) && !t.IsAbstract
                       select Activator.CreateInstance(t) as PackageConfig;

        foreach (var config in configs)
        {
            SdkInfo info;
            sdkInfo.TryGetValue(config.Name, out info);
            if (info.FromConfig(config))
            {
                sdkInfo[info.Key] = info;
            }
        }

        // Clear up the async-job state.
        coroutine = null;
        Repaint();
    }
コード例 #3
0
    private void SdkRow(SdkInfo info, Func <bool, bool> customButton = null)
    {
        var lat     = info.LatestVersion;
        var cur     = info.CurrentVersion;
        var isInst  = !string.IsNullOrEmpty(cur);
        var canInst = !string.IsNullOrEmpty(lat) && (!isInst || MoPubUtils.CompareVersions(cur, lat) < 0);
        // Is any async job in progress?
        var stillWorking = coroutine != null || downloader != null;

        var tooltip = string.Empty;

        if (info.NetworkVersions != null)
        {
            string version;
            if (info.NetworkVersions.TryGetValue(PackageConfig.Platform.ANDROID, out version))
            {
                tooltip += "\n  Android SDK:  " + version;
            }
            if (info.NetworkVersions.TryGetValue(PackageConfig.Platform.IOS, out version))
            {
                tooltip += "\n  iOS SDK:  " + version;
            }
        }
        tooltip += "\n  Installed:  " + (cur ?? "n/a");
        tooltip  = info.Name + "\n  Package:  " + (lat ?? "n/a") + tooltip;

        GUILayout.Space(4);
        using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false))) {
            GUILayout.Space(10);
            EditorGUILayout.LabelField(new GUIContent {
                text = info.Name, tooltip = tooltip
            });
            GUILayout.Button(new GUIContent {
                text    = lat ?? "--",
                tooltip = tooltip
            }, canInst ? EditorStyles.boldLabel : EditorStyles.label);
            GUILayout.Space(3);
            if (customButton == null || !customButton(canInst))
            {
                GUI.enabled = !stillWorking && (canInst || testing);
                if (GUILayout.Button(new GUIContent {
                    text = isInst ? "Upgrade" : "Install",
                    tooltip = tooltip
                }, fieldWidth))
                {
                    this.StartCoroutine(DownloadSDK(info));
                }
                GUI.enabled = true;
            }

            if (!string.IsNullOrEmpty(info.Instructions) && (info.Instructions != helpLink || testing))
            {
                if (GUILayout.Button("?", GUILayout.ExpandWidth(false)))
                {
                    Application.OpenURL(info.Instructions);
                }
            }
            else
            {
                // Need to fill space so that the Install/Upgrade buttons all line up nicely.
                GUILayout.Button(" ", EditorStyles.label, GUILayout.Width(17));
            }
            GUILayout.Space(5);
        }
        GUILayout.Space(4);
    }
コード例 #4
0
        /// <summary>
        /// Maps (converts) the provided <see cref="bet_cancel"/> instance to the <see cref="IBetCancel{T}"/> instance
        /// </summary>
        /// <param name="message">A <see cref="bet_cancel"/> instance to be mapped (converted)</param>
        /// <param name="cultures">A <see cref="IEnumerable{CultureInfo}" /> specifying the languages to which the mapped message will be translated</param>
        /// <param name="rawMessage">The raw message</param>
        /// <returns>A <see cref="IBetCancel{T}"/> instance constructed from information in the provided <see cref="bet_cancel"/></returns>
        public IBetCancel <T> MapBetCancel <T>(bet_cancel message, IEnumerable <CultureInfo> cultures, byte[] rawMessage) where T : ISportEvent
        {
            Guard.Argument(message, nameof(message)).NotNull();

            var culturesList = cultures as List <CultureInfo> ?? cultures.ToList();

            return(new BetCancel <T>(new MessageTimestamp(message.GeneratedAt, message.SentAt, message.ReceivedAt, SdkInfo.ToEpochTime(DateTime.Now)),
                                     _producerManager.Get(message.product),
                                     GetEventForMessage <T>(URN.Parse(message.event_id), message.SportId, culturesList),
                                     message.request_idSpecified ? (long?)message.request_id : null,
                                     message.start_timeSpecified ? (long?)message.start_time : null,
                                     message.end_timeSpecified ? (long?)message.end_time : null,
                                     string.IsNullOrEmpty(message.superceded_by)
                                        ? null
                                        : URN.Parse(message.superceded_by),
                                     message.market.Select(m => GetMarketCancel(GetEventForNameProvider <T>(URN.Parse(message.event_id), message.SportId, culturesList),
                                                                                m, message.ProducerId, message.SportId, culturesList)),
                                     rawMessage));
        }
コード例 #5
0
        private void Compare(PlayerProfileCI playerCI, playerExtended player, CultureInfo culture)
        {
            Assert.IsNotNull(playerCI);
            Assert.IsNotNull(player);

            Assert.AreEqual(player.id, playerCI.Id.ToString());
            Assert.AreEqual(_competitorId, playerCI.CompetitorId);
            if (player.type == null)
            {
                Assert.IsNull(playerCI.Type);
            }
            else
            {
                Assert.AreEqual(player.type, playerCI.Type);
            }
            if (player.country_code == null)
            {
                Assert.IsNull(playerCI.CountryCode);
            }
            else
            {
                Assert.AreEqual(player.country_code, playerCI.CountryCode);
            }
            if (player.date_of_birth == null)
            {
                Assert.IsNull(playerCI.DateOfBirth);
            }
            else
            {
                Assert.AreEqual(player.date_of_birth, playerCI.DateOfBirth.Value.ToString("yyyy-MM-dd"));
            }
            if (player.full_name == null)
            {
                Assert.IsNull(playerCI.FullName);
            }
            else
            {
                Assert.AreEqual(player.full_name, playerCI.FullName);
            }
            if (player.gender == null)
            {
                Assert.IsNull(playerCI.Gender);
            }
            else
            {
                Assert.AreEqual(player.gender, playerCI.Gender);
            }
            if (!player.heightSpecified)
            {
                Assert.IsNull(playerCI.Height);
            }
            else
            {
                Assert.IsTrue(player.height > 0);
                Assert.AreEqual(player.height, playerCI.Height);
            }
            if (!player.weightSpecified)
            {
                Assert.IsNull(playerCI.Weight);
            }
            else
            {
                Assert.IsTrue(player.weight > 0);
                Assert.AreEqual(player.weight, playerCI.Weight);
            }
            if (player.type == null)
            {
                Assert.IsNull(playerCI.Type);
            }
            else
            {
                Assert.AreEqual(player.type, playerCI.Type);
            }
            //if (!player.jersey_numberSpecified)
            //{
            //    Assert.IsNull(playerCI.);
            //}
            //else
            //{
            //    Assert.IsTrue(player.height > 0);
            //    Assert.AreEqual(player.height, playerCI.Height);
            //}
            if (player.name == null)
            {
                Assert.IsNull(playerCI.GetName(culture));
            }
            else
            {
                Assert.AreEqual(player.name, playerCI.GetName(culture));
            }
            if (player.nationality == null)
            {
                Assert.IsNull(playerCI.GetNationality(culture));
            }
            else
            {
                Assert.AreEqual(player.nationality, playerCI.GetNationality(culture));
            }
            if (player.nickname == null)
            {
                Assert.IsNull(playerCI.Nickname);
            }
            else
            {
                Assert.AreEqual(player.nickname, playerCI.Nickname);
            }
            if (player.name == null)
            {
                Assert.IsNull(playerCI.Abbreviation);
            }
            else
            {
                Assert.AreEqual(SdkInfo.GetAbbreviationFromName(player.name), playerCI.Abbreviation);
            }
        }
コード例 #6
0
        /// <summary>
        /// Maps (converts) the provided <see cref="alive"/> instance to the <see cref="IAlive"/> instance
        /// </summary>
        /// <param name="message">A <see cref="alive"/> instance to be mapped (converted)</param>
        /// <returns>A <see cref="IAlive"/> instance constructed from information in the provided <see cref="alive"/></returns>
        public IAlive MapAlive(alive message)
        {
            Guard.Argument(message, nameof(message)).NotNull();

            return(new Alive(new MessageTimestamp(message.GeneratedAt, message.SentAt, message.ReceivedAt, SdkInfo.ToEpochTime(DateTime.Now)), _producerManager.Get(message.product), message.subscribed != 0));
        }
コード例 #7
0
        /// <summary>
        /// Maps (converts) the provided <see cref="fixture_change" /> instance to the <see cref="IFixtureChange{T}" /> instance
        /// </summary>
        /// <param name="message">A <see cref="fixture_change" /> instance to be mapped (converted)</param>
        /// <param name="cultures">A <see cref="IEnumerable{CultureInfo}" /> specifying the languages to which the mapped message will be translated</param>
        /// <param name="rawMessage">The raw message</param>
        /// <returns>A <see cref="IFixtureChange{T}" /> instance constructed from information in the provided <see cref="fixture_change" /></returns>
        public IFixtureChange <T> MapFixtureChange <T>(fixture_change message, IEnumerable <CultureInfo> cultures, byte[] rawMessage) where T : ISportEvent
        {
            Guard.Argument(message, nameof(message)).NotNull();

            return(new FixtureChange <T>(new MessageTimestamp(message.GeneratedAt, message.SentAt, message.ReceivedAt, SdkInfo.ToEpochTime(DateTime.Now)),
                                         _producerManager.Get(message.product),
                                         GetEventForMessage <T>(URN.Parse(message.event_id), message.SportId, cultures),
                                         message.request_idSpecified ? (long?)message.request_id : null,
                                         MessageMapperHelper.GetEnumValue(message.change_typeSpecified, message.change_type, FixtureChangeType.OTHER),
                                         message.next_live_timeSpecified ? (long?)message.next_live_time : null,
                                         message.start_time,
                                         rawMessage));
        }
コード例 #8
0
        /// <summary>
        /// Maps (converts) the provided <see cref="cashout" /> instance to the <see cref="ICashOutProbabilities{T}" /> instance
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="message">A <see cref="cashout" /> instance to be mapped (converted)</param>
        /// <param name="cultures">A <see cref="IEnumerable{CultureInfo}" /> specifying the languages to which the mapped message will be translated</param>
        /// <param name="rawMessage">The raw message</param>
        /// <returns>A <see cref="ICashOutProbabilities{T}" /> instance constructed from information in the provided <see cref="cashout" /></returns>
        public ICashOutProbabilities <T> MapCashOutProbabilities <T>(cashout message, IEnumerable <CultureInfo> cultures, byte[] rawMessage) where T : ISportEvent
        {
            Guard.Argument(message, nameof(message)).NotNull();

            var culturesList = cultures as List <CultureInfo> ?? cultures.ToList();
            var eventId      = URN.Parse(message.event_id);
            var sportId      = URN.Parse("sr:sport:1");

            return(new CashOutProbabilities <T>(new MessageTimestamp(message.GeneratedAt, message.SentAt, message.ReceivedAt, SdkInfo.ToEpochTime(DateTime.Now)),
                                                _producerManager.Get(message.product),
                                                GetEventForMessage <T>(eventId, sportId, culturesList),
                                                message.odds != null && message.odds.betstop_reasonSpecified
                    ? (int?)message.odds.betstop_reason
                    : null,
                                                message.odds != null && message.odds.betting_statusSpecified
                    ? (int?)message.odds.betting_status
                    : null,
                                                message.odds?.market?.Select(m => GetMarketWithProbabilities(GetEventForNameProvider <T>(eventId, sportId, culturesList), m, message.product, sportId, culturesList)).ToList(),
                                                _namedValuesProvider,
                                                rawMessage));
        }
コード例 #9
0
        /// <summary>
        /// Handles the message received event
        /// </summary>
        /// <param name="sender">The <see cref="object"/> representation of the event sender</param>
        /// <param name="eventArgs">A <see cref="BasicDeliverEventArgs"/> containing event information</param>
        private void consumer_OnReceived(object sender, BasicDeliverEventArgs eventArgs)
        {
            if (eventArgs.Body == null || !eventArgs.Body.Any())
            {
                ExecutionLog.WarnFormat("A message with {0} body received. Aborting message processing", eventArgs.Body == null ? "null" : "empty");
                return;
            }

            var receivedAt = SdkInfo.ToEpochTime(DateTime.Now);

            // NOT used for GetRawMessage()
            var         sessionName = _interest == null ? "system" : _interest.Name;
            string      messageBody = null;
            FeedMessage feedMessage;
            IProducer   producer;
            string      messageName;

            try
            {
                using (var t = Metric.Context("FEED")
                               .Timer("Message deserialization time", Unit.Items, SamplingType.Default, TimeUnit.Minutes)
                               .NewContext(eventArgs.RoutingKey))
                {
                    messageBody = Encoding.UTF8.GetString(eventArgs.Body);
                    feedMessage = _deserializer.Deserialize(new MemoryStream(eventArgs.Body));
                    producer    = _producerManager.Get(feedMessage.ProducerId);
                    messageName = feedMessage.GetType().Name;
                    if (!string.IsNullOrEmpty(feedMessage.EventId) && URN.TryParse(feedMessage.EventId, out URN eventUrn))
                    {
                        feedMessage.EventURN = eventUrn;
                    }
                    if (_keyParser.TryGetSportId(eventArgs.RoutingKey, messageName, out var sportId))
                    {
                        feedMessage.SportId = sportId;
                    }
                    if (t.Elapsed.TotalMilliseconds > 300)
                    {
                        var marketCounts  = 0;
                        var outcomeCounts = 0;
                        if (feedMessage is odds_change oddsChange)
                        {
                            marketCounts  = oddsChange.odds?.market?.Length ?? 0;
                            outcomeCounts = oddsChange.odds?.market?.Where(w => w.outcome != null).SelectMany(list => list.outcome).Count() ?? 0;
                        }

                        if (feedMessage is bet_settlement betSettlement)
                        {
                            marketCounts  = betSettlement.outcomes?.Length ?? 0;
                            outcomeCounts = betSettlement.outcomes?.Where(w => w.Items != null).SelectMany(list => list.Items).Count() ?? 0;
                        }

                        ExecutionLog.Debug(
                            $"Deserialization of {feedMessage.GetType().Name} for {feedMessage.EventId} ({feedMessage.GeneratedAt}) and sport {sportId} took {t.Elapsed.TotalMilliseconds}ms. Markets={marketCounts}, Outcomes={outcomeCounts}");
                    }
                }

                if (producer.IsAvailable && !producer.IsDisabled)
                {
                    FeedLog.Info($"<~> {sessionName} <~> {eventArgs.RoutingKey} <~> {messageBody}");
                }
                else
                {
                    if (FeedLog.IsDebugEnabled)
                    {
                        FeedLog.Debug($"<~> {sessionName} <~> {eventArgs.RoutingKey} <~> {producer.Id}");
                    }
                }

                if (eventArgs.BasicProperties?.Headers != null)
                {
                    feedMessage.SentAt = eventArgs.BasicProperties.Headers.ContainsKey("timestamp_in_ms")
                                             ? long.Parse(eventArgs.BasicProperties.Headers["timestamp_in_ms"].ToString())
                                             : feedMessage.GeneratedAt;
                }
                feedMessage.ReceivedAt = receivedAt;
                Metric.Context("FEED").Meter("Message received", Unit.Items).Mark(messageName);
            }
            catch (DeserializationException ex)
            {
                ExecutionLog.Error($"Failed to parse message. RoutingKey={eventArgs.RoutingKey} Message: {messageBody}", ex);
                Metric.Context("FEED").Meter("Message deserialization exception", Unit.Items).Mark();
                RaiseDeserializationFailed(eventArgs.Body);
                return;
            }
            catch (Exception ex)
            {
                ExecutionLog.Error($"Error consuming feed message. RoutingKey={eventArgs.RoutingKey} Message: {messageBody}", ex);
                Metric.Context("FEED").Meter("Exception consuming feed message", Unit.Items).Mark(eventArgs.RoutingKey);
                RaiseDeserializationFailed(eventArgs.Body);
                return;
            }

            // send RawFeedMessage if needed
            try
            {
                if (producer.IsAvailable && !producer.IsDisabled)
                {
                    //ExecutionLog.LogDebug($"Raw msg [{_interest}]: {feedMessage.GetType().Name} for event {feedMessage.EventId}.");
                    var args = new RawFeedMessageEventArgs(eventArgs.RoutingKey, feedMessage, sessionName);
                    RawFeedMessageReceived?.Invoke(this, args);
                }
            }
            catch (Exception e)
            {
                ExecutionLog.Error($"Error dispatching raw message for {feedMessage.EventId}", e);
            }
            // continue normal processing

            if (!_producerManager.Exists(feedMessage.ProducerId))
            {
                ExecutionLog.Warn($"A message for producer which is not defined was received. Producer={feedMessage.ProducerId}");
                return;
            }

            if (!_useReplay && (!producer.IsAvailable || producer.IsDisabled))
            {
                ExecutionLog.Debug($"A message for producer which is disabled was received. Producer={producer}, MessageType={messageName}");
                return;
            }

            ExecutionLog.Info($"Message received. Message=[{feedMessage}].");
            if (feedMessage.IsEventRelated)
            {
                if (!string.IsNullOrEmpty(eventArgs.RoutingKey) && _keyParser.TryGetSportId(eventArgs.RoutingKey, messageName, out var sportId))
                {
                    feedMessage.SportId = sportId;
                }
                else
                {
                    ExecutionLog.Warn($"Failed to parse the SportId from the routing key. RoutingKey={eventArgs.RoutingKey}, message=[{feedMessage}]. SportId will not be set.");
                }
            }

            RaiseMessageReceived(feedMessage, eventArgs.Body);
        }
コード例 #10
0
        private IEnumerable <IMarketMappingData> GetMarketMapping(IMarketDescription marketDescription)
        {
            if (marketDescription == null)
            {
                return(new List <IMarketMappingData>());
            }

            if (marketDescription.Mappings == null || !marketDescription.Mappings.Any())
            {
                ExecutionLog.LogDebug($"An error occurred getting mapped marketId for marketId={_marketId} (no mappings exist).");
                return(new List <IMarketMappingData>());
            }

            var mappings = marketDescription.Mappings.Where(m => m.CanMap(_producer, _sportId, _specifiers)).ToList();

            if (!mappings.Any())
            {
                ExecutionLog.LogDebug($"Market with id:{_marketId}, producer:{_producer}, sportId:{_sportId} has no mappings.");
                return(mappings);
            }

            if (mappings.Count > 1)
            {
                foreach (var mapping in mappings)
                {
                    if (mapping.MarketId.Equals(marketDescription.Id.ToString()))
                    {
                        return(new[] { mapping });
                    }
                }

                ExecutionLog.LogWarning($"Market with id:{_marketId}, producer:{_producer.Id}, sportId:{_sportId.Id} has too many mappings [{mappings.Count}].");
                CacheLog.LogWarning($"MarketId:{_marketId}, producer:{_producer.Id}, sportId:{_sportId.Id}, specifiers={SdkInfo.SpecifiersKeysToString(marketDescription.Specifiers)} has too many mappings [{mappings.Count}].");
                var i = 0;
                foreach (var mapping in mappings)
                {
                    CacheLog.LogDebug($"MarketId:{_marketId}, producer:{_producer.Id}, sportId:{_sportId.Id} mapping[{i}]: {mapping}.");
                    i++;
                }
            }

            return(mappings);
        }
コード例 #11
0
 /// <inheritdoc />
 public override string ToString()
 {
     return($"After={After}/{SdkInfo.FromEpochTime(After)}, NodeId={NodeId}, Timestamp={Timestamp}/{SdkInfo.FromEpochTime(Timestamp)}, RequestId={RequestId}, Response={ResponseCode}-{ResponseMessage}");
 }
コード例 #12
0
        private async Task <(string path, SdkInfo)> GetSDKForBinary(OpenJDKRelease release, OpenJDKBinary binary)
        {
            if (
                release.release_name == null ||
                release.release_link == null ||
                binary.os == null ||
                binary.architecture == null ||
                binary.binary_name == null ||
                binary.binary_link == null ||
                binary.checksum_link == null ||
                binary.version_data == null ||
                binary.version_data.openjdk_version == null ||
                binary.version_data.semver == null
                )
            {
                throw new ArgumentException("Property is null");
            }

            Console.WriteLine($"Creating SDK for binary {binary.binary_name}");

            var shaFileContent = await HttpUtil.FetchString(binary.checksum_link);

            var sha256 = HashUtil.ParseSha256(shaFileContent) ?? throw new Exception($"Invalid SHA256 from {binary.checksum_link}.");

            var os   = SdkHelper.ParseOperatingSystem(binary.os);
            var arch = SdkHelper.ParseArch(binary.architecture);

            var zipDirName =
                binary.version == "10"
                    ? release.release_name.Replace(binary.version_data.openjdk_version, binary.version_data.semver)
                    : release.release_name;

            var sdkInfo = new SdkInfo(
                implements: new[] { "jdk" },
                version: binary.version_data.semver,
                platforms: new[] { new PlatformInfo(os, arch) },
                setupSteps: new SdkSetupStep[] {
                new SdkSetupStep.Download(binary.binary_link, binary.binary_name, new SdkHash(SdkHashType.Sha256, sha256)),
                new SdkSetupStep.Extract(binary.binary_name, "."),
                new SdkSetupStep.Delete(binary.binary_name),
            },
                pathDirs: new[] {
                zipDirName + "/bin"
            },
                env: new Dictionary <string, EnvValue> {
                { "JAVA_HOME", new EnvValue.Concat(
                      new EnvValue[] {
                        new EnvValue.BuiltInValue(EnvValue.BuiltInValue.SdkDirectory),
                        new EnvValue.OfString("/" + zipDirName),
                    }
                      ) },
            }
                );

            var noExtFile = Path.GetFileNameWithoutExtension(binary.binary_name);

            if (noExtFile.EndsWith(".tar"))
            {
                noExtFile = Path.GetFileNameWithoutExtension(noExtFile);
            }

            return($"jdk/jdk{binary.version}/{noExtFile}.json", sdkInfo);
        }
コード例 #13
0
        private void ChannelOnModelShutdown(object sender, ShutdownEventArgs shutdownEventArgs)
        {
            var reason = _channel.CloseReason == null ? string.Empty : SdkInfo.ClearSensitiveData(_channel.CloseReason.ToString(), _accessToken);

            ExecutionLog.Info($"The channel with channelNumber {_channel.ChannelNumber} is shutdown. Reason={reason}");
        }
コード例 #14
0
        private void ConsumerOnShutdown(object sender, ShutdownEventArgs shutdownEventArgs)
        {
            var reason = _consumer.ShutdownReason == null ? string.Empty : SdkInfo.ClearSensitiveData(_consumer.ShutdownReason.ToString(), _accessToken);

            ExecutionLog.Info($"The consumer {_consumer.ConsumerTag} is shutdown. Reason={reason}");
        }
コード例 #15
0
        /// <summary>
        /// Maps (converts) the provided <see cref="odds_change"/> instance to the <see cref="IOddsChange{T}"/> instance
        /// </summary>
        /// <param name="message">A <see cref="odds_change"/> instance to be mapped (converted)</param>
        /// <param name="cultures">A <see cref="IEnumerable{CultureInfo}" /> specifying the languages to which the mapped message will be translated</param>
        /// <param name="rawMessage">The raw message</param>
        /// <returns>A <see cref="IOddsChange{T}"/> instance constructed from information in the provided <see cref="odds_change"/></returns>
        public IOddsChange <T> MapOddsChange <T>(odds_change message, IEnumerable <CultureInfo> cultures, byte[] rawMessage) where T : ISportEvent
        {
            Guard.Argument(message, nameof(message)).NotNull();

            var culturesList = cultures as List <CultureInfo> ?? cultures.ToList();

            var markets = message.odds?.market?.Select(m => GetMarketWithOdds(GetEventForNameProvider <T>(message.EventURN, message.SportId, culturesList), m, message.ProducerId, message.SportId, culturesList)).ToList();

            return(new OddsChange <T>(new MessageTimestamp(message.GeneratedAt, message.SentAt, message.ReceivedAt, SdkInfo.ToEpochTime(DateTime.Now)),
                                      _producerManager.Get(message.product),
                                      GetEventForMessage <T>(URN.Parse(message.event_id), message.SportId, culturesList),
                                      message.request_idSpecified ? (long?)message.request_id : null,
                                      MessageMapperHelper.GetEnumValue(message.odds_change_reasonSpecified, message.odds_change_reason, OddsChangeReason.NORMAL),
                                      message.odds != null && message.odds.betstop_reasonSpecified ? (int?)message.odds.betstop_reason : null,
                                      message.odds != null && message.odds.betting_statusSpecified ? (int?)message.odds.betting_status : null,
                                      markets,
                                      message.odds_generation_properties,
                                      _namedValuesProvider,
                                      rawMessage));
        }
コード例 #16
0
        /// <summary>
        /// Merges the information from the provided <see cref="CompetitorProfileDTO"/> into the current instance
        /// </summary>
        /// <param name="competitorProfile">A <see cref="CompetitorProfileDTO"/> containing information about the competitor</param>
        /// <param name="culture">A <see cref="CultureInfo"/> specifying the language of the passed <code>dto</code></param>
        internal void Merge(CompetitorProfileDTO competitorProfile, CultureInfo culture)
        {
            Guard.Argument(competitorProfile, nameof(competitorProfile)).NotNull();
            Guard.Argument(competitorProfile.Competitor, nameof(competitorProfile.Competitor)).NotNull();

            _isVirtual              = competitorProfile.Competitor.IsVirtual;
            Names[culture]          = competitorProfile.Competitor.Name;
            _countryNames[culture]  = competitorProfile.Competitor.CountryName;
            _abbreviations[culture] = string.IsNullOrEmpty(competitorProfile.Competitor.Abbreviation)
                ? SdkInfo.GetAbbreviationFromName(competitorProfile.Competitor.Name)
                : competitorProfile.Competitor.Abbreviation;
            _referenceId = UpdateReferenceIds(competitorProfile.Competitor.Id, competitorProfile.Competitor.ReferenceIds);
            if (!string.IsNullOrEmpty(competitorProfile.Competitor.CountryCode))
            {
                _countryCode = competitorProfile.Competitor.CountryCode;
            }
            if (!string.IsNullOrEmpty(competitorProfile.Competitor.State))
            {
                _state = competitorProfile.Competitor.State;
            }
            if (!competitorProfile.Players.IsNullOrEmpty())
            {
                _associatedPlayerIds = competitorProfile.Players.Select(s => s.Id).ToList();
            }
            if (!competitorProfile.Jerseys.IsNullOrEmpty())
            {
                _jerseys = competitorProfile.Jerseys.Select(s => new JerseyCI(s)).ToList();
            }
            if (competitorProfile.Manager != null)
            {
                if (_manager == null)
                {
                    _manager = new ManagerCI(competitorProfile.Manager, culture);
                }
                else
                {
                    _manager.Merge(competitorProfile.Manager, culture);
                }
            }
            if (competitorProfile.Venue != null)
            {
                if (_venue == null)
                {
                    _venue = new VenueCI(competitorProfile.Venue, culture);
                }
                else
                {
                    _venue.Merge(competitorProfile.Venue, culture);
                }
            }
            if (!string.IsNullOrEmpty(competitorProfile.Competitor.Gender))
            {
                _gender = competitorProfile.Competitor.Gender;
            }
            if (!string.IsNullOrEmpty(competitorProfile.Competitor.AgeGroup))
            {
                _ageGroup = competitorProfile.Competitor.AgeGroup;
            }
            if (competitorProfile.RaceDriverProfile != null)
            {
                _raceDriverProfile = new RaceDriverProfileCI(competitorProfile.RaceDriverProfile);
            }
            if (competitorProfile.Competitor.SportId != null)
            {
                _sportId = competitorProfile.Competitor.SportId;
            }
            if (competitorProfile.Competitor.CategoryId != null)
            {
                _categoryId = competitorProfile.Competitor.CategoryId;
            }
            if (!string.IsNullOrEmpty(competitorProfile.Competitor.ShortName))
            {
                _shortName = competitorProfile.Competitor.ShortName;
            }
            _lastTimeCompetitorProfileFetched = DateTime.Now;
            _cultureCompetitorProfileFetched.Add(culture);
            _fetchedCultures.Add(culture);
        }
コード例 #17
0
ファイル: SdkResolver.cs プロジェクト: helium-build/helium
 private PlatformSdk(List <string> realUrls, SdkInfo sdk)
 {
     this.realUrls = realUrls;
     this.sdk      = sdk;
 }
コード例 #18
0
        /// <summary>
        /// Handles the message received event
        /// </summary>
        /// <param name="sender">The <see cref="object"/> representation of the event sender</param>
        /// <param name="eventArgs">A <see cref="BasicDeliverEventArgs"/> containing event information</param>
        private void consumer_OnReceived(object sender, BasicDeliverEventArgs eventArgs)
        {
            if (eventArgs.Body == null || !eventArgs.Body.Any())
            {
                ExecutionLog.WarnFormat("A message with {0} body received. Aborting message processing", eventArgs.Body == null ? "null" : "empty");
                return;
            }

            var receivedAt = SdkInfo.ToEpochTime(DateTime.Now);

            // NOT used for GetRawMessage()
            var         sessionName = _interest == null ? "system" : _interest.Name;
            string      messageBody = null;
            FeedMessage feedMessage;
            IProducer   producer;
            string      messageName;

            try
            {
                messageBody = Encoding.UTF8.GetString(eventArgs.Body);
                feedMessage = _deserializer.Deserialize(new MemoryStream(eventArgs.Body));
                producer    = _producerManager.Get(feedMessage.ProducerId);
                messageName = feedMessage.GetType().Name;

                if (producer.IsAvailable && !producer.IsDisabled)
                {
                    FeedLog.Info($"<~> {sessionName} <~> {eventArgs.RoutingKey} <~> {messageBody}");
                }
                else
                {
                    if (FeedLog.IsDebugEnabled)
                    {
                        FeedLog.Debug($"<~> {sessionName} <~> {eventArgs.RoutingKey} <~> {producer.Id}");
                    }
                }

                if (eventArgs.BasicProperties?.Headers != null)
                {
                    feedMessage.SentAt = eventArgs.BasicProperties.Headers.ContainsKey("timestamp_in_ms")
                                             ? long.Parse(eventArgs.BasicProperties.Headers["timestamp_in_ms"].ToString())
                                             : feedMessage.GeneratedAt;
                }
                feedMessage.ReceivedAt = receivedAt;
                Metric.Context("RABBIT").Meter("RabbitMqMessageReceiver", Unit.Items).Mark(messageName);
            }
            catch (DeserializationException ex)
            {
                ExecutionLog.Error($"Failed to parse message. RoutingKey={eventArgs.RoutingKey} Message: {messageBody}", ex);
                Metric.Context("RABBIT").Meter("RabbitMqMessageReceiver->DeserializationException", Unit.Calls).Mark();
                RaiseDeserializationFailed(eventArgs.Body);
                return;
            }

            // send RawFeedMessage if needed
            try
            {
                if (producer.IsAvailable && !producer.IsDisabled)
                {
                    //ExecutionLog.LogDebug($"Raw msg [{_interest}]: {feedMessage.GetType().Name} for event {feedMessage.EventId}.");
                    var args = new RawFeedMessageEventArgs(eventArgs.RoutingKey, feedMessage, sessionName);
                    RawFeedMessageReceived?.Invoke(this, args);
                }
            }
            catch (Exception e)
            {
                ExecutionLog.Error($"Error dispatching raw message for {feedMessage.EventId}", e);
            }
            // continue normal processing

            if (!_producerManager.Exists(feedMessage.ProducerId))
            {
                ExecutionLog.Warn($"A message for producer which is not defined was received. Producer={feedMessage.ProducerId}");
                return;
            }

            if (!_useReplay && (!producer.IsAvailable || producer.IsDisabled))
            {
                ExecutionLog.Debug($"A message for producer which is disabled was received. Producer={producer}, MessageType={messageName}");
                return;
            }

            ExecutionLog.Info($"Message received. Message=[{feedMessage}].");
            if (feedMessage.IsEventRelated)
            {
                URN sportId;
                if (!string.IsNullOrEmpty(eventArgs.RoutingKey) && _keyParser.TryGetSportId(eventArgs.RoutingKey, messageName, out sportId))
                {
                    feedMessage.SportId = sportId;
                }
                else
                {
                    ExecutionLog.Warn($"Failed to parse the SportId from the routing key. RoutingKey={eventArgs.RoutingKey}, message=[{feedMessage}]. SportId will not be set.");
                }
            }

            RaiseMessageReceived(feedMessage, eventArgs.Body);
        }
コード例 #19
0
        /// <summary>
        /// Maps (converts) the provided <see cref="snapshot_complete"/> instance to the <see cref="ISnapshotCompleted"/> instance
        /// </summary>
        /// <param name="message">A <see cref="snapshot_complete"/> instance to be mapped (converted)</param>
        /// <returns>A <see cref="ISnapshotCompleted"/> instance constructed from information in the provided <see cref="snapshot_complete"/></returns>
        public ISnapshotCompleted MapSnapShotCompleted(snapshot_complete message)
        {
            Guard.Argument(message, nameof(message)).NotNull();

            return(new SnapshotCompleted(new MessageTimestamp(message.GeneratedAt, message.SentAt, message.ReceivedAt, SdkInfo.ToEpochTime(DateTime.Now)), _producerManager.Get(message.product), message.request_id));
        }
コード例 #20
0
        /// <summary>
        /// Processes a message received on the system's session
        /// </summary>
        /// <remarks>
        /// This method does:
        /// - starts recovery operations if needed
        /// - interrupt running recoveries on non-subscribed alive(s) and alive violation(s)
        /// - set LastTimestampBeforeDisconnect property on the producer.
        /// This method does not:
        /// - determine if the user is behind (or not) with message processing - this is done in CheckStatus(..) method
        /// - attempt to determine whether the recovery has timed-out - this is done in CheckStatus(..) method
        /// </remarks>
        /// <param name="message">A <see cref="FeedMessage"/> received on the system session</param>
        public void ProcessSystemMessage(FeedMessage message)
        {
            Guard.Argument(message, nameof(message)).NotNull();

            var alive = message as alive;

            if (alive?.ProducerId != Producer.Id)
            {
                return;
            }

            var newStatus = Status;

            if (Status == ProducerRecoveryStatus.FatalError || _producer.IgnoreRecovery)
            {
                return;
            }

            lock (_syncLock)
            {
                try
                {
                    // store the timestamp of most recent system alive before it is overridden by
                    // _timestampTracker.ProcessSystemAlive(alive); in case the current alive
                    // is not subscribed and ongoing recovery operation must be interrupted
                    var previousAliveTimestamp = _timestampTracker.SystemAliveTimestamp;
                    _timestampTracker.ProcessSystemAlive(alive);
                    _producer.SetTimeOfLastAlive(TimeProviderAccessor.Current.Now);

                    // if current status is NotStarted or Error just start the recovery
                    if (Status == ProducerRecoveryStatus.NotStarted || Status == ProducerRecoveryStatus.Error)
                    {
                        try
                        {
                            if (_recoveryOperation.Start())
                            {
                                ExecutionLog.Info($"Producer={_producer.Id}: Recovery operation started. Current status={Enum.GetName(typeof(ProducerRecoveryStatus), Status)}, After={SdkInfo.ToEpochTime(_producer.LastTimestampBeforeDisconnect)}.");
                                newStatus = ProducerRecoveryStatus.Started;
                            }
                            else
                            {
                                ExecutionLog.Warn($"Producer={_producer.Id}: An error occurred while starting recovery operation with after={SdkInfo.ToEpochTime(_producer.LastTimestampBeforeDisconnect)}. Retry will be made at next system alive.");
                            }
                        }
                        catch (RecoveryInitiationException ex)
                        {
                            ExecutionLog.Fatal($"Producer id={Producer.Id} failed to execute recovery because 'after' is to much in the past. After={ex.After}. Stopping the feed.");
                            newStatus = ProducerRecoveryStatus.FatalError;
                        }
                    }
                    else
                    {
                        Debug.Assert(Status == ProducerRecoveryStatus.Started ||
                                     Status == ProducerRecoveryStatus.Completed ||
                                     Status == ProducerRecoveryStatus.Delayed);

                        // we are no longer in sync with the feed
                        if (alive.subscribed == 0)
                        {
                            if (_recoveryOperation.IsRunning)
                            {
                                Debug.Assert(Status == ProducerRecoveryStatus.Started);
                                var timestamp = SdkInfo.FromEpochTime(previousAliveTimestamp);
                                ExecutionLog.Info($"Producer={_producer.Id}: Recovery operation interrupted. Current status={Enum.GetName(typeof(ProducerRecoveryStatus), Status)}, Timestamp={timestamp}.");
                                _recoveryOperation.Interrupt(timestamp);
                            }
                            else
                            {
                                Debug.Assert(Status == ProducerRecoveryStatus.Completed || Status == ProducerRecoveryStatus.Delayed);
                                try
                                {
                                    if (_recoveryOperation.Start())
                                    {
                                        ExecutionLog.Info($"Producer={_producer.Id}: Recovery operation started due to un-subscribed alive. Current status={Enum.GetName(typeof(ProducerRecoveryStatus), Status)}, After={SdkInfo.ToEpochTime(_producer.LastTimestampBeforeDisconnect)}.");
                                        newStatus = ProducerRecoveryStatus.Started;
                                    }
                                    else
                                    {
                                        ExecutionLog.Warn($"Producer={_producer.Id}: An error occurred while starting recovery operation with after={SdkInfo.ToEpochTime(_producer.LastTimestampBeforeDisconnect)}. Retry will be made at next system alive.");
                                        newStatus = ProducerRecoveryStatus.Error;
                                    }
                                }
                                catch (RecoveryInitiationException ex)
                                {
                                    ExecutionLog.Fatal($"Producer id={Producer.Id} failed to execute recovery because 'after' is to much in the past. After={ex.After}. Stopping the feed.");
                                    newStatus = ProducerRecoveryStatus.FatalError;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    ExecutionLog.Error($"An unexpected exception occurred while processing system message. Producer={_producer.Id}, message={message}. Exception:", ex);
                }
                if (newStatus != Status)
                {
                    SetStatusAndRaiseEvent(null, newStatus);
                }
            }
        }
コード例 #21
0
        /// <summary>
        /// Maps (converts) the provided <see cref="bet_stop" /> instance to the <see cref="IBetStop{T}" /> instance
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="message">A <see cref="bet_stop" /> instance to be mapped (converted)</param>
        /// <param name="cultures">A <see cref="IEnumerable{CultureInfo}" /> specifying the languages to which the mapped message will be translated</param>
        /// <param name="rawMessage">The raw message</param>
        /// <returns>A <see cref="IBetStop{T}" /> instance constructed from information in the provided <see cref="bet_stop" /></returns>
        public IBetStop <T> MapBetStop <T>(bet_stop message, IEnumerable <CultureInfo> cultures, byte[] rawMessage) where T : ISportEvent
        {
            Guard.Argument(message, nameof(message)).NotNull();

            return(new BetStop <T>(new MessageTimestamp(message.GeneratedAt, message.SentAt, message.ReceivedAt, SdkInfo.ToEpochTime(DateTime.Now)),
                                   _producerManager.Get(message.product),
                                   GetEventForMessage <T>(URN.Parse(message.event_id), message.SportId, cultures),
                                   message.request_idSpecified ? (long?)message.request_id : null,
                                   MessageMapperHelper.GetEnumValue(message.market_statusSpecified, message.market_status, MarketStatus.SUSPENDED),
                                   message.groups?.Split('|'),
                                   rawMessage));
        }
コード例 #22
0
        /// <summary>
        /// Checks the status of the current recovery manager
        /// </summary>
        /// <remarks>
        /// The method must:
        /// - Check whether current recovery is running and has expired
        /// - Whether there is an alive violation
        /// - Whether the user is behind with processing
        /// The method should not:
        /// - Update the processing delay - this is done on a message from a user's session
        /// - Start the recovery - this is done on alive from the system session
        /// - Complete non timed-out recovery - this is done on the snapshot_complete from user's session
        /// </remarks>
        public void CheckStatus()
        {
            //if the producer is disabled in SDK or not available for current user - nothing to do
            if (!Producer.IsAvailable || Producer.IsDisabled)
            {
                return;
            }

            // recovery must not be done (replay server)
            if (_producer.IgnoreRecovery)
            {
                return;
            }

            // multiple class fields can be accessed from multiple threads(messages from user session(s), system session, here, ...)
            lock (_syncLock)
            {
                var newStatus = Status;

                try
                {
                    // check whether the user is falling behind with processing
                    if (Status == ProducerRecoveryStatus.Completed && _timestampTracker.IsBehind)
                    {
                        newStatus = ProducerRecoveryStatus.Delayed;
                    }

                    // check whether the user was behind with processing but is no longer
                    if (Status == ProducerRecoveryStatus.Delayed && !_timestampTracker.IsBehind)
                    {
                        newStatus = ProducerRecoveryStatus.Completed;
                    }

                    // Check whether there is an alive violation during normal processing
                    if ((Status == ProducerRecoveryStatus.Completed || Status == ProducerRecoveryStatus.Delayed) && _timestampTracker.IsAliveViolated)
                    {
                        ExecutionLog.Warn($"Producer id={Producer.Id}: alive violation detected. Recovery will be done on next system alive.");
                        newStatus = ProducerRecoveryStatus.Error;
                    }

                    // Check whether there is an alive violation during recovery
                    if (Status == ProducerRecoveryStatus.Started && _timestampTracker.IsAliveViolated)
                    {
                        Debug.Assert(_recoveryOperation.IsRunning);
                        ExecutionLog.Warn($"Producer id={Producer.Id}: alive violation detected during recovery. Additional recovery from {_timestampTracker.SystemAliveTimestamp} will be done once the current is completed.");
                        _recoveryOperation.Interrupt(SdkInfo.FromEpochTime(_timestampTracker.SystemAliveTimestamp));
                    }

                    // Check whether the recovery is running and has timed-out
                    if (Status == ProducerRecoveryStatus.Started && _recoveryOperation.HasTimedOut())
                    {
                        Debug.Assert(_recoveryOperation.IsRunning);
                        _recoveryOperation.CompleteTimedOut();
                        ExecutionLog.Warn($"Producer id={Producer.Id}: recovery timeout. New recovery from {_timestampTracker.SystemAliveTimestamp} will be done.");
                        newStatus = ProducerRecoveryStatus.Error;
                    }
                    ExecutionLog.Info($"Status check: Producer={_producer}({Enum.GetName(typeof(ProducerRecoveryStatus), Status)}), Timing Info={_timestampTracker}");
                }
                catch (Exception ex)
                {
                    ExecutionLog.Error($"An unexpected exception occurred while checking status. Producer={_producer.Id}. Status={Status}, IsRunning={_recoveryOperation.IsRunning}", ex);
                }
                if (newStatus != Status)
                {
                    SetStatusAndRaiseEvent(null, newStatus);
                }
            }
        }
コード例 #23
0
        /// <summary>
        /// Maps (converts) the provided <see cref="bet_settlement"/> instance to the <see cref="IBetSettlement{T}"/> instance
        /// </summary>
        /// <param name="message">A <see cref="bet_settlement"/> instance to be mapped (converted)</param>
        /// <param name="cultures">A <see cref="IEnumerable{CultureInfo}" /> specifying the languages to which the mapped message will be translated</param>
        /// <param name="rawMessage">The raw message</param>
        /// <returns>A <see cref="IBetSettlement{T}"/> instance constructed from information in the provided <see cref="bet_settlement"/></returns>
        public IBetSettlement <T> MapBetSettlement <T>(bet_settlement message, IEnumerable <CultureInfo> cultures, byte[] rawMessage) where T : ISportEvent
        {
            Guard.Argument(message, nameof(message)).NotNull();

            var culturesList = cultures as List <CultureInfo> ?? cultures.ToList();

            return(new BetSettlement <T>(new MessageTimestamp(message.GeneratedAt, message.SentAt, message.ReceivedAt, SdkInfo.ToEpochTime(DateTime.Now)),
                                         _producerManager.Get(message.product),
                                         GetEventForMessage <T>(URN.Parse(message.event_id), message.SportId, culturesList),
                                         message.request_idSpecified ? (long?)message.request_id : null,
                                         message.outcomes.Select(m => GetMarketWithResults(GetEventForNameProvider <T>(URN.Parse(message.event_id), message.SportId, culturesList),
                                                                                           m, message.ProducerId, message.SportId, culturesList)),
                                         message.certainty,
                                         rawMessage));
        }
コード例 #24
0
        private void CreateAndAttachEvents()
        {
            ExecutionLog.LogInformation("Opening the channel ...");
            _channel = _channelFactory.CreateChannel();
            ExecutionLog.LogInformation($"Channel opened with channelNumber: {_channel.ChannelNumber}. MaxAllowedTimeBetweenMessages={_maxTimeBetweenMessages.TotalSeconds}s.");
            var declareResult = _channel.QueueDeclare();

            foreach (var routingKey in _routingKeys)
            {
                ExecutionLog.LogInformation($"Binding queue={declareResult.QueueName} with routingKey={routingKey}");
                _channel.QueueBind(declareResult.QueueName, "unifiedfeed", routingKey);
            }
            var interestName = _interest == null ? "system" : _interest.Name;

            _consumer             = new EventingBasicConsumer(_channel);
            _consumer.ConsumerTag = $"UfSdk-NetStd|{SdkInfo.GetVersion()}|{interestName}|{_channel.ChannelNumber}|{DateTime.Now:yyyyMMdd-HHmmss}|{SdkInfo.GetGuid(8)}";
            _consumer.Received   += ConsumerOnDataReceived;
            _consumer.Shutdown   += ConsumerOnShutdown;
            _channel.BasicConsume(declareResult.QueueName, true, _consumer.ConsumerTag, _consumer);
            _channel.ModelShutdown += ChannelOnModelShutdown;
            ExecutionLog.LogInformation("BasicConsume for channel={}, queue={} and consumer tag {} executed.", _channel.ChannelNumber, declareResult.QueueName, _consumer.ConsumerTag);

            _lastMessageReceived = DateTime.MinValue;
            _channelStarted      = DateTime.Now;
        }