/// <summary> /// Does item exists in the cache /// </summary> /// <param name="id">A <see cref="URN" /> representing the id of the item to be checked</param> /// <param name="cacheItemType">A cache item type</param> /// <returns><c>true</c> if exists, <c>false</c> otherwise</returns> public abstract bool CacheHasItem(URN id, CacheItemType cacheItemType);
private void AddCompetitor(ExportableCompetitorCI item) { if (_cache.Contains(item.Id)) { var itemId = URN.Parse(item.Id); try { var ci = (CompetitorCI)_cache.Get(item.Id); WaitTillIdIsAvailable(_mergeUrns, itemId); ci?.Import(item); } catch (Exception ex) { ExecutionLog.LogError(ex, $"Error importing competitor for id={item.Id}."); } finally { if (!_isDisposed) { ReleaseId(_mergeUrns, itemId); } } } else { if (!string.IsNullOrEmpty(item.Id)) { _cache.Add(item.Id, new CompetitorCI(item, _dataRouterManager), GetCorrectCacheItemPolicy(URN.Parse(item.Id))); } } }
/// <summary> /// Gets the outcome name from profile /// </summary> /// <param name="outcomeId">The outcome identifier</param> /// <param name="culture">The language of the returned name</param> /// <returns>A <see cref="Task{String}"/> representing the async operation</returns> /// <exception cref="NameExpressionException">The name of the specified outcome could not be generated</exception> private async Task <string> GetOutcomeNameFromProfileAsync(string outcomeId, CultureInfo culture) { var idParts = outcomeId.Split(new[] { SdkInfo.NameProviderCompositeIdSeparator }, StringSplitOptions.RemoveEmptyEntries); var names = new List <string>(idParts.Length); foreach (var idPart in idParts) { URN profileId; try { profileId = URN.Parse(idPart); } catch (FormatException ex) { throw new NameExpressionException($"OutcomeId={idPart} is not a valid URN", ex); } try { var fetchCultures = new[] { culture }; if (idPart.StartsWith(SdkInfo.PlayerProfileMarketPrefix)) { // first try to fetch all the competitors for the sportEvent, so all player profiles are preloaded if (!_competitorsAlreadyFetched) { var competitionEvent = _sportEvent as ICompetition; if (competitionEvent != null) { try { var competitors = await competitionEvent.GetCompetitorsAsync().ConfigureAwait(false); var competitorsList = competitors.ToList(); if (!competitorsList.Any()) { continue; } var tasks = competitorsList.Select(s => _profileCache.GetCompetitorProfileAsync(s.Id, fetchCultures)); await Task.WhenAll(tasks).ConfigureAwait(false); } catch (Exception ex) { ExecutionLog.LogDebug("Error fetching all competitor profiles", ex); } } _competitorsAlreadyFetched = true; } var profile = await _profileCache.GetPlayerProfileAsync(profileId, fetchCultures).ConfigureAwait(false); names.Add(profile.GetName(culture)); continue; } if (idPart.StartsWith(SdkInfo.CompetitorProfileMarketPrefix)) { var profile = await _profileCache.GetCompetitorProfileAsync(profileId, fetchCultures).ConfigureAwait(false); names.Add(profile.GetName(culture)); continue; } } catch (CacheItemNotFoundException ex) { throw new NameExpressionException("Error occurred while evaluating name expression", ex); } throw new ArgumentException($"OutcomeId={idPart} must start with 'sr:player:' or 'sr:competitor'"); } return(string.Join(SdkInfo.NameProviderCompositeIdSeparator, names)); }
/// <summary> /// Builds and returns a new instance of the <see cref="INameProvider" /> /// </summary> /// <param name="sportEvent">A <see cref="ISportEvent" /> instance representing associated sport @event</param> /// <param name="marketId">A market identifier, identifying the market associated with the returned instance</param> /// <param name="specifiers">A <see cref="IReadOnlyDictionary{String, String}" /> representing specifiers of the associated market</param> /// <param name="producerId">An id of the <see cref="IProducer"/> of the <see cref="ISportEvent"/></param> /// <param name="sportId">A sportId of the <see cref="ISportEvent"/></param> /// <returns>Returns an instance of <see cref="IMarketMappingProvider"/></returns> public IMarketMappingProvider BuildMarketMappingProvider(ISportEvent sportEvent, int marketId, IReadOnlyDictionary <string, string> specifiers, int producerId, URN sportId) { return(new MarketMappingProvider(_marketCacheProvider, _eventStatusCache, sportEvent, marketId, specifiers, producerId, sportId, _exceptionStrategy)); }
/// <summary> /// Adds the dto item to cache /// </summary> /// <param name="id">The identifier of the object</param> /// <param name="item">The item</param> /// <param name="culture">The culture</param> /// <param name="dtoType">Type of the dto</param> /// <param name="requester">The cache item which invoked request</param> /// <returns><c>true</c> if added, <c>false</c> otherwise</returns> protected override bool CacheAddDtoItem(URN id, object item, CultureInfo culture, DtoType dtoType, ISportEventCI requester) { if (_isDisposed) { return(false); } var saved = false; switch (dtoType) { case DtoType.MatchSummary: if (SaveCompetitorsFromSportEvent(item, culture)) { saved = true; } else { LogSavingDtoConflict(id, typeof(MatchDTO), item.GetType()); } break; case DtoType.RaceSummary: if (SaveCompetitorsFromSportEvent(item, culture)) { saved = true; } else { LogSavingDtoConflict(id, typeof(StageDTO), item.GetType()); } break; case DtoType.TournamentInfo: if (SaveCompetitorsFromSportEvent(item, culture)) { saved = true; } else { LogSavingDtoConflict(id, typeof(TournamentInfoDTO), item.GetType()); } break; case DtoType.SportEventSummary: if (SaveCompetitorsFromSportEvent(item, culture)) { saved = true; } else { LogSavingDtoConflict(id, typeof(SportEventSummaryDTO), item.GetType()); } break; case DtoType.Sport: break; case DtoType.Category: break; case DtoType.Tournament: break; case DtoType.PlayerProfile: var playerProfile = item as PlayerProfileDTO; if (playerProfile != null) { AddPlayerProfile(playerProfile, null, culture, true); saved = true; } else { LogSavingDtoConflict(id, typeof(PlayerProfileDTO), item.GetType()); } break; case DtoType.Competitor: var competitor = item as CompetitorDTO; if (competitor != null) { AddCompetitor(id, competitor, culture, true); saved = true; } else { LogSavingDtoConflict(id, typeof(CompetitorDTO), item.GetType()); } break; case DtoType.CompetitorProfile: var competitorProfile = item as CompetitorProfileDTO; if (competitorProfile != null) { AddCompetitorProfile(id, competitorProfile, culture, true); saved = true; } else { LogSavingDtoConflict(id, typeof(CompetitorProfileDTO), item.GetType()); } break; case DtoType.SimpleTeamProfile: var simpleTeamProfile = item as SimpleTeamProfileDTO; if (simpleTeamProfile != null) { AddCompetitorProfile(id, simpleTeamProfile, culture, true); saved = true; } else { LogSavingDtoConflict(id, typeof(SimpleTeamProfileDTO), item.GetType()); } break; case DtoType.MarketDescription: break; case DtoType.SportEventStatus: break; case DtoType.MatchTimeline: var matchTimeline = item as MatchTimelineDTO; if (matchTimeline != null) { saved = SaveCompetitorsFromSportEvent(matchTimeline.SportEvent, culture); } else { LogSavingDtoConflict(id, typeof(MatchTimelineDTO), item.GetType()); } break; case DtoType.TournamentSeasons: var tournamentSeason = item as TournamentSeasonsDTO; if (tournamentSeason?.Tournament != null) { SaveCompetitorsFromSportEvent(tournamentSeason.Tournament, culture); saved = true; } break; case DtoType.Fixture: if (SaveCompetitorsFromSportEvent(item, culture)) { saved = true; } else { LogSavingDtoConflict(id, typeof(FixtureDTO), item.GetType()); } break; case DtoType.SportList: break; case DtoType.SportEventSummaryList: var sportEventSummaryList = item as EntityList <SportEventSummaryDTO>; if (sportEventSummaryList != null) { foreach (var sportEventSummary in sportEventSummaryList.Items) { SaveCompetitorsFromSportEvent(sportEventSummary, culture); } saved = true; } else { LogSavingDtoConflict(id, typeof(SportEventSummaryDTO), item.GetType()); } break; case DtoType.MarketDescriptionList: break; case DtoType.VariantDescription: break; case DtoType.VariantDescriptionList: break; case DtoType.Lottery: break; case DtoType.LotteryDraw: break; case DtoType.LotteryList: break; case DtoType.BookingStatus: break; case DtoType.SportCategories: break; case DtoType.AvailableSelections: break; case DtoType.TournamentInfoList: var ts = item as EntityList <TournamentInfoDTO>; if (ts != null) { foreach (var t1 in ts.Items) { SaveCompetitorsFromSportEvent(t1, culture); } saved = true; } else { LogSavingDtoConflict(id, typeof(EntityList <TournamentInfoDTO>), item.GetType()); } break; default: ExecutionLog.LogWarning($"Trying to add unchecked dto type: {dtoType} for id: {id}."); break; } return(saved); }
/// <summary> /// Gets a <see cref="ICompetition"/> representing the specified sport event in language specified by <code>culture</code> or a null reference if the sport event with /// specified <code>id</code> does not exist /// </summary> /// <param name="id">A <see cref="URN"/> specifying the sport event to retrieve</param> /// <param name="culture">A <see cref="CultureInfo"/> specifying the language or a null reference to use the languages specified in the configuration</param> /// <returns>A <see cref="ICompetition"/> representing the specified sport event or a null reference if the requested sport event does not exist</returns> public ICompetition GetCompetition(URN id, CultureInfo culture = null) { Log.Info($"Invoked GetCompetition: Id={id}, Culture={culture}"); return(GetCompetition(id, null, culture)); }
/// <summary> /// Delete the competitor from cache /// </summary> /// <param name="id">A <see cref="URN"/> specifying the id of <see cref="ICompetitor"/> to be deleted</param> public void DeleteCompetitorFromCache(URN id) { Log.Info($"Invoked DeleteCompetitorFromCache: Id={id}"); _cacheManager.RemoveCacheItem(id, CacheItemType.Competitor, "SportDataProvider"); }
/// <summary> /// Builds the <see cref="ISportEvent" /> derived class based on specified id /// </summary> /// <typeparam name="T">A <see cref="ISportEvent" /> derived type</typeparam> /// <param name="id">The identifier</param> /// <param name="sportId">The sport identifier</param> /// <param name="cultures">The cultures used for returned instance</param> /// <param name="exceptionStrategy">A <see cref="ExceptionHandlingStrategy"/> enum member specifying how the build instance will handle potential exceptions</param> /// <returns>The constructed <see cref="ICompetition"/> derived instance</returns> public T BuildSportEvent <T>(URN id, URN sportId, IEnumerable <CultureInfo> cultures, ExceptionHandlingStrategy exceptionStrategy) where T : ISportEvent { ISportEvent sportEvent; switch (id.TypeGroup) { case ResourceTypeGroup.MATCH: { if (sportId != null && sportId.Equals(URN.Parse("sr:sport:1"))) { sportEvent = new SoccerEvent(id, sportId, this, _sportEventCache, _eventStatusCache, _matchStatusCache, cultures, exceptionStrategy); } else { sportEvent = new Match(id, sportId, this, _sportEventCache, _eventStatusCache, _matchStatusCache, cultures, exceptionStrategy); } break; } case ResourceTypeGroup.STAGE: { sportEvent = new Stage(id, sportId, this, _sportEventCache, _sportDataCache, _eventStatusCache, _matchStatusCache, cultures, exceptionStrategy); break; } case ResourceTypeGroup.BASIC_TOURNAMENT: { sportEvent = new BasicTournament(id, sportId, this, _sportEventCache, _sportDataCache, cultures, exceptionStrategy); break; } case ResourceTypeGroup.TOURNAMENT: { sportEvent = new Tournament(id, sportId, this, _sportEventCache, _sportDataCache, cultures, exceptionStrategy); break; } case ResourceTypeGroup.SEASON: { sportEvent = new Season(id, sportId, this, _sportEventCache, _sportDataCache, cultures, exceptionStrategy); break; } case ResourceTypeGroup.DRAW: { sportEvent = new Draw(id, sportId, _sportEventCache, cultures, exceptionStrategy); break; } case ResourceTypeGroup.LOTTERY: { sportEvent = new Lottery(id, sportId, _sportEventCache, _sportDataCache, cultures, exceptionStrategy); break; } case ResourceTypeGroup.UNKNOWN: { sportEvent = new SportEvent(id, sportId, null, _sportEventCache, cultures, exceptionStrategy); break; } default: throw new ArgumentException($"ResourceTypeGroup:{id.TypeGroup} is not supported", nameof(id)); } return((T)sportEvent); }
/// <summary> /// Adds the item to the all registered caches /// </summary> /// <param name="id">The identifier of the item</param> /// <param name="item">The item to be add</param> /// <param name="culture">The culture of the data-transfer-object</param> /// <param name="dtoType">Type of the dto item</param> /// <param name="requester">The cache item which invoked request</param> /// <returns><c>true</c> if is added/updated, <c>false</c> otherwise</returns> public void SaveDto(URN id, object item, CultureInfo culture, DtoType dtoType, ISportEventCI requester) { SaveDtoAsync(id, item, culture, dtoType, requester).Wait(); }
/// <summary> /// Initializes a new instance of the <see cref="CompetitionCI" /> class /// </summary> /// <param name="exportable">A <see cref="ExportableSportEventCI" /> representing the sport event</param> /// <param name="dataRouterManager">The <see cref="IDataRouterManager"/> used to obtain summary and fixture</param> /// <param name="semaphorePool">A <see cref="ISemaphorePool" /> instance used to obtain sync objects</param> /// <param name="defaultCulture">A <see cref="CultureInfo" /> specifying the language used when fetching info which is not translatable (e.g. Scheduled, ..)</param> /// <param name="fixtureTimestampCache">A <see cref="ObjectCache"/> used to cache the sport events fixture timestamps</param> public CompetitionCI(ExportableSportEventCI exportable, IDataRouterManager dataRouterManager, ISemaphorePool semaphorePool, CultureInfo defaultCulture, ObjectCache fixtureTimestampCache) : base(exportable, dataRouterManager, semaphorePool, defaultCulture, fixtureTimestampCache) { var exportableCompetition = exportable as ExportableCompetitionCI; _bookingStatus = exportableCompetition.BookingStatus; _venue = exportableCompetition.Venue != null ? new VenueCI(exportableCompetition.Venue) : null; _conditions = exportableCompetition.Conditions != null ? new SportEventConditionsCI(exportableCompetition.Conditions) : null; Competitors = exportableCompetition.Competitors != null ? new List <URN>(exportableCompetition.Competitors.Select(URN.Parse)) : null; _referenceId = exportableCompetition.ReferenceId != null ? new ReferenceIdCI(exportableCompetition.ReferenceId) : null; _competitorsQualifiers = exportableCompetition.CompetitorsQualifiers != null ? new Dictionary <URN, string>(exportableCompetition.CompetitorsQualifiers.ToDictionary(c => URN.Parse(c.Key), c => c.Value)) : null; _competitorsReferences = exportableCompetition.CompetitorsReferences != null ? new Dictionary <URN, ReferenceIdCI>(exportableCompetition.CompetitorsReferences.ToDictionary(c => URN.Parse(c.Key), c => new ReferenceIdCI(c.Value))) : null; }
/// <summary> /// Adds the dto item to cache /// </summary> /// <param name="id">The identifier of the object</param> /// <param name="item">The item</param> /// <param name="culture">The culture</param> /// <param name="dtoType">Type of the dto</param> /// <param name="requester">The cache item which invoked request</param> /// <returns><c>true</c> if added, <c>false</c> otherwise</returns> protected override bool CacheAddDtoItem(URN id, object item, CultureInfo culture, DtoType dtoType, ISportEventCI requester) { Guard.Argument(id, nameof(id)).NotNull(); Guard.Argument(item, nameof(item)).NotNull(); if (_isDisposed) { return(false); } var saved = false; switch (dtoType) { case DtoType.Category: break; case DtoType.Competitor: break; case DtoType.CompetitorProfile: break; case DtoType.SimpleTeamProfile: break; case DtoType.Fixture: var fixtureDTO = item as FixtureDTO; if (fixtureDTO != null) { if (fixtureDTO.SportEventStatus != null) { AddSportEventStatus(id, new SportEventStatusCI(null, fixtureDTO.SportEventStatus), fixtureDTO.StatusOnEvent, "Fixture"); } saved = true; } else { LogSavingDtoConflict(id, typeof(FixtureDTO), item.GetType()); } break; case DtoType.MarketDescription: break; case DtoType.MatchSummary: var matchDTO = item as MatchDTO; if (matchDTO != null) { if (matchDTO.SportEventStatus != null) { AddSportEventStatus(id, new SportEventStatusCI(null, matchDTO.SportEventStatus), matchDTO.StatusOnEvent, "Match"); } saved = true; } else { LogSavingDtoConflict(id, typeof(MatchDTO), item.GetType()); } break; case DtoType.MatchTimeline: var matchTimelineDTO = item as MatchTimelineDTO; if (matchTimelineDTO != null) { if (matchTimelineDTO.SportEventStatus != null) { AddSportEventStatus(id, new SportEventStatusCI(null, matchTimelineDTO.SportEventStatus), matchTimelineDTO.SportEvent.StatusOnEvent, "MatchTimeline"); } saved = true; } else { LogSavingDtoConflict(id, typeof(MatchTimelineDTO), item.GetType()); } break; case DtoType.PlayerProfile: break; case DtoType.RaceSummary: var stageDTO = item as StageDTO; if (stageDTO != null) { if (stageDTO.SportEventStatus != null) { AddSportEventStatus(id, new SportEventStatusCI(null, stageDTO.SportEventStatus), stageDTO.StatusOnEvent, "Stage"); } saved = true; } else { LogSavingDtoConflict(id, typeof(StageDTO), item.GetType()); } break; case DtoType.Sport: break; case DtoType.SportList: break; case DtoType.SportEventStatus: var sportEventStatusDTO = item as SportEventStatusDTO; if (sportEventStatusDTO != null) { AddSportEventStatus(id, new SportEventStatusCI(sportEventStatusDTO, null), sportEventStatusDTO.Status.ToString(), "OddsChange"); saved = true; } else { LogSavingDtoConflict(id, typeof(SportEventStatusDTO), item.GetType()); } break; case DtoType.SportEventSummary: var competitionDTO = item as CompetitionDTO; if (competitionDTO != null) { if (competitionDTO.SportEventStatus != null) { AddSportEventStatus(id, new SportEventStatusCI(null, competitionDTO.SportEventStatus), competitionDTO.StatusOnEvent, "SportEventSummary"); } saved = true; } break; case DtoType.SportEventSummaryList: var summaryList = item as EntityList <SportEventSummaryDTO>; if (summaryList != null) { foreach (var s in summaryList.Items) { var compDTO = s as CompetitionDTO; if (compDTO?.SportEventStatus != null) { AddSportEventStatus(id, new SportEventStatusCI(null, compDTO.SportEventStatus), s.StatusOnEvent, "SportEventSummaryList"); } } saved = true; } else { LogSavingDtoConflict(id, typeof(EntityList <SportEventSummaryDTO>), item.GetType()); } break; case DtoType.Tournament: break; case DtoType.TournamentInfo: break; case DtoType.TournamentSeasons: break; case DtoType.MarketDescriptionList: break; case DtoType.VariantDescription: break; case DtoType.VariantDescriptionList: break; case DtoType.Lottery: break; case DtoType.LotteryDraw: break; case DtoType.LotteryList: break; case DtoType.BookingStatus: break; case DtoType.SportCategories: break; case DtoType.AvailableSelections: break; case DtoType.TournamentInfoList: break; default: ExecutionLog.Warn($"Trying to add unchecked dto type: {dtoType} for id: {id}."); break; } //CacheLog.Debug($"Saving {id} COMPLETED. Saved={saved}."); return(saved); }
public ICustomBetSelectionBuilder SetEventId(URN eventId) { _eventId = eventId; return(this); }
/// <summary> /// Merges the specified dto /// </summary> /// <param name="dto">The dto</param> /// <param name="culture">The culture</param> private void ActualMerge(TournamentInfoDTO dto, CultureInfo culture) { base.Merge(dto, culture, false); if (dto.Category != null) { _categoryId = dto.Category.Id; } if (dto.TournamentCoverage != null) { _tournamentCoverage = new TournamentCoverageCI(dto.TournamentCoverage); } if (dto.Competitors != null) { if (_competitors == null) { _competitors = new List <CompetitorCI>(dto.Competitors.Select(t => new CompetitorCI(t, culture, DataRouterManager))); } else { MergeCompetitors(dto.Competitors, culture); } FillCompetitorsReferences(dto.Competitors); } if (dto.CurrentSeason != null) { if (_currentSeasonInfo == null) { _currentSeasonInfo = new CurrentSeasonInfoCI(dto.CurrentSeason, culture, DataRouterManager); } else { _currentSeasonInfo.Merge(dto.CurrentSeason, culture); } } if (dto.Groups != null) { if (_groups == null) { _groups = new List <GroupCI>(dto.Groups.Select(s => new GroupCI(s, culture, DataRouterManager))); } else { MergeGroups(dto.Groups, culture); } var comps = new List <CompetitorDTO>(); foreach (var groupDTO in dto.Groups) { comps.AddRange(groupDTO.Competitors); } FillCompetitorsReferences(comps); } if (dto.Schedule != null) { _scheduleUrns = new ReadOnlyCollection <URN>(dto.Schedule.Select(s => s.Id).ToList()); } if (dto.CurrentRound != null) { if (_round == null) { _round = new RoundCI(dto.CurrentRound, culture); } else { _round.Merge(dto.CurrentRound, culture); } } if (!string.IsNullOrEmpty(dto.Year)) { _year = dto.Year; } if (dto.TournamentInfo != null) { if (_tournamentInfoBasic == null) { _tournamentInfoBasic = new TournamentInfoBasicCI(dto.TournamentInfo, culture, DataRouterManager); } else { _tournamentInfoBasic.Merge(dto.TournamentInfo, culture); } } if (dto.SeasonCoverage != null) { _seasonCoverage = new SeasonCoverageCI(dto.SeasonCoverage); } }
/// <summary> /// Adds the dto item to cache /// </summary> /// <param name="id">The identifier of the object</param> /// <param name="item">The item to be added</param> /// <param name="culture">The culture of the item</param> /// <param name="dtoType">Type of the dto</param> /// <param name="requester">The cache item which invoked request</param> /// <returns><c>true</c> if added, <c>false</c> otherwise</returns> protected abstract bool CacheAddDtoItem(URN id, object item, CultureInfo culture, DtoType dtoType, ISportEventCI requester);
/// <summary> /// Maps (converts) the provided <see cref="rollback_bet_settlement"/> instance to the <see cref="IRollbackBetSettlement{T}"/> instance /// </summary> /// <param name="message">A <see cref="rollback_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="IRollbackBetSettlement{T}"/> instance constructed from information in the provided <see cref="rollback_bet_settlement"/></returns> public IRollbackBetSettlement <T> MapRollbackBetSettlement <T>(rollback_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 RollbackBetSettlement <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.market.Select(m => GetMarketCancel(GetEventForNameProvider <T>(URN.Parse(message.event_id), message.SportId, culturesList), m, message.ProducerId, message.SportId, culturesList)), rawMessage)); }
private async Task <MatchCI> GetMatchCacheItemAsync(URN matchId, CultureInfo culture, Stopwatch stopWatch, int i) { MatchCI ci = null; var startTime = stopWatch.Elapsed; try { Debug.WriteLine($"{GetElapsed(stopWatch)} Loading {i} culture: {culture.TwoLetterISOLanguageName}"); ci = (MatchCI)_sportEventCache.GetEventCacheItem(matchId); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} culture: {culture.TwoLetterISOLanguageName}"); var name = await ci.GetNamesAsync(new[] { culture }).ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} name: {name?.Values.First()}"); var fixture = await ci.GetFixtureAsync(new[] { culture }).ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} fixture: {fixture.StartTime}"); var tournamentId = await ci.GetTournamentIdAsync(TestData.Cultures).ConfigureAwait(false); // Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} tournament: {tournamentId}"); var bookingStatus = await ci.GetBookingStatusAsync().ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} booking status: {bookingStatus}"); var competitorIds = await ci.GetCompetitorsIdsAsync(new[] { culture }).ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} competitors: {string.Join(",", competitorIds.Select(s => s.ToString()))}"); var venue = await ci.GetVenueAsync(new[] { culture }).ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} venue: {venue?.Id}"); var liveOdds = await ci.GetLiveOddsAsync().ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} live odds: {liveOdds}"); var sportEventType = await ci.GetSportEventTypeAsync().ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} sport event type: {sportEventType}"); var stageType = await ci.GetStageTypeAsync().ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} stage type: {stageType}"); var status = await ci.FetchSportEventStatusAsync().ConfigureAwait(false); //Debug.WriteLine($"{GetElapsed(stopWatch)} Get {i} status: {status}"); Debug.WriteLine($"{GetElapsed(stopWatch)} Tasks {i} completed."); if (i % 10 == 3) { Debug.WriteLine($"{GetElapsed(stopWatch)} Deleting {i} culture: {culture.TwoLetterISOLanguageName}"); _sportEventCache.CacheDeleteItem(matchId, CacheItemType.All); } } catch (Exception e) { Debug.WriteLine($"{GetElapsed(stopWatch)} Error: {e}"); } var took = stopWatch.Elapsed - startTime; Debug.WriteLine($"{GetElapsed(stopWatch)} Iteration {i} completed. Took {took.Milliseconds} ms."); return(ci); }
/// <summary> /// Initializes a new instance of the <see cref="IGoalScorer" /> class /// </summary> /// <param name="id">The <see cref="URN" /> uniquely identifying the current <see cref="IPlayer" /> instance</param> /// <param name="names">A <see cref="IDictionary{TKey,TValue}" /> containing player names in different languages</param> public GoalScorer(URN id, IDictionary <CultureInfo, string> names) : base(id, names as IReadOnlyDictionary <CultureInfo, string>) { Contract.Requires(id != null); }
public void competitor_profile_is_called_when_wanted_player_profile() { var match = new TestSportEntityFactory().BuildSportEvent <IMatch>(URN.Parse("sr:match:1"), URN.Parse("sr:sport:5"), TestData.Cultures, ExceptionHandlingStrategy.THROW); _nameProvider = new NameProvider( new Mock <IMarketCacheProvider>().Object, _profileCache, new Mock <INameExpressionFactory>().Object, match, 1, null, ExceptionHandlingStrategy.THROW); const string callType1 = "GetPlayerProfileAsync"; const string callType2 = "GetCompetitorAsync"; Assert.AreEqual(0, _memoryCache.Count()); Assert.AreEqual(0, _dataRouterManager.GetCallCount(callType1), $"{callType1} should be called 0 time."); Assert.AreEqual(0, _dataRouterManager.GetCallCount(callType2), $"{callType2} should be called 0 time."); var name = _nameProvider.GetOutcomeNameAsync("sr:player:1", TestData.Cultures.First()).Result; Assert.AreEqual("van Persie, Robin", name, "The generated name is not correct"); Assert.AreEqual(61 + 2, _memoryCache.Count()); Assert.AreEqual(0, _dataRouterManager.GetCallCount(callType1), $"{callType1} should be called 0 time."); Assert.AreEqual(2, _dataRouterManager.GetCallCount(callType2), $"{callType2} should be called 2 time."); }
/// <summary> /// Delete the tournament from cache /// </summary> /// <param name="id">A <see cref="URN"/> specifying the id of <see cref="ILongTermEvent"/> to be deleted</param> public void DeleteTournamentFromCache(URN id) { Log.Info($"Invoked DeleteTournamentFromCache: Id={id}"); _cacheManager.RemoveCacheItem(id, CacheItemType.SportEvent, "SportDataProvider"); }
/// <summary> /// Gets the new <see cref="IMarketWithSettlement"/> instance /// </summary> /// <param name="sportEvent">A <see cref="ISportEvent"/> representing the sport event associated with the generated message</param> /// <param name="marketSettlement">The <see cref="betSettlementMarket"/> instance used</param> /// <param name="producerId">A producerId of the <see cref="ISportEvent"/></param> /// <param name="sportId">A producerId of the <see cref="ISportEvent"/></param> /// <param name="cultures">The list of cultures that should be prefetched</param> /// <returns>Returns the new <see cref="IMarketWithSettlement"/> instance</returns> protected virtual IMarketWithSettlement GetMarketWithResults(ISportEvent sportEvent, betSettlementMarket marketSettlement, int producerId, URN sportId, IEnumerable <CultureInfo> cultures) { Guard.Argument(sportEvent, nameof(sportEvent)).NotNull(); Guard.Argument(marketSettlement, nameof(marketSettlement)).NotNull(); var cultureInfos = cultures.ToList(); var specifiers = string.IsNullOrEmpty(marketSettlement.specifiers) ? null : FeedMapperHelper.GetSpecifiers(marketSettlement.specifiers); var additionalInfo = string.IsNullOrEmpty(marketSettlement.extended_specifiers) ? null : FeedMapperHelper.GetSpecifiers(marketSettlement.extended_specifiers); var producer = _producerManager.Get(producerId); var nameProvider = _nameProviderFactory.BuildNameProvider(sportEvent, marketSettlement.id, specifiers); var mappingProvider = _mappingProviderFactory.BuildMarketMappingProvider(sportEvent, marketSettlement.id, specifiers, _producerManager.Get(producerId), sportId); var outcomes = marketSettlement.Items.Select(outcome => new OutcomeSettlement( outcome.dead_heat_factorSpecified ? (double?)outcome.dead_heat_factor : null, outcome.id, outcome.result != 0, MessageMapperHelper.GetVoidFactor(outcome.void_factorSpecified, outcome.void_factor), nameProvider, mappingProvider, cultureInfos, BuildOutcomeDefinition(marketSettlement.id, sportId, producer, specifiers, outcome.id, cultureInfos))); return(new MarketWithSettlement(marketSettlement.id, specifiers, additionalInfo, outcomes, nameProvider, mappingProvider, BuildMarketDefinition(marketSettlement.id, sportId, producer, specifiers, cultureInfos), marketSettlement.void_reasonSpecified ? (int?)marketSettlement.void_reason : null, _namedValuesProvider.VoidReasons, cultureInfos)); }
/// <summary> /// Delete the player profile from cache /// </summary> /// <param name="id">A <see cref="URN"/> specifying the id of <see cref="IPlayerProfile"/> to be deleted</param> public void DeletePlayerProfileFromCache(URN id) { Log.Info($"Invoked DeletePlayerProfileFromCache: Id={id}"); _cacheManager.RemoveCacheItem(id, CacheItemType.Player, "SportDataProvider"); }
/// <summary> /// Gets the new <see cref="IMarketWithProbabilities"/> instance /// </summary> /// <param name="sportEvent">A <see cref="ISportEvent"/> representing the sport event associated with the generated message</param> /// <param name="marketOddsChange">The <see cref="oddsChangeMarket"/> instance used</param> /// <param name="producerId">A producerId specifying message producer</param> /// <param name="sportId">A sportId of the <see cref="ISportEvent"/></param> /// <param name="cultures">The list of cultures that should be prefetched</param> /// <returns>Returns the new <see cref="IMarketWithOdds"/> instance</returns> protected virtual IMarketWithProbabilities GetMarketWithProbabilities(ISportEvent sportEvent, oddsChangeMarket marketOddsChange, int producerId, URN sportId, IEnumerable <CultureInfo> cultures) { var cultureInfos = cultures.ToList(); var specifiers = string.IsNullOrEmpty(marketOddsChange.specifiers) ? null : FeedMapperHelper.GetSpecifiers(marketOddsChange.specifiers); var additionalInfo = string.IsNullOrEmpty(marketOddsChange.extended_specifiers) ? null : FeedMapperHelper.GetSpecifiers(marketOddsChange.extended_specifiers); var producer = _producerManager.Get(producerId); var nameProvider = _nameProviderFactory.BuildNameProvider(sportEvent, marketOddsChange.id, specifiers); var mappingProvider = _mappingProviderFactory.BuildMarketMappingProvider(sportEvent, marketOddsChange.id, specifiers, _producerManager.Get(producerId), sportId); return(new MarketWithProbabilities(marketOddsChange.id, specifiers, additionalInfo, nameProvider, mappingProvider, MessageMapperHelper.GetEnumValue <MarketStatus>(marketOddsChange.status), marketOddsChange.outcome?.Select(outcomeOdds => new OutcomeProbabilities( outcomeOdds.id, outcomeOdds.activeSpecified ? (bool?)(outcomeOdds.active != 0) : null, outcomeOdds.probabilitiesSpecified ? (double?)outcomeOdds.probabilities : null, nameProvider, mappingProvider, cultureInfos, BuildOutcomeDefinition(marketOddsChange.id, sportId, producer, specifiers, outcomeOdds.id, cultureInfos))), BuildMarketDefinition(marketOddsChange.id, sportId, producer, specifiers, cultureInfos), cultureInfos)); }
public async Task <PlayerProfileCI> GetPlayerProfileAsync(URN playerId, IEnumerable <CultureInfo> cultures) { Guard.Argument(playerId, nameof(playerId)).NotNull(); Guard.Argument(cultures, nameof(cultures)).NotNull(); if (!cultures.Any()) { throw new ArgumentOutOfRangeException(nameof(cultures)); } var timerOptions = new TimerOptions { Context = "ProfileCache", Name = "GetPlayerProfileAsync", MeasurementUnit = Unit.Requests }; using (SdkMetricsFactory.MetricsRoot.Measure.Timer.Time(timerOptions, $"{playerId}")) { WaitTillIdIsAvailable(_fetchedPlayerProfiles, playerId); PlayerProfileCI cachedItem; try { cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); var wantedCultures = cultures.ToList(); var missingLanguages = LanguageHelper.GetMissingCultures(wantedCultures, cachedItem?.Names.Keys.ToList()).ToList(); if (!missingLanguages.Any()) { return(cachedItem); } // try to fetch for competitor, to avoid requests by each player if (cachedItem?.CompetitorId != null) { var competitorCI = (CompetitorCI)_cache.Get(cachedItem.CompetitorId.ToString()); if (competitorCI != null && (competitorCI.LastTimeCompetitorProfileFetched < DateTime.Now.AddSeconds(-30) || LanguageHelper.GetMissingCultures(wantedCultures, competitorCI.CultureCompetitorProfileFetched.ToList()).Any())) { ExecutionLog.LogDebug($"Fetching competitor profile for competitor {competitorCI.Id} instead of player {cachedItem.Id} for languages=[{string.Join(",", missingLanguages.Select(s => s.TwoLetterISOLanguageName))}]."); try { WaitTillIdIsAvailable(_fetchedCompetitorProfiles, cachedItem.CompetitorId); var cultureTasks = missingLanguages.ToDictionary(c => c, c => _dataRouterManager.GetCompetitorAsync(competitorCI.Id, c, null)); await Task.WhenAll(cultureTasks.Values).ConfigureAwait(false); } catch (Exception) { // ignored } finally { if (!_isDisposed) { ReleaseId(_fetchedCompetitorProfiles, cachedItem.CompetitorId); } } cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); missingLanguages = LanguageHelper.GetMissingCultures(wantedCultures, cachedItem?.Names.Keys.ToList()).ToList(); if (!missingLanguages.Any()) { return(cachedItem); } } } var cultureTaskDictionary = missingLanguages.ToDictionary(c => c, c => _dataRouterManager.GetPlayerProfileAsync(playerId, c, null)); await Task.WhenAll(cultureTaskDictionary.Values).ConfigureAwait(false); cachedItem = (PlayerProfileCI)_cache.Get(playerId.ToString()); } catch (Exception ex) { if (ex is DeserializationException || ex is MappingException) { throw new CacheItemNotFoundException($"An error occurred while fetching player profile for player {playerId} in cache", playerId.ToString(), ex); } throw; } finally { ReleaseId(_fetchedPlayerProfiles, playerId); } return(cachedItem); } }
/// <summary> /// Gets the new <see cref="IMarketWithOdds"/> instance /// </summary> /// <param name="sportEvent">A <see cref="ISportEvent"/> representing the sport event associated with the generated message</param> /// <param name="marketOddsChange">The <see cref="oddsChangeMarket"/> instance used</param> /// <param name="producerId">A producerId of the <see cref="ISportEvent"/></param> /// <param name="sportId">A sportId of the <see cref="ISportEvent"/></param> /// <param name="cultures">The list of cultures that should be prefetched</param> /// <returns>Returns the new <see cref="IMarketWithOdds"/> instance</returns> protected virtual IMarketWithOdds GetMarketWithOdds(ISportEvent sportEvent, oddsChangeMarket marketOddsChange, int producerId, URN sportId, IEnumerable <CultureInfo> cultures) { var cultureInfos = cultures.ToList(); var specifiers = string.IsNullOrEmpty(marketOddsChange.specifiers) ? null : FeedMapperHelper.GetSpecifiers(marketOddsChange.specifiers); var additionalInfo = string.IsNullOrEmpty(marketOddsChange.extended_specifiers) ? null : FeedMapperHelper.GetSpecifiers(marketOddsChange.extended_specifiers); var marketMetadata = marketOddsChange.market_metadata == null || !marketOddsChange.market_metadata.next_betstopSpecified ? new MarketMetadata(null) : new MarketMetadata(marketOddsChange.market_metadata.next_betstop); var producer = _producerManager.Get(producerId); var nameProvider = _nameProviderFactory.BuildNameProvider(sportEvent, marketOddsChange.id, specifiers); var mappingProvider = _mappingProviderFactory.BuildMarketMappingProvider(sportEvent, marketOddsChange.id, specifiers, _producerManager.Get(producerId), sportId); return(new MarketWithOdds(marketOddsChange.id, specifiers, additionalInfo, nameProvider, mappingProvider, MessageMapperHelper.GetEnumValue <MarketStatus>(marketOddsChange.status), marketOddsChange.cashout_statusSpecified ? (CashoutStatus?)MessageMapperHelper.GetEnumValue <CashoutStatus>(marketOddsChange.cashout_status) : null, marketOddsChange.favouriteSpecified && marketOddsChange.favourite == 1, marketOddsChange.outcome?.Select(o => GetOutcomeWithOdds(sportEvent, nameProvider, mappingProvider, o, cultureInfos, BuildOutcomeDefinition(marketOddsChange.id, sportId, producer, specifiers, o.id, cultureInfos))), marketMetadata, BuildMarketDefinition(marketOddsChange.id, sportId, producer, specifiers, cultureInfos), cultureInfos)); }
private void AddTeamCompetitor(ExportableTeamCompetitorCI item) { if (_cache.Contains(item.Id)) { var itemId = URN.Parse(item.Id); try { var ci = (CompetitorCI)_cache.Get(item.Id); var teamCI = ci as TeamCompetitorCI; if (teamCI != null) { WaitTillIdIsAvailable(_mergeUrns, itemId); teamCI.Import(item); } else { WaitTillIdIsAvailable(_mergeUrns, itemId); teamCI = new TeamCompetitorCI(ci); teamCI.Import(item); _cache.Set(item.Id, teamCI, GetCorrectCacheItemPolicy(URN.Parse(item.Id))); } } catch (Exception ex) { ExecutionLog.LogError(ex, $"Error importing team competitor for id={item.Id}."); } finally { if (!_isDisposed) { ReleaseId(_mergeUrns, itemId); } } } else { _cache.Add(item.Id, new TeamCompetitorCI(item, _dataRouterManager), GetCorrectCacheItemPolicy(URN.Parse(item.Id))); } }
/// <summary> /// Gets the new <see cref="IMarket"/> instance /// </summary> /// <param name="sportEvent">A <see cref="ISportEvent"/> representing the sport event associated with the generated message</param> /// <param name="market">The <see cref="market"/> instance used</param> /// <param name = "producerId" > A producerId of the<see cref="ISportEvent"/></param> /// <param name="sportId">A sportId of the <see cref="ISportEvent"/></param> /// <param name="cultures">The list of cultures that should be prefetched</param> /// <returns>Returns the new <see cref="IMarket"/> instance</returns> protected virtual IMarketCancel GetMarketCancel(ISportEvent sportEvent, market market, int producerId, URN sportId, IEnumerable <CultureInfo> cultures) { Guard.Argument(sportEvent, nameof(sportEvent)).NotNull(); Guard.Argument(market, nameof(market)).NotNull(); var specifiers = string.IsNullOrEmpty(market.specifiers) ? null : FeedMapperHelper.GetSpecifiers(market.specifiers); var additionalInfo = string.IsNullOrEmpty(market.extended_specifiers) ? null : FeedMapperHelper.GetSpecifiers(market.extended_specifiers); var producer = _producerManager.Get(producerId); var cultureInfos = cultures.ToList(); return(new MarketCancel(market.id, specifiers, additionalInfo, _nameProviderFactory.BuildNameProvider(sportEvent, market.id, specifiers), _mappingProviderFactory.BuildMarketMappingProvider(sportEvent, market.id, specifiers, _producerManager.Get(producerId), sportId), BuildMarketDefinition(market.id, sportId, producer, specifiers, cultureInfos), market.void_reasonSpecified ? market.void_reason : (int?)null, _voidReasonCache, cultureInfos)); }
private void AddPlayerProfile(ExportablePlayerProfileCI item) { if (_cache.Contains(item.Id)) { var itemId = URN.Parse(item.Id); try { var ci = (PlayerProfileCI)_cache.Get(item.Id); WaitTillIdIsAvailable(_mergeUrns, itemId); ci?.Import(item); } catch (Exception ex) { ExecutionLog.LogError(ex, $"Error importing player profile for id={item.Id}."); } finally { if (!_isDisposed) { ReleaseId(_mergeUrns, itemId); } } } else { _cache.Add(item.Id, new PlayerProfileCI(item, _dataRouterManager), GetCorrectCacheItemPolicy(URN.Parse(item.Id))); } }
/// <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)); }
/// <summary> /// Initializes a new instance of the <see cref="IGoalScorer"/> class /// </summary> /// <param name="id">The <see cref="URN"/> uniquely identifying the current <see cref="IPlayer"/> instance</param> /// <param name="names">A <see cref="IDictionary{CultureInfo, String}"/> containing player names in different languages</param> public GoalScorer(URN id, IDictionary <CultureInfo, string> names) : base(id, names as IReadOnlyDictionary <CultureInfo, string>) { Guard.Argument(id, nameof(id)).NotNull(); }
/// <summary> /// Deletes the item from cache /// </summary> /// <param name="id">A <see cref="URN" /> representing the id of the item in the cache to be deleted</param> /// <param name="cacheItemType">A cache item type</param> public abstract void CacheDeleteItem(URN id, CacheItemType cacheItemType);