/// <summary>
        /// Constructs and returns a <see cref="MarketDescriptionCacheItem"/> from the provided DTO
        /// </summary>
        /// <param name="dto">The <see cref="MarketDescriptionDTO"/> containing market description data.</param>
        /// <param name="factory">The <see cref="IMappingValidatorFactory"/> instance used to build market mapping validators .</param>
        /// <param name="culture">A <see cref="CultureInfo"/> specifying the language of the provided DTO.</param>
        /// <param name="source">The source cache where <see cref="MarketDescriptionCacheItem"/> is built</param>
        /// <returns>The constructed <see cref="MarketDescriptionCacheItem"/>.</returns>
        /// <exception cref="InvalidOperationException">The cache item could not be build from the provided DTO</exception>
        public static MarketDescriptionCacheItem Build(MarketDescriptionDTO dto, IMappingValidatorFactory factory, CultureInfo culture, string source)
        {
            Guard.Argument(dto, nameof(dto)).NotNull();
            Guard.Argument(factory, nameof(factory)).NotNull();
            Guard.Argument(culture, nameof(culture)).NotNull();

            var names = new Dictionary <CultureInfo, string> {
                { culture, dto.Name }
            };
            var descriptions = string.IsNullOrEmpty(dto.Description)
                ? new Dictionary <CultureInfo, string>()
                : new Dictionary <CultureInfo, string> {
                { culture, dto.Description }
            };

            var outcomes = dto.Outcomes == null
                ? null
                : new ReadOnlyCollection <MarketOutcomeCacheItem>(dto.Outcomes.Select(o => new MarketOutcomeCacheItem(o, culture)).ToList());

            var mappings = dto.Mappings == null
                ? null
                : new ReadOnlyCollection <MarketMappingCacheItem>(dto.Mappings.Select(m => MarketMappingCacheItem.Build(m, factory, culture)).ToList());

            var specifiers = dto.Specifiers == null
                ? null
                : new ReadOnlyCollection <MarketSpecifierCacheItem>(dto.Specifiers.Select(s => new MarketSpecifierCacheItem(s)).ToList());

            var attributes = dto.Attributes == null
                ? null
                : new ReadOnlyCollection <MarketAttributeCacheItem>(dto.Attributes.Select(a => new MarketAttributeCacheItem(a)).ToList());

            var groups = dto.Groups == null ? null : new ReadOnlyCollection <string>(dto.Groups.ToList());

            return(new MarketDescriptionCacheItem(dto.Id, names, descriptions, dto.Variant, dto.OutcomeType, outcomes, mappings, specifiers, attributes, groups, culture, source));
        }
示例#2
0
        public void MarketDescriptionDTOMappingTest()
        {
            var msg = RMF.GetDescMarket();
            var dto = new MarketDescriptionDTO(msg);

            Assert.AreEqual(msg.id, dto.Id);
            Assert.AreEqual(msg.name, dto.Name);
            Assert.AreEqual(msg.description, dto.Description);
            //Assert.AreEqual(msg.variant, dto.Variant); //TODO: check if variant is missing in dto?
            Assert.AreEqual(msg.mappings.Length, dto.Mappings.Count());
            Assert.AreEqual(msg.outcomes.Length, dto.Outcomes.Count());
            Assert.AreEqual(msg.specifiers.Length, dto.Specifiers.Count());

            for (var i = 0; i < msg.mappings.Length; i++)
            {
                ValidateMapping(msg.mappings[i], dto.Mappings.ToArray()[i]);
            }

            for (var i = 0; i < msg.outcomes.Length; i++)
            {
                ValidateOutcome(msg.outcomes[i], dto.Outcomes.ToArray()[i]);
            }

            for (var i = 0; i < msg.specifiers.Length; i++)
            {
                ValidateSpecifier(msg.specifiers[i], dto.Specifiers.ToArray()[i]);
            }
        }
