Ejemplo n.º 1
0
        public async Task <ActionResult> Search([FromRoute] string serviceName, [FromQuery] string query)
        {
            // Check if parameters fulfill our basic requirements
            if (string.IsNullOrWhiteSpace(serviceName))
            {
                return(NotFound());
            }

            if (string.IsNullOrWhiteSpace(query))
            {
                return(NotFound());
            }

            logger.LogInformation($"{User.Identity.Name} @ {HttpContext.Connection.RemoteIpAddress} -> {Request.Path}{Request.QueryString}");

            // Use the cache before contacting the requested service
            string cacheKey   = GenerateCacheKey("search", serviceName, query);
            string cacheValue = null;

            try
            {
                var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));
                cacheValue = await cache.GetStringAsync(cacheKey, cancellationTokenSource.Token);
            }
            catch (OperationCanceledException)
            {
                logger.LogError($"Search: Cache took too long to respond (> 1 second) [key: {cacheKey}]");
            }
            catch (Exception exception)
            {
                logger.LogError($"Search: Cache threw an exception for data lookup: {exception} [key: {cacheKey}]");
            }

            if (!string.IsNullOrWhiteSpace(cacheValue))
            {
                try
                {
                    var items = JsonConvert.DeserializeObject <RepeatedField <SearchResponseItem> >(cacheValue);

                    return(new JsonResult(new
                    {
                        success = true,
                        items,
                    }));
                }
                catch (JsonReaderException readerException)
                {
                    logger.LogError($"Service {serviceName} threw an exception during cache deserialization: {readerException}");
                    RemoveCacheString(cacheKey);
                }
            }

            // Use the respective service client to fetch data from a remote api or remote service
            WebradioService service = services.GetService(serviceName);

            if (service == null)
            {
                return(SearchFailure("service is not supported"));
            }

            SearchResponse response;

            try
            {
                var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(SearchRequestTimeoutInSeconds));
                response = await service.Client.SearchAsync(new SearchRequest { Query = query }, cancellationToken : cancellationTokenSource.Token);
            }
            catch (OperationCanceledException)
            {
                logger.LogError($"Search: Service {serviceName} took too long to respond (> {SearchRequestTimeoutInSeconds} seconds)");
                return(SearchFailure($"service timeout reached after {SearchRequestTimeoutInSeconds} seconds"));
            }
            catch (RpcException exception)
            {
                logger.LogError($"Service {serviceName} threw an exception: {exception}");
                return(SearchFailure("service is out of order"));
            }

            // Check the response from the service
            if (response.Status == null || response.Items == null || !response.Status.Success)
            {
                return(SearchFailure(response.Status?.ErrorMessage));
            }

            if (response.Items.Count > 0)
            {
                SetCacheString(cacheKey, JsonConvert.SerializeObject(response.Items), service.Configuration.SearchExpirationInSeconds);
            }

            return(new JsonResult(new
            {
                success = true,
                items = response.Items,
            }));
        }
Ejemplo n.º 2
0
        public async Task <ActionResult> Stream([FromRoute] string serviceName, [FromRoute] string id)
        {
            // Check if parameters fulfill our basic requirements
            if (string.IsNullOrWhiteSpace(serviceName))
            {
                return(NotFound());
            }

            if (string.IsNullOrWhiteSpace(id))
            {
                return(NotFound());
            }

            logger.LogInformation($"{HttpContext.Connection.RemoteIpAddress} @ {User.Identity.Name} -> {Request.Path}{Request.QueryString}");

            // Use the cache before contacting the requested service
            string cacheKey   = GenerateCacheKey("stream", serviceName, id);
            string cacheValue = null;

            try
            {
                var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));
                cacheValue = await cache.GetStringAsync(cacheKey, cancellationTokenSource.Token);
            }
            catch (OperationCanceledException)
            {
                logger.LogError($"Stream: Cache took too long to respond (> 1 second) [key: {cacheKey}]");
            }
            catch (Exception exception)
            {
                logger.LogError($"Stream: Cache threw an exception for data lookup: {exception} [key: {cacheKey}]");
            }

            if (!string.IsNullOrWhiteSpace(cacheValue))
            {
                return(Redirect(cacheValue));
            }

            // Use the respective service client to fetch data from a remote api or remote service
            WebradioService service = services.GetService(serviceName);

            if (service == null)
            {
                return(SearchFailure("service is not supported"));
            }

            StreamResponse response;

            try
            {
                var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(StreamRequestTimeoutInSeconds));
                response = await service.Client.StreamAsync(new StreamRequest { Id = id }, cancellationToken : cancellationTokenSource.Token);
            }
            catch (OperationCanceledException)
            {
                logger.LogError($"Stream: Service {serviceName} took too long to respond (> {SearchRequestTimeoutInSeconds} seconds)");
                return(NotFound());
            }
            catch (RpcException exception)
            {
                logger.LogError($"Stream: Service {serviceName} threw an exception: {exception}");
                return(NotFound());
            }

            // Check the response from the service
            if (response.Status == null || !response.Status.Success || string.IsNullOrWhiteSpace(response.Url))
            {
                return(NotFound());
            }

            SetCacheString(cacheKey, response.Url, service.Configuration.StreamExpirationInSeconds);
            return(Redirect(response.Url));
        }