aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcache.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2023-01-11 23:52:55 -0800
committerGitHub <[email protected]>2023-01-11 23:52:55 -0800
commita24820cbbc3c032f2cfc7b4c3bf9cac0bbaaeb6c (patch)
tree4c756826edc1839cdf894a995a8dc4e927f6bb65 /zenserver/cache/structuredcache.cpp
parent0.2.1 (diff)
downloadzen-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.cpp160
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));