示例#3
0
        internal void Merge(MarketDescriptionDTO dto, CultureInfo culture)
        {
            Contract.Requires(dto != null);
            Contract.Requires(culture != null);

            lock (_lock)
            {
                _names[culture] = dto.Name;
                if (!string.IsNullOrEmpty(dto.Description))
                {
                    _descriptions[culture] = dto.Description;
                }
                Variant = dto.Variant;

                if (dto.Outcomes != null)
                {
                    foreach (var outcomeDto in dto.Outcomes)
                    {
                        var existingOutcome = Outcomes?.FirstOrDefault(o => o.Id == outcomeDto.Id);
                        if (existingOutcome != null)
                        {
                            existingOutcome.Merge(outcomeDto, culture);
                        }
                        else
                        {
                            ExecutionLog.Warn(
                                $"Could not merge outcome[Id={outcomeDto.Id}] for lang={culture.TwoLetterISOLanguageName} on marketDescription[Id={Id}] because the specified outcome does not exist on stored market description.");
                            ComparePrint(dto, culture);
                        }
                    }
                }

                if (dto.Mappings != null)
                {
                    foreach (var mappingDto in dto.Mappings)
                    {
                        var existingMapping = Mappings?.FirstOrDefault(m => MarketMappingsMatch(m, mappingDto));
                        if (existingMapping != null)
                        {
                            existingMapping.Merge(mappingDto, culture);
                        }
                        else
                        {
                            ExecutionLog.Warn(
                                $"Could not merge mapping[MarketId={mappingDto.MarketTypeId}:{mappingDto.MarketSubTypeId}] for lang={culture.TwoLetterISOLanguageName} on marketDescription[Id={dto.Id}]because the specified mapping does not exist on stored market description.");
                            ComparePrint(dto, culture);
                        }
                    }
                }

                OutcomeType = dto.OutcomeType;

                Groups = dto.Groups == null ? null : new ReadOnlyCollection <string>(dto.Groups.ToList());

                FetchedLanguages.Add(culture);

                LastDataReceived = DateTime.Now;
            }
        }
        private void ComparePrint(MarketDescriptionDTO dto, CultureInfo culture)
        {
            var names    = _names.Aggregate(string.Empty, (current, name) => current + $", {name.Key.TwoLetterISOLanguageName}-{name.Value}").Substring(2);
            var desc     = _descriptions.Aggregate(string.Empty, (current, d) => current + $", {d.Key.TwoLetterISOLanguageName}-{d.Value}");
            var specs    = Specifiers == null ? null : string.Join(", ", Specifiers.Select(s => s.Name));
            var outcomes = Outcomes == null ? null : string.Join(",", Outcomes.Select(s => s.Id));
            var maps     = Mappings == null ? null : string.Join(",", Mappings.Select(s => s.MarketTypeId));

            ExecutionLog.Debug($"Original Id={Id}, Names=[{names}], Descriptions=[{desc}], Variant=[{Variant}], Specifiers=[{specs}], Outocomes=[{outcomes}], Mappings=[{maps}].");

            var specsNew    = dto.Specifiers == null ? null : string.Join(", ", dto.Specifiers.Select(s => s.Name));
            var outcomesNew = dto.Outcomes == null ? null : string.Join(",", dto.Outcomes.Select(s => s.Id));
            var mapsNew     = dto.Mappings == null ? null : string.Join(",", dto.Mappings.Select(s => s.MarketTypeId));

            ExecutionLog.Debug($"New Id={dto.Id}, Name=[{culture.TwoLetterISOLanguageName}-{dto.Name}], Descriptions=[{dto.Description}], Variant=[{dto.Variant}], Specifiers=[{specsNew}], Outocomes=[{outcomesNew}], Mappings=[{mapsNew}].");
        }
