예제 #1
0
        public async Task <IActionResult> Get([FromQuery] ExchangeRatesRequest request, CancellationToken cancellationToken)
        {
            try
            {
                if (request.currencyCodes.Values.Where(x => x != "EUR").Count() > 0)
                {
                    return(BadRequest("Denominated currency has to be EUR!"));
                }

                DateTime endDate = request.endDate.GetValueOrDefault(request.startDate);

                if (request.startDate > DateTime.Now || request.endDate > DateTime.Now ||
                    request.startDate > request.endDate)
                {
                    throw new InvalidDateTime("Startdate has to be earlier or equal to enddate " +
                                              "and earlier or equal to current date!");
                }

                var response = await _currencyRatesService.GetExchangeRatesAsync(request.currencyCodes,
                                                                                 request.startDate, endDate, cancellationToken);

                return(Ok(response));
            }
            catch (InvalidDateTime ex)
            {
                return(NotFound(ex.Message));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message);
                return(BadRequest(ex.Message));
            }
        }
        public ExchangeRatesResponse GetExchangeRatesFor(ExchangeRatesRequest request)
        {
            var req = CreateRestRequest("/", Method.POST);

            req.AddBody(request);
            return(RestClient.Execute <ExchangeRatesResponse>(req).Data);
        }
        public async Task <ExchangeRatesResult> GetExchangeRates(ExchangeRatesRequest request)
        {
            ValidateCurrencies(request.BaseCurrency, request.TargetCurrency);
            ValidateDates(request.Dates);

            var tasks = request.Dates.Select(date => _connector.GetExchangeRate(date, request.BaseCurrency, request.TargetCurrency));
            var exchangeRatesResponses = await Task.WhenAll(tasks);

            var dateRateList = exchangeRatesResponses.Select(x => new { x.Date, Rate = x.Rates.First().Value })
                               .OrderBy(x => x.Rate)
                               .ToList();

            var minRate = dateRateList.First();
            var maxRate = dateRateList.Last();
            var average = dateRateList.Average(x => x.Rate);

            var minRateDate = new RateOnDate {
                Rate = minRate.Rate, Date = minRate.Date
            };
            var maxRateDate = new RateOnDate {
                Rate = maxRate.Rate, Date = maxRate.Date
            };

            return(new ExchangeRatesResult(minRateDate, maxRateDate, average));
        }
        public async Task <ExchangeRateResponse> GetExchangeRatesAsync(ExchangeRatesRequest request)
        {
            ValidateCurrencies(request.BaseCurrency, request.TargetCurrency);

            var tasks = new List <Task <ExchangeRatesResult> >();

            request.Dates.ForEach(date =>
            {
                tasks.Add(GetExchangeRatesAsync(date, request.BaseCurrency, request.TargetCurrency));
            });

            var result = await Task.WhenAll(tasks);

            if (result == null || result.Length == 0)
            {
                throw new NotFoundException("There are no exchange rates for provided dates.");
            }

            var rateDates = result.Select(res => new DateRate(res.Date, res.Rates.Values.First())).OrderBy(r => r.Rate).ToList();

            var minRate = rateDates.FirstOrDefault();
            var maxRate = rateDates.LastOrDefault();
            var average = rateDates.Average(rd => rd.Rate);

            return(new ExchangeRateResponse(minRate, maxRate, average));
        }
예제 #5
0
        public async Task <ExchangeRatesResponse> GetRates(ExchangeRatesRequest request)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (request.Date < _MinDate)
            {
                throw new ArgumentOutOfRangeException($"{nameof(request.Date)} must be greater than {_MinDate} but was {request.Date}");
            }

            var uriBuilder = new UriBuilder(_EcbBaseUri)
            {
                Path  = $"{request.Date.ToString("yyyy-MM-dd")}",
                Query = $"base={request.BaseCurrency}"
            };

            var apiResponse = await _HttpClient.GetAsync(uriBuilder.Uri).ConfigureAwait(false);

            var apiContent = await apiResponse.Content.ReadAsStringAsync();

            if (!apiResponse.IsSuccessStatusCode)
            {
                var error = _ResponseHandler.ParseError(apiContent);

                throw new HttpRequestException(
                          $"{nameof(apiResponse.StatusCode)}: {apiResponse.StatusCode}. {error}");
            }

            var exchangeRates = _ResponseHandler.ParseResponse(apiContent);

            return(exchangeRates);
        }
