/// <summary> /// Asynchronously gets a <see cref="IPlayerProfile"/> /// </summary> /// <param name="id">A <see cref="URN"/> specifying the id for which <see cref="IPlayerProfile"/> to be retrieved</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="IPlayerProfile"/> representing the specified player or a null reference</returns> public async Task <IPlayerProfile> GetPlayerProfileAsync(URN id, CultureInfo culture = null) { var cs = culture == null ? _defaultCultures : new[] { culture }; var s = cs.Aggregate(string.Empty, (current, cultureInfo) => current + (";" + cultureInfo.TwoLetterISOLanguageName)); s = s.Substring(1); LogInt.LogInformation($"Invoked GetPlayerProfileAsync: [Id={id}, Cultures={s}]"); try { var cacheItem = await _profileCache.GetPlayerProfileAsync(id, cs).ConfigureAwait(false); return(cacheItem == null ? null : new PlayerProfile(cacheItem, cs)); } catch (Exception e) { LogInt.LogError(e, $"Error executing GetPlayerProfileAsync: [Id={id}, Cultures={s}]"); if (_exceptionStrategy == ExceptionHandlingStrategy.THROW) { throw; } return(null); } }
/// <summary> /// Builds and returns a new instance of the <see cref="IPlayer"/> representing the player or competitor profile specified by its id /// </summary> /// <param name="playerId">A <see cref="URN"/> specifying the id of the player or competitor which will be represented by the constructed instance</param> /// <param name="cultures">A list of all supported languages</param> /// <param name="exceptionStrategy">A <see cref="ExceptionHandlingStrategy"/> enum member specifying how the build instance will handle potential exceptions</param> /// <returns>A <see cref="Task{IPlayer}"/> representing the asynchronous operation</returns> public async Task <IPlayer> BuildPlayerAsync(URN playerId, IEnumerable <CultureInfo> cultures, ExceptionHandlingStrategy exceptionStrategy) { var cultureList = cultures as IList <CultureInfo> ?? cultures.ToList(); if (playerId.Type.Equals("competitor", StringComparison.InvariantCultureIgnoreCase)) { var competitorCI = await _profileCache.GetCompetitorProfileAsync(playerId, cultureList).ConfigureAwait(false); return(competitorCI == null ? null : new Competitor(competitorCI, _profileCache, cultureList, this, exceptionStrategy, (ICompetitionCI)null)); } var playerProfileCI = await _profileCache.GetPlayerProfileAsync(playerId, cultureList).ConfigureAwait(false); return(playerProfileCI == null ? null : new PlayerProfile(playerProfileCI, cultureList)); }
public void player_profile_gets_cached() { const string callType = "GetPlayerProfileAsync"; Assert.AreEqual(0, _dataRouterManager.GetCallCount(callType), "Should be called exactly 0 times."); Assert.IsTrue(!_memoryCache.Any()); var player = _profileCache.GetPlayerProfileAsync(CreatePlayerUrn(1), TestData.Cultures).Result; Assert.IsNotNull(player); Assert.AreEqual(1, _memoryCache.Count()); Assert.AreEqual(TestData.Cultures.Count, _dataRouterManager.GetCallCount(callType), $"{callType} should be called exactly {TestData.Cultures.Count} times."); //if we call again, should not fetch again player = _profileCache.GetPlayerProfileAsync(CreatePlayerUrn(1), TestData.Cultures).Result; Assert.IsNotNull(player); Assert.AreEqual(1, _memoryCache.Count()); Assert.AreEqual(TestData.Cultures.Count, _dataRouterManager.GetCallCount(callType), $"{callType} should be called exactly {TestData.Cultures.Count} times."); }
public void player_profile_expression_returns_correct_value() { var specifiers = new Dictionary <string, string> { { "player", "sr:player:1" } }; var expression = new PlayerProfileExpression(_profileCache, _operandFactory.BuildOperand(new ReadOnlyDictionary <string, string>(specifiers), "player")); var result = expression.BuildNameAsync(TestData.Culture).Result; Assert.AreEqual( _profileCache.GetPlayerProfileAsync(URN.Parse("sr:player:1"), new [] { TestData.Culture }).Result.GetName(TestData.Culture), result, "The result is not correct"); }
/// <summary> /// Asynchronously gets a <see cref="IPlayerProfile"/> /// </summary> /// <param name="id">A <see cref="URN"/> specifying the id for which <see cref="IPlayerProfile"/> to be retrieved</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="IPlayerProfile"/> representing the specified player or a null reference</returns> public async Task <IPlayerProfile> GetPlayerProfileAsync(URN id, CultureInfo culture = null) { var cs = culture == null ? _defaultCultures : new[] { culture }; var s = cs.Aggregate(string.Empty, (current, cultureInfo) => current + (";" + cultureInfo.TwoLetterISOLanguageName)); s = s.Substring(1); Log.LogInformation($"Invoked GetPlayerProfileAsync: [Id={id}, Cultures={s}]."); var cacheItem = await _profileCache.GetPlayerProfileAsync(id, cs).ConfigureAwait(false); return(cacheItem == null ? null : new PlayerProfile(cacheItem, cs)); }
/// <summary> /// Asynchronously builds a name of the associated instance /// </summary> /// <param name="culture">A <see cref="CultureInfo" /> specifying the language of the constructed name</param> /// <returns>A <see cref="Task{String}" /> representing the asynchronous operation</returns> /// <exception cref="NameExpressionException">Error occurred while evaluating name expression</exception> public async Task <string> BuildNameAsync(CultureInfo culture) { var urnString = await _operand.GetStringValue().ConfigureAwait(false); var urn = URN.Parse(urnString); string name = null; if (urn.Type == "player") { var profile = await _profileCache.GetPlayerProfileAsync(urn, new[] { culture }).ConfigureAwait(false); name = profile?.GetName(culture); } else if (urn.Type == "competitor") { var profile = await _profileCache.GetCompetitorProfileAsync(urn, new[] { culture }).ConfigureAwait(false); name = profile?.GetName(culture); } return(name); }
/// <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)); }