/// <summary> /// Asynchronously gets a <see cref="IMarketDescription"/> instance describing the specified market in the specified language /// </summary> /// <param name="culture">The <see cref="CultureInfo"/> specifying the language of the returned descriptor</param> /// <returns>A <see cref="Task{IMarketDescriptor}"/> representing the asynchronous operation</returns> /// <exception cref="CacheItemNotFoundException">The requested key was not found in the cache and could not be loaded</exception> private async Task <IMarketDescription> GetMarketDescriptorAsync(CultureInfo culture) { Contract.Requires(culture != null); Contract.Ensures(Contract.Result <Task <IMarketDescription> >() != null); return(await _marketCacheProvider.GetMarketDescriptionAsync(_marketId, _specifiers, new[] { culture }, true).ConfigureAwait(false)); }
/// <summary> /// Returns the unmodified market name template /// </summary> /// <param name="culture">The culture in which the name template should be provided</param> /// <returns>The unmodified market name template</returns> public string GetNameTemplate(CultureInfo culture) { if (_names.Any()) { return(_names.ContainsKey(culture) ? _names[culture] : null); } if (string.IsNullOrEmpty(_outcomeId)) { return(null); } try { var marketDescription = _marketCacheProvider.GetMarketDescriptionAsync((int)_marketDescription.Id, _specifiers, _cultures, true).Result; if (marketDescription?.Outcomes == null || !marketDescription.Outcomes.Any()) { return(null); } var outcomeDescription = marketDescription.Outcomes.FirstOrDefault(s => s.Id.Equals(_outcomeId, StringComparison.InvariantCultureIgnoreCase)); if (outcomeDescription == null) { if (!string.IsNullOrEmpty(marketDescription.OutcomeType) && marketDescription.OutcomeType.Equals(SdkInfo.CompetitorsMarketOutcomeType)) { foreach (var cultureInfo in _cultures) { _names[cultureInfo] = _outcomeId; } return(_outcomeId); } var outcomesString = WriteOutcomes(marketDescription.Outcomes, culture); throw new CacheItemNotFoundException($"OutcomeDescription in marketDescription for id={_marketDescription.Id} not found. Existing outcomes: {outcomesString}", _outcomeId, null); } foreach (var cultureInfo in _cultures) { _names[cultureInfo] = outcomeDescription.GetName(cultureInfo); } } catch (CacheItemNotFoundException e) { if (_exceptionHandlingStrategy == ExceptionHandlingStrategy.THROW) { throw new CacheItemNotFoundException($"OutcomeDescription in marketDescription for id={_marketDescription.Id} could not provide the requested translated name", _outcomeId, e); } } catch (Exception ex) { if (_exceptionHandlingStrategy == ExceptionHandlingStrategy.THROW) { throw new CacheItemNotFoundException($"OutcomeDescription in marketDescription for id={_marketDescription.Id} could not provide the requested translated name", _outcomeId, ex); } } return(_names.ContainsKey(culture) ? _names[culture] : null); }
/// <summary> /// Checks if the market descriptor exists for this marketId and specifiers /// </summary> /// <param name="producerId">The id of the producer which produced the message</param> /// <param name="marketId">A market identifier, identifying the market to be checked</param> /// <param name="specifiers">A <see cref="IReadOnlyDictionary{String, String}" /> representing specifiers of the associated market</param> private async Task <bool> CheckSpecifiersAsync(int producerId, int marketId, IReadOnlyDictionary <string, string> specifiers) { IMarketDescription marketDescriptor; try { marketDescriptor = await _marketCacheProvider.GetMarketDescriptionAsync(marketId, specifiers, _defaultCulture, false).ConfigureAwait(false); } catch (CacheItemNotFoundException ex) { ExecutionLog.Info($"Check failed. Failed to retrieve market name descriptor market[id={marketId}].", ex); return(false); } if (marketDescriptor == null) { ExecutionLog.Info($"Check failed. Failed to retrieve market name descriptor for market[id={marketId}]."); return(false); } var nameDescription = marketDescriptor.GetName(_defaultCulture.First()); if (nameDescription == null) { ExecutionLog.Info($"Check failed. Retrieved market[id={marketId}] descriptor does not contain name descriptor in the specified language"); return(false); } if (marketDescriptor.Id != marketId) { ExecutionLog.Info($"Check failed. Retrieved market descriptor has different marketId. ({marketDescriptor.Id}!={marketId})"); return(false); } if (marketDescriptor.Specifiers != null && marketDescriptor.Specifiers.Any() && specifiers != null) { if (marketDescriptor.Specifiers.Count() != specifiers.Count) { var requiredSpecifiers = string.Join(",", marketDescriptor.Specifiers.Select(d => d.Name)); var actualSpecifiers = string.Join(",", specifiers.Select(k => k.Key)); ExecutionLog.Info($"Specifiers check failed. Producer={producerId}, market[id={marketId}], Required:{requiredSpecifiers}, Actual:{actualSpecifiers}"); return(false); } foreach (var specifier in marketDescriptor.Specifiers) { var keyValuePair = specifiers.FirstOrDefault(f => f.Key == specifier.Name); if (string.IsNullOrEmpty(keyValuePair.Value)) { var requiredSpecifiers = string.Join(",", marketDescriptor.Specifiers.Select(d => d.Name)); var actualSpecifiers = string.Join(",", specifiers.Select(k => k.Key)); ExecutionLog.Info($"Specifiers check for market[id={marketId}] failed. Required:{requiredSpecifiers}, Actual:{actualSpecifiers}"); return(false); } } } return(true); }
/// <summary> /// Returns the unmodified market name template /// </summary> /// <param name="culture">The culture in which the name template should be provided</param> /// <returns>The unmodified market name template</returns> public string GetNameTemplate(CultureInfo culture) { // name templates need to be always fetched from the cache because of the variant markets (they are not being fetched on market definition creation) //string variant = null; //_specifiers?.TryGetValue("variant", out variant); var marketDescription = _marketCacheProvider.GetMarketDescriptionAsync((int)_marketDescription.Id, _specifiers, new[] { culture }, true).Result; return(marketDescription?.GetName(culture)); }
/// <summary> /// Builds a <see cref="IMarketDefinition" /> associated with the provided data /// </summary> /// <param name="marketId">the id of the market</param> /// <param name="sportId">the sport id</param> /// <param name="producer">the source of the market</param> /// <param name="specifiers">the received market specifiers</param> /// <param name="cultures">the cultures in which the market data should be prefetched</param> /// <returns></returns> private IMarketDefinition BuildMarketDefinition(int marketId, URN sportId, IProducer producer, IReadOnlyDictionary <string, string> specifiers, IEnumerable <CultureInfo> cultures) { // market descriptor should exist or else the market generation would fail // variant always null because we are interested only in the general market attributes IMarketDescription marketDescription = null; try { marketDescription = _marketCacheProvider.GetMarketDescriptionAsync(marketId, specifiers, cultures, false).Result; } catch (CacheItemNotFoundException) { ExecutionLog.Warn($"Market description for market={marketId}, sport={sportId} and producer={producer.Name} not found."); } return(marketDescription == null ? null : new MarketDefinition(marketDescription, _marketCacheProvider, sportId, producer, specifiers)); }
/// <summary> /// Returns the unmodified market name template /// </summary> /// <param name="culture">The culture in which the name template should be provided</param> /// <returns>The unmodified market name template</returns> public string GetNameTemplate(CultureInfo culture) { if (_names.Any()) { return(_names.ContainsKey(culture) ? _names[culture] : null); } if (string.IsNullOrEmpty(_outcomeId)) { return(null); } try { var marketDescription = _marketCacheProvider.GetMarketDescriptionAsync((int)_marketDescription.Id, _specifiers, _cultures, true).Result; if (marketDescription?.Outcomes == null || !marketDescription.Outcomes.Any()) { return(null); } var outcomeDescription = marketDescription.Outcomes.FirstOrDefault(s => s.Id.Equals(_outcomeId, StringComparison.InvariantCultureIgnoreCase)); if (outcomeDescription == null) { throw new CacheItemNotFoundException("Item not found", nameof(_outcomeId), null); } foreach (var cultureInfo in _cultures) { _names[cultureInfo] = outcomeDescription.GetName(cultureInfo); } } catch (CacheItemNotFoundException e) { if (_exceptionHandlingStrategy == ExceptionHandlingStrategy.THROW) { throw new CacheItemNotFoundException("Could not provide the requested translated name", nameof(_outcomeId), e); } } return(_names.ContainsKey(culture) ? _names[culture] : null); }
/// <summary> /// Asynchronously gets a <see cref="IMarketDescription"/> instance describing the specified market in the specified language /// </summary> /// <returns>A <see cref="Task{IMarketDescriptor}"/> representing the asynchronous operation</returns> /// <exception cref="CacheItemNotFoundException">The requested key was not found in the cache and could not be loaded</exception> private async Task <IMarketDescription> GetMarketDescriptorAsync(IEnumerable <CultureInfo> cultures) { try { //fetch the market description from the invariant market cache to get the mapping information var marketDescriptor = await _marketCacheProvider.GetMarketDescriptionAsync(_marketId, _specifiers, cultures, true).ConfigureAwait(false); if (marketDescriptor == null) { ExecutionLog.LogWarning($"An error occurred getting marketDescription for marketId={_marketId}."); } return(marketDescriptor); } catch (CacheItemNotFoundException ex) { HandleMappingErrorCondition("Failed to retrieve market name descriptor", "MarketId", _marketId.ToString(), string.Empty, ex); return(null); } }
/// <summary> /// Gets a <see cref="IMarketDefinition" /> associated with the provided data /// </summary> private void GetMarketDefinition() { // market descriptor should exist or else the market generation would fail // variant always null because we are interested only in the general market attributes if (_marketDescription != null) { return; } lock (_lock) { if (_marketDescription != null) { return; } try { _marketDescription = _marketCacheProvider.GetMarketDescriptionAsync(_marketId, _specifiers, _cultures, true).Result; // was false and true in GetNameTemplate } catch (CacheItemNotFoundException ci) { if (_exceptionHandlingStrategy == ExceptionHandlingStrategy.THROW) { throw new CacheItemNotFoundException($"Market description for market={_marketId}, sport={_sportId} and producer={_producerId} not found.", _marketId.ToString(), ci); } } catch (Exception ex) { if (_exceptionHandlingStrategy == ExceptionHandlingStrategy.THROW) { throw new CacheItemNotFoundException($"Market description for market={_marketId} not found.", _marketId.ToString(), ex); } } } }
/// <summary> /// Asynchronously gets a <see cref="IEnumerable{IMarketMappingData}"/> of available mappings for the provided marketId/producer combination /// </summary> /// <param name="marketId">The id of the market for which you need the mapping</param> /// <param name="specifiers">The associated market specifiers</param> /// <param name="producer">The <see cref="IProducer"/> for which you need the mapping</param> /// <returns>A <see cref="IEnumerable{IMarketMappingData}"/> of available mappings for the provided marketId/producer combination</returns> public async Task <IEnumerable <IMarketMappingData> > GetMarketMappingAsync(int marketId, IReadOnlyDictionary <string, string> specifiers, IProducer producer) { IMarketDescription marketDescriptor; try { marketDescriptor = await _marketCacheProvider.GetMarketDescriptionAsync(marketId, specifiers, new[] { _config.DefaultLocale }, false).ConfigureAwait(false); } catch (Exception ex) { var specifiersMessage = specifiers != null ? $", specifiers: {string.Join("; ", specifiers)}" : string.Empty; if (_exceptionHandlingStrategy == ExceptionHandlingStrategy.THROW) { throw new ObjectNotFoundException($"Market mappings for {marketId} could not be provided{specifiersMessage}", ex); } _executionLog.Warn($"Market mappings for the marketId: {marketId} could not be provided{specifiersMessage}", ex); return(null); } return(marketDescriptor.Mappings?.Where(m => m.ProducerIds.Contains(producer.Id)).ToList() ?? Enumerable.Empty <IMarketMappingData>()); }
/// <summary> /// Asynchronously gets a <see cref="IMarketDescription"/> instance describing the specified market in the specified language /// </summary> /// <param name="culture">The <see cref="CultureInfo"/> specifying the language of the returned descriptor</param> /// <returns>A <see cref="Task{IMarketDescriptor}"/> representing the asynchronous operation</returns> /// <exception cref="CacheItemNotFoundException">The requested key was not found in the cache and could not be loaded</exception> private async Task <IMarketDescription> GetMarketDescriptorAsync(CultureInfo culture) { Guard.Argument(culture, nameof(culture)).NotNull(); return(await _marketCacheProvider.GetMarketDescriptionAsync(_marketId, _specifiers, new[] { culture }, true).ConfigureAwait(false)); }