예제 #6
0
        public IEnumerable <ExchangeRate> Fetch(ExchangeRatesRequest request)
        {
            ConfigurationContainer.EnsureAppSettingExists("OpenExchangeRates.ApiKey");

            var exchangeRateData = Client.Get();

            return(exchangeRateData.Rates.Select(r => new ExchangeRate(r.Key, r.Value, exchangeRateData.Base, DateTime.UtcNow)));
        }
        private static HttpWebRequest CreateRequest(ExchangeRatesRequest request)
        {
            var apiUri      = string.Format(ApiUriFormat, request.BaseCurrencyCode, request.CurrencyCode);
            var httpRequest = (HttpWebRequest)WebRequest.Create(apiUri);

            httpRequest.Method = "GET";

            return(httpRequest);
        }
        public IEnumerable <ExchangeRate> GetLatest(ExchangeRatesRequest request)
        {
            var dataFetchingStrategy = _configuration.DataFetchingStrategy;

            if (_strategies.Keys.All(x => !string.Equals(x, dataFetchingStrategy, StringComparison.InvariantCultureIgnoreCase)))
            {
                const string errMsgFormat = "Data fetching strategy not found: {0}.";
                var          errMsg       = string.Format(errMsgFormat, dataFetchingStrategy);
                throw new ConfigurationMissingException(errMsg);
            }
            return(_strategies[dataFetchingStrategy].Fetch(request));
        }
        public static Task <ExchangeRatesResponse> ExchangeRates(bool isshort = false, bool accepted = false)
        {
            var request = new ExchangeRatesRequest
            {
                Short    = isshort ? 1 : 0,
                Accepted = accepted ? 1 : 0
            };

            var req = new HttpUrlRequest(request);

            return(process <ExchangeRatesResponse>(req));
        }
        public IEnumerable <ExchangeRate> Fetch(ExchangeRatesRequest request)
        {
            var httpRequest  = CreateRequest(request);
            var httpResponse = ExecuteHttpRequest(httpRequest);
            var rate         = ScrapeExchangeRate(httpResponse);

            var exchangeRate = new ExchangeRate(request.CurrencyCode, rate, request.BaseCurrencyCode, DateTime.UtcNow);

            return(new List <ExchangeRate> {
                exchangeRate
            });
        }
        public void WhenDefaultRequestIsRetrieved_ThenItIsTheDefaultOfTheInjectedAccess()
        {
            var expectedRequest = new ExchangeRatesRequest("BASEBASE", DateTime.UtcNow);

            var injectedAccess = new Mock <IExchangeRatesAccess>();

            injectedAccess.SetupGet(m => m.DefaultRequest).Returns(expectedRequest);

            var cachingAccess = new CachingExchangeRatesAccess(
                new MemoryCache("name"),
                injectedAccess.Object);

            var defaultRequest = cachingAccess.DefaultRequest;

            defaultRequest.Should().BeEquivalentTo(expectedRequest);
        }
        public async Task WhenCacheDoesNotContainItem_ThenAccessIsInvoked()
        {
            var expectedRequest = new ExchangeRatesRequest("BASE", DateTime.UtcNow);
            var accessMock      = new Mock <IExchangeRatesAccess>();

            ExchangeRatesRequest actualRequest = null;

            accessMock.Setup(m => m.GetRates(It.IsAny <ExchangeRatesRequest>()))
            .Callback <ExchangeRatesRequest>(request => actualRequest = request)
            .ReturnsAsync(new ExchangeRatesResponse(
                              expectedRequest.BaseCurrency,
                              expectedRequest.Date,
                              new Dictionary <string, decimal>()));

            var cachingAccess = new CachingExchangeRatesAccess(new MemoryCache("rates"), accessMock.Object);

            await cachingAccess.GetRates(expectedRequest);

            actualRequest.Should().BeEquivalentTo(expectedRequest);
        }
        public async Task WhenLatestRatesAreRetrieved_ThenAccessDefaultRequestIsUsed()
        {
            var expectedRequest = new ExchangeRatesRequest("DEFAULTBase", DateTime.MaxValue);

            var accessMock = new Mock <IExchangeRatesAccess>();

            accessMock.SetupGet(m => m.DefaultRequest).Returns(expectedRequest);

            ExchangeRatesRequest actualRequest = null;

            accessMock.Setup(m => m.GetRates(It.IsAny <ExchangeRatesRequest>()))
            .Callback <ExchangeRatesRequest>(request => actualRequest = request)
            .ReturnsAsync(new ExchangeRatesResponse(
                              "blah",
                              DateTime.UtcNow,
                              new Dictionary <string, decimal>()));

            var manager = new ExchangeRatesManager(accessMock.Object, Mock.Of <IExchangeRatesEngine>());

            await manager.GetLatestRates();

            actualRequest.Should().Be(expectedRequest);
        }
        public ExchangeRate Get(ExchangeRatesRequest request)
        {
            var cacheKey = GetCacheKey(request);

            return(MemCache.Get(cacheKey) as ExchangeRate);
        }
 private static string GetCacheKey(ExchangeRatesRequest request)
 {
     return(GetCacheKey(request.BaseCurrencyCode, request.CurrencyCode));
 }
