diff options
| author | Dan Engelbrecht <[email protected]> | 2023-01-11 23:52:55 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-01-11 23:52:55 -0800 |
| commit | a24820cbbc3c032f2cfc7b4c3bf9cac0bbaaeb6c (patch) | |
| tree | 4c756826edc1839cdf894a995a8dc4e927f6bb65 /zenserver/cache/structuredcache.cpp | |
| parent | 0.2.1 (diff) | |
| download | zen-a24820cbbc3c032f2cfc7b4c3bf9cac0bbaaeb6c.tar.xz zen-a24820cbbc3c032f2cfc7b4c3bf9cac0bbaaeb6c.zip | |
Add info (GET) endpoints for structured cache (#211)
* Add GET requests on cache/namespace/bucket level
* Add root route for project store requests (same as /list)
* Add markerpath to oplog info object
* Add totalsize, opcount and expired to oplog info
* Changelog
Diffstat (limited to 'zenserver/cache/structuredcache.cpp')
| -rw-r--r-- | zenserver/cache/structuredcache.cpp | 160 |
1 files changed, 141 insertions, 19 deletions
diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index d273bc88c..7550ce111 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -334,13 +334,15 @@ namespace { bool HttpRequestParseRelativeUri(std::string_view Key, HttpRequestData& Data) { std::vector<std::string_view> Tokens; - uint32_t TokenCount = zen::ForEachStrTok(Key, '/', [&](const std::string_view& Token) { + uint32_t TokenCount = ForEachStrTok(Key, '/', [&](const std::string_view& Token) { Tokens.push_back(Token); return true; }); switch (TokenCount) { + case 0: + return true; case 1: Data.Namespace = GetValidNamespaceName(Tokens[0]); return Data.Namespace.has_value(); @@ -624,26 +626,114 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request) return HandleCacheBucketRequest(Request, RequestData.Namespace.value(), RequestData.Bucket.value()); } - ZEN_ASSERT(RequestData.Namespace.has_value()); - return HandleCacheNamespaceRequest(Request, RequestData.Namespace.value()); + if (RequestData.Namespace.has_value()) + { + return HandleCacheNamespaceRequest(Request, RequestData.Namespace.value()); + } + return HandleCacheRequest(Request); +} + +void +HttpStructuredCacheService::HandleCacheRequest(HttpServerRequest& Request) +{ + switch (Request.RequestVerb()) + { + case HttpVerb::kHead: + case HttpVerb::kGet: + { + ZenCacheStore::Info Info = m_CacheStore.GetInfo(); + + CbObjectWriter ResponseWriter; + + ResponseWriter.BeginObject("Configuration"); + { + ExtendableStringBuilder<128> BasePathString; + BasePathString << Info.Config.BasePath.u8string(); + ResponseWriter.AddString("BasePath"sv, BasePathString.ToView()); + ResponseWriter.AddBool("AllowAutomaticCreationOfNamespaces", Info.Config.AllowAutomaticCreationOfNamespaces); + } + ResponseWriter.EndObject(); + + std::sort(begin(Info.NamespaceNames), end(Info.NamespaceNames), [](std::string_view L, std::string_view R) { + return L.compare(R) < 0; + }); + ResponseWriter.BeginArray("Namespaces"); + for (const std::string& NamespaceName : Info.NamespaceNames) + { + ResponseWriter.AddString(NamespaceName); + } + ResponseWriter.EndArray(); + ResponseWriter.BeginObject("StorageSize"); + { + ResponseWriter.AddInteger("DiskSize", Info.StorageSize.DiskSize); + ResponseWriter.AddInteger("MemorySize", Info.StorageSize.MemorySize); + } + + ResponseWriter.EndObject(); + + ResponseWriter.AddInteger("DiskEntryCount", Info.DiskEntryCount); + ResponseWriter.AddInteger("MemoryEntryCount", Info.MemoryEntryCount); + + return Request.WriteResponse(HttpResponseCode::OK, ResponseWriter.Save()); + } + break; + } } void -HttpStructuredCacheService::HandleCacheNamespaceRequest(zen::HttpServerRequest& Request, std::string_view Namespace) +HttpStructuredCacheService::HandleCacheNamespaceRequest(HttpServerRequest& Request, std::string_view NamespaceName) { switch (Request.RequestVerb()) { case HttpVerb::kHead: case HttpVerb::kGet: { - // Query stats + std::optional<ZenCacheNamespace::Info> Info = m_CacheStore.GetNamespaceInfo(NamespaceName); + if (!Info.has_value()) + { + return Request.WriteResponse(HttpResponseCode::NotFound); + } + + CbObjectWriter ResponseWriter; + + ResponseWriter.BeginObject("Configuration"); + { + ExtendableStringBuilder<128> BasePathString; + BasePathString << Info->Config.RootDir.u8string(); + ResponseWriter.AddString("RootDir"sv, BasePathString.ToView()); + ResponseWriter.AddInteger("DiskLayerThreshold"sv, Info->Config.DiskLayerThreshold); + } + ResponseWriter.EndObject(); + + std::sort(begin(Info->BucketNames), end(Info->BucketNames), [](std::string_view L, std::string_view R) { + return L.compare(R) < 0; + }); + + ResponseWriter.BeginArray("Buckets"sv); + for (const std::string& BucketName : Info->BucketNames) + { + ResponseWriter.AddString(BucketName); + } + ResponseWriter.EndArray(); + + ResponseWriter.BeginObject("StorageSize"sv); + { + ResponseWriter.AddInteger("DiskSize"sv, Info->DiskLayerInfo.TotalSize); + ResponseWriter.AddInteger("MemorySize"sv, Info->MemoryLayerInfo.TotalSize); + } + ResponseWriter.EndObject(); + + ResponseWriter.AddInteger("DiskEntryCount", Info->DiskLayerInfo.EntryCount); + ResponseWriter.AddInteger("MemoryEntryCount", Info->MemoryLayerInfo.EntryCount); + + return Request.WriteResponse(HttpResponseCode::OK, ResponseWriter.Save()); } break; case HttpVerb::kDelete: // Drop namespace { - if (m_CacheStore.DropNamespace(Namespace)) + if (m_CacheStore.DropNamespace(NamespaceName)) { return Request.WriteResponse(HttpResponseCode::OK); } @@ -660,21 +750,41 @@ HttpStructuredCacheService::HandleCacheNamespaceRequest(zen::HttpServerRequest& } void -HttpStructuredCacheService::HandleCacheBucketRequest(HttpServerRequest& Request, std::string_view Namespace, std::string_view Bucket) +HttpStructuredCacheService::HandleCacheBucketRequest(HttpServerRequest& Request, + std::string_view NamespaceName, + std::string_view BucketName) { switch (Request.RequestVerb()) { case HttpVerb::kHead: case HttpVerb::kGet: { - // Query stats + std::optional<ZenCacheNamespace::BucketInfo> Info = m_CacheStore.GetBucketInfo(NamespaceName, BucketName); + if (!Info.has_value()) + { + return Request.WriteResponse(HttpResponseCode::NotFound); + } + + CbObjectWriter ResponseWriter; + + ResponseWriter.BeginObject("StorageSize"); + { + ResponseWriter.AddInteger("DiskSize", Info->DiskLayerInfo.TotalSize); + ResponseWriter.AddInteger("MemorySize", Info->MemoryLayerInfo.TotalSize); + } + ResponseWriter.EndObject(); + + ResponseWriter.AddInteger("DiskEntryCount", Info->DiskLayerInfo.EntryCount); + ResponseWriter.AddInteger("MemoryEntryCount", Info->MemoryLayerInfo.EntryCount); + + return Request.WriteResponse(HttpResponseCode::OK, ResponseWriter.Save()); } break; case HttpVerb::kDelete: // Drop bucket { - if (m_CacheStore.DropBucket(Namespace, Bucket)) + if (m_CacheStore.DropBucket(NamespaceName, BucketName)) { return Request.WriteResponse(HttpResponseCode::OK); } @@ -711,7 +821,7 @@ HttpStructuredCacheService::HandleCacheRecordRequest(HttpServerRequest& Request, } void -HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromUrl) +HttpStructuredCacheService::HandleGetCacheRecord(HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromUrl) { const ZenContentType AcceptType = Request.AcceptContentType(); const bool SkipData = EnumHasAllFlags(PolicyFromUrl, CachePolicy::SkipData); @@ -1027,7 +1137,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request } void -HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromUrl) +HttpStructuredCacheService::HandlePutCacheRecord(HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromUrl) { IoBuffer Body = Request.ReadPayload(); @@ -1233,7 +1343,7 @@ HttpStructuredCacheService::HandleCacheChunkRequest(HttpServerRequest& Request, } void -HttpStructuredCacheService::HandleGetCacheChunk(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromUrl) +HttpStructuredCacheService::HandleGetCacheChunk(HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromUrl) { Stopwatch Timer; @@ -1311,7 +1421,7 @@ HttpStructuredCacheService::HandleGetCacheChunk(zen::HttpServerRequest& Request, } void -HttpStructuredCacheService::HandlePutCacheChunk(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromUrl) +HttpStructuredCacheService::HandlePutCacheChunk(HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromUrl) { // Note: Individual cacherecord values are not propagated upstream until a valid cache record has been stored ZEN_UNUSED(PolicyFromUrl); @@ -1369,7 +1479,7 @@ HttpStructuredCacheService::HandleRpcRequest(const ZenContentType ContentType, CbObject ObjectBuffer; if (ContentType == ZenContentType::kCbObject) { - ObjectBuffer = zen::LoadCompactBinaryObject(std::move(Body)); + ObjectBuffer = LoadCompactBinaryObject(std::move(Body)); Object = ObjectBuffer; } else @@ -1454,7 +1564,7 @@ HttpStructuredCacheService::ReplayRequestRecorder(cache::detail::IRequestReplaye } void -HttpStructuredCacheService::HandleRpcRequest(zen::HttpServerRequest& Request) +HttpStructuredCacheService::HandleRpcRequest(HttpServerRequest& Request) { switch (Request.RequestVerb()) { @@ -2800,7 +2910,7 @@ HttpStructuredCacheService::WriteGetCacheChunksResponse(std::string_view Namespa } void -HttpStructuredCacheService::HandleStatsRequest(zen::HttpServerRequest& Request) +HttpStructuredCacheService::HandleStatsRequest(HttpServerRequest& Request) { CbObjectWriter Cbo; @@ -2843,7 +2953,7 @@ HttpStructuredCacheService::HandleStatsRequest(zen::HttpServerRequest& Request) } void -HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request) +HttpStructuredCacheService::HandleStatusRequest(HttpServerRequest& Request) { CbObjectWriter Cbo; Cbo << "ok" << true; @@ -2854,6 +2964,20 @@ HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request) TEST_CASE("z$service.parse.relative.Uri") { + HttpRequestData RootRequest; + CHECK(HttpRequestParseRelativeUri("", RootRequest)); + CHECK(!RootRequest.Namespace.has_value()); + CHECK(!RootRequest.Bucket.has_value()); + CHECK(!RootRequest.HashKey.has_value()); + CHECK(!RootRequest.ValueContentId.has_value()); + + RootRequest = {}; + CHECK(HttpRequestParseRelativeUri("/", RootRequest)); + CHECK(!RootRequest.Namespace.has_value()); + CHECK(!RootRequest.Bucket.has_value()); + CHECK(!RootRequest.HashKey.has_value()); + CHECK(!RootRequest.ValueContentId.has_value()); + HttpRequestData LegacyBucketRequestBecomesNamespaceRequest; CHECK(HttpRequestParseRelativeUri("test", LegacyBucketRequestBecomesNamespaceRequest)); CHECK(LegacyBucketRequestBecomesNamespaceRequest.Namespace == "test"sv); @@ -2921,8 +3045,6 @@ TEST_CASE("z$service.parse.relative.Uri") CHECK(V2ValueContentIdRequest.ValueContentId == IoHash::FromHexString("56789abcdef12345678956789abcdef123456789"sv)); HttpRequestData Invalid; - CHECK(!HttpRequestParseRelativeUri("", Invalid)); - CHECK(!HttpRequestParseRelativeUri("/", Invalid)); CHECK(!HttpRequestParseRelativeUri("bad\2_namespace", Invalid)); CHECK(!HttpRequestParseRelativeUri("nice/\2\1bucket", Invalid)); CHECK(!HttpRequestParseRelativeUri("namespace/bucket/0123456789a", Invalid)); |