public HttpResponseMessage GetSections([FromUri] OpenApiMetadaSectionsRequest request) { var content = new StringContent( JsonConvert.SerializeObject( _openApiMetadataCacheProvider.GetAllSectionDocuments(request.Sdk) .Select(x => GetSwaggerSectionDetailsForCacheItem(x, request)))); var eTag = new EntityTagHeaderValue(HashHelper.GetSha256Hash(content.ToString()).ToHexString().DoubleQuoted()); if (ActionContext.Request.Headers.IfNoneMatch.Contains(eTag)) { return(new HttpResponseMessage(HttpStatusCode.NotModified)); } var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = content, Headers = { ETag = eTag } }; result.Content.Headers.ContentType = new MediaTypeHeaderValue(SwaggerDocumentHelper.ContentType); return(result); }
protected override void Act() { _openApiMetadataCacheProvider.InitializeCache(); _actualMetadata = _openApiMetadataCacheProvider .GetAllSectionDocuments(sdk: true) .ToList(); }
protected override void Arrange() { var configValueProvider = new ApiSettings(); configValueProvider.UseReverseProxyHeaders = true; Feature item = new Feature(); item.IsEnabled = true; item.Name = "openApiMetadata"; configValueProvider.Features.Add(item); _openApiMetadataCacheProvider = Stub <IOpenApiMetadataCacheProvider>(); A.CallTo(() => _openApiMetadataCacheProvider.GetOpenApiContentByFeedName(A <string> ._)) .Returns(OpenApiMetadataHelper.GetIdentityContent()); var fakeopenAPIcontent = A.Fake <List <OpenApiContent> >(); A.CallTo(() => _openApiMetadataCacheProvider.GetAllSectionDocuments(A <bool> ._)).Returns(fakeopenAPIcontent); var sectiondata = _openApiMetadataCacheProvider.GetOpenApiContentByFeedName("openApiMetadata"); fakeopenAPIcontent.Add(sectiondata); _controller = new OpenApiMetadataController(_openApiMetadataCacheProvider, configValueProvider); var request = A.Fake <HttpRequest>(); request.Method = "Post"; request.Scheme = "http"; A.CallTo(() => request.Host).Returns(new HostString("localhost", 80)); request.PathBase = "/"; request.RouteValues = new RouteValueDictionary { { "controller", "Token" } }; var httpContext = A.Fake <HttpContext>(); A.CallTo(() => httpContext.Request).Returns(request); var controllerContext = new ControllerContext() { HttpContext = httpContext, }; RouteValueDictionary dictionary = new RouteValueDictionary(); dictionary.Add("controller", "Token"); controllerContext.RouteData = new RouteData(dictionary); _controller.ControllerContext = controllerContext; }
public IActionResult Get([FromRoute] OpenApiMetadataSectionRequest request) { if (!IsFeatureEnabled()) { return(NotFound()); } if (Request.Query.ContainsKey("sdk")) { if (bool.TryParse(Request.Query["sdk"], out bool sdk)) { request.Sdk = sdk; } } var content = _openApiMetadataCacheProvider.GetAllSectionDocuments(request.Sdk) .OrderBy(x => x.Section) .ThenBy(x => x.Name) .Select(GetSwaggerSectionDetailsForCacheItem) .ToList(); var eTag = HashHelper.GetSha256Hash(content.ToString()) .ToHexString() .DoubleQuoted(); if (Request.TryGetRequestHeader(HeaderConstants.IfNoneMatch, out string headerValue)) { if (headerValue.EqualsIgnoreCase(eTag)) { return(StatusCode((int)HttpStatusCode.NotModified)); } } Response.GetTypedHeaders().ETag = new EntityTagHeaderValue(eTag); return(Ok(content)); OpenApiMetadataSectionDetails GetSwaggerSectionDetailsForCacheItem(OpenApiContent apiContent) { // Construct fully qualified metadata url var url = new Uri( new Uri( new Uri(Request.RootUrl(_useProxyHeaders).EnsureSuffixApplied("/")), "metadata/"), GetMetadataUrlSegmentForCacheItem(apiContent, request.SchoolYearFromRoute, request.InstanceIdFromRoute)); return(new OpenApiMetadataSectionDetails { EndpointUri = url.AbsoluteUri, Name = apiContent.Name.NormalizeCompositeTermForDisplay('-') .Replace(" ", "-"), Prefix = apiContent.Section.EqualsIgnoreCase(OpenApiMetadataSections.SwaggerUi) ? string.Empty : apiContent.Section }); } string GetMetadataUrlSegmentForCacheItem(OpenApiContent apiContent, int?schoolYear, string instanceId) { // 'Other' sections (Identity) do not live under 'ods' as other metadata endpoints do. // eg identity/v1/2017/swagger.json, // eg identity/v1/swagger.json, // SDKgen All // eg data/v3/2017/swagger.json, // eg data/v3/swagger.json, var basePath = GetBasePath(apiContent, schoolYear, instanceId); // Profiles and composites endpoints have an extra url segment (profiles or composites). // eg data/v3/2017/profiles/assessment/swagger.json // eg data/v3/profiles/assessment/swagger.json // eg composites/v1/2017/ed-fi/swagger.json // eg composites/v1/ed-fi/assessment/swagger.json var relativeSectionUri = string.IsNullOrWhiteSpace(apiContent.RelativeSectionPath) ? string.Empty : apiContent.RelativeSectionPath.EnsureSuffixApplied("/"); return($"{basePath}/{relativeSectionUri}{OpenApiMetadataDocumentHelper.Json}".ToLowerInvariant()); } string GetBasePath(OpenApiContent apiContent, int?schoolYear, string instanceId) { string basePath = $"{apiContent.BasePath}"; if (!string.IsNullOrEmpty(instanceId)) { basePath += $"/{instanceId}"; } if (schoolYear.HasValue) { basePath += $"/{schoolYear.Value}"; } return(basePath); } bool IsFeatureEnabled() { if (_isEnabled) { return(true); } _logger.Info("Open Api Metadata is disabled."); return(false); } }