예제 #16
0
        public ExchangeRatesResponse GetExchangeRatesFor(ExchangeRatesRequest request)
        {
            Contract.Ensures(Contract.Result <ExchangeRatesResponse>() != null);
            // Check if there is a valid cached response to this request.
            var cached = _cache.Get(request);

            if (cached != null)
            {
                // If yes, return that result
                return(new ExchangeRatesResponse(cached));
            }

            //TODO: We're making the assumption here that our API fetches USD as the default base rate.
            // It's kinda bad, but I can't think of a better solution right now.
            var cachedBaseRate = _cache.Get(new ExchangeRatesRequest
            {
                BaseCurrencyCode = "USD",
                CurrencyCode     = request.BaseCurrencyCode
            });

            var cachedCurrRate = _cache.Get(new ExchangeRatesRequest
            {
                BaseCurrencyCode = "USD",
                CurrencyCode     = request.CurrencyCode
            });

            if (cachedBaseRate != null && cachedCurrRate != null)
            {
                var rate   = cachedCurrRate.ConversionRate / cachedBaseRate.ConversionRate;
                var exRate = new ExchangeRate(request.CurrencyCode, rate, request.BaseCurrencyCode, DateTime.UtcNow);

                _cache.Add(exRate);
                _historicalStorage.Store(new List <ExchangeRate> {
                    exRate
                });

                return(new ExchangeRatesResponse(exRate));
            }

            // If no, check when we last pulled from the API.
            var lastFetch       = _cache.GetLastFetch();
            var cacheExpiryTime = DateTime.UtcNow.AddMinutes(_config.CacheExpiryTime);

            // It isn't in the cache, and we've made a request recently, so no dice.
            if (lastFetch.HasValue && lastFetch.Value > cacheExpiryTime)
            {
                return(new ExchangeRatesResponse(null));
            }

            // We've not made a request recently, so go get 'em.
            var fetchedRates = _fetch.GetLatest(request);

            // If there was data, store this data in the historical storage & cache.
            var latestRates = fetchedRates as IList <ExchangeRate> ?? fetchedRates.ToList();

            _cache.Add(latestRates);
            _historicalStorage.Store(latestRates);

            // Save when we last did a fetch, so we don't spam an API somewhere.
            _cache.AddLastFetch(DateTime.UtcNow);

            // If we have the rate we are looking for, return it. If not, we end up with an empty result.
            var requestedRate = latestRates.SingleOrDefault(x => x.BaseCurrencyCode == request.BaseCurrencyCode &&
                                                            x.CurrencyCode == request.CurrencyCode);

            // If it doesn't exist, but we can figure it out, figure it out and cache that too.
            if (requestedRate == null &&
                latestRates.Any(x => x.CurrencyCode == request.BaseCurrencyCode) &&
                latestRates.Any(x => x.CurrencyCode == request.CurrencyCode))
            {
                var baseRate = latestRates.Single(x => x.CurrencyCode == request.BaseCurrencyCode);
                var currRate = latestRates.Single(x => x.CurrencyCode == request.CurrencyCode);

                var rate   = currRate.ConversionRate / baseRate.ConversionRate;
                var exRate = new ExchangeRate(request.CurrencyCode, rate, request.BaseCurrencyCode, DateTime.UtcNow);

                _cache.Add(exRate);
                _historicalStorage.Store(new List <ExchangeRate> {
                    exRate
                });

                requestedRate = exRate;
            }

            return(new ExchangeRatesResponse(requestedRate));
        }