示例#5
0
        public void Merge(MarketDescriptionDTO dto, CultureInfo culture)
        {
            Guard.Argument(dto, nameof(dto)).NotNull();
            Guard.Argument(culture, nameof(culture)).NotNull();

            _names[culture] = dto.Name;
            if (!string.IsNullOrEmpty(dto.Description))
            {
                _descriptions[culture] = dto.Description;
            }
            Variant = dto.Variant;

            if (dto.Outcomes != null)
            {
                foreach (var outcomeDto in dto.Outcomes)
                {
                    var existingOutcome = Outcomes?.FirstOrDefault(o => o.Id == outcomeDto.Id);
                    if (existingOutcome != null)
                    {
                        existingOutcome.Merge(outcomeDto, culture);
                    }
                    else
                    {
                        Log.Warn($"Could not merge outcome[Id={outcomeDto.Id}] on marketDescription[Id={dto.Id}] because the specified outcome does not exist on stored market description");
                    }
                }
            }

            if (dto.Mappings != null)
            {
                foreach (var mappingDto in dto.Mappings)
                {
                    var existingMapping = Mappings?.FirstOrDefault(m => m.MarketTypeId == mappingDto.MarketTypeId && m.MarketSubTypeId == mappingDto.MarketSubTypeId);
                    if (existingMapping != null)
                    {
                        existingMapping.Merge(mappingDto);
                    }
                    else
                    {
                        Log.Warn($"Could not merge mapping[MarketId={mappingDto.MarketTypeId}:{mappingDto.MarketSubTypeId}] on marketDescription[Id={dto.Id}] because the specified mapping" +
                                 " does not exist on stored market description");
                    }
                }
            }

            _supportedLanguages.Add(culture);
        }
示例#6
0
        /// <summary>
        ///     Merges the provided descriptions with those found in cache
        /// </summary>
        /// <param name="culture">A <see cref="CultureInfo" /> specifying the language of the <code>descriptions</code></param>
        /// <param name="description">A <see cref="MarketDescriptionDTO" /> containing market description in specified language</param>
        private void Merge(CultureInfo culture, MarketDescriptionDTO description)
        {
            Contract.Requires(culture != null);
            Contract.Requires(description != null);

            if (_isDisposed)
            {
                return;
            }

            try
            {
                _semaphoreCacheMerge.Wait();
                var cachedItem = _cache.GetCacheItem(GetCacheKey(description.Id, description.Variant));
                if (cachedItem == null)
                {
                    cachedItem = new CacheItem(GetCacheKey(description.Id, description.Variant),
                                               MarketDescriptionCacheItem.Build(description, _mappingValidatorFactory, culture, CacheName));
                    _cache.Add(cachedItem, _cacheItemPolicy);
                }
                else
                {
                    ((MarketDescriptionCacheItem)cachedItem.Value).Merge(description, culture);
                }
            }
            catch (Exception e)
            {
                if (!(e is InvalidOperationException))
                {
                    throw;
                }
                ExecutionLog.Warn("Mapping validation for MarketDescriptionCacheItem failed.", e);
            }
            finally
            {
                if (!_isDisposed)
                {
                    _semaphoreCacheMerge.Release();
                }
            }
        }
        /// <summary>
        /// Merges the provided descriptions with those found in cache
        /// </summary>
        /// <param name="culture">A <see cref="CultureInfo"/> specifying the language of the <code>descriptions</code></param>
        /// <param name="description">A <see cref="MarketDescriptionDTO"/> containing market description in specified language</param>
        private async Task MergeAsync(CultureInfo culture, MarketDescriptionDTO description)
        {
            Guard.Argument(culture, nameof(culture)).NotNull();
            Guard.Argument(description, nameof(description)).NotNull();

            if (_isDisposed)
            {
                return;
            }

            try
            {
                await _semaphoreCacheMerge.WaitAsync().ConfigureAwait(false);

                var cacheId    = GetCacheKey(description.Id, description.Variant);
                var cachedItem = _cache.GetCacheItem(cacheId);
                if (cachedItem == null)
                {
                    cachedItem = new CacheItem(cacheId, MarketDescriptionCacheItem.Build(description, _mappingValidatorFactory, culture, CacheName));
                    _cache.Add(cachedItem, new CacheItemPolicy {
                        SlidingExpiration = OperationManager.VariantMarketDescriptionCacheTimeout
                    });
                }
                else
                {
                    ((MarketDescriptionCacheItem)cachedItem.Value).Merge(description, culture);
                }
            }
            catch (Exception e)
            {
                if (!(e is InvalidOperationException))
                {
                    throw;
                }
                ExecutionLog.LogWarning(e, "Mapping validation for MarketDescriptionCacheItem failed.");
            }
            finally
            {
                _semaphoreCacheMerge.ReleaseSafe();
            }
        }