From 39f319e14efac196aeaae70e193a6d09a282c0c8 Mon Sep 17 00:00:00 2001 From: Eddy Ashton Date: Wed, 10 Jul 2024 12:58:14 +0000 Subject: [PATCH 1/5] Add a `nonstd::camel_case` util function --- include/ccf/ds/nonstd.h | 32 +++++++++++++++++++++ src/ds/test/nonstd.cpp | 61 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/include/ccf/ds/nonstd.h b/include/ccf/ds/nonstd.h index 97ba29c13f25..c7dc4780acf7 100644 --- a/include/ccf/ds/nonstd.h +++ b/include/ccf/ds/nonstd.h @@ -6,11 +6,15 @@ #include #include #include +#include #include #include #include #include +#define FMT_HEADER_ONLY +#include + /** * This file defines various type traits and utils that are not available in the * standard library. Some are added in future versions of the standard library, @@ -288,4 +292,32 @@ namespace ccf::nonstd return resolved.lexically_normal().string(); } + + static inline std::string camel_case( + std::string s, + // Should the first character be upper-cased? + bool camel_first = true, + // Regex fragment to identify which characters should be upper-cased, by + // matching a separator preceding them. Default is to match any + // non-alphanumeric character + const std::string& separator_regex = "[^[:alnum:]]") + { + // Replacement is always a 1-character string + std::string replacement(1, '\0'); + + std::string prefix_matcher = + camel_first ? fmt::format("(^|{})", separator_regex) : separator_regex; + std::regex re(prefix_matcher + "[a-z]"); + std::smatch match; + + while (std::regex_search(s, match, re)) + { + // Replacement is the upper-casing of the final character from the match + replacement[0] = std::toupper(match.str()[match.length() - 1]); + + s = s.replace(match.position(), match.length(), replacement); + } + + return s; + } } \ No newline at end of file diff --git a/src/ds/test/nonstd.cpp b/src/ds/test/nonstd.cpp index ccd352b73719..a39414dcc056 100644 --- a/src/ds/test/nonstd.cpp +++ b/src/ds/test/nonstd.cpp @@ -319,4 +319,65 @@ TEST_CASE("envvars" * doctest::test_suite("nonstd")) fmt::format("/{}/{}", test_value1, test_value2) == ccf::nonstd::expand_envvars_in_path("/$TEST_ENV_VAR1/$TEST_ENV_VAR2")); } +} + +TEST_CASE("camel_case" * doctest::test_suite("nonstd")) +{ + { + INFO("Default separator"); + REQUIRE(ccf::nonstd::camel_case("") == ""); + REQUIRE(ccf::nonstd::camel_case("abc") == "Abc"); + REQUIRE(ccf::nonstd::camel_case("abc", false) == "abc"); + + REQUIRE(ccf::nonstd::camel_case("hello world") == "HelloWorld"); + REQUIRE(ccf::nonstd::camel_case("hello world", false) == "helloWorld"); + + REQUIRE( + ccf::nonstd::camel_case( + "camel-with.many/many!many_many,many|many$separators") == + "CamelWithManyManyManyManyManyManySeparators"); + REQUIRE( + ccf::nonstd::camel_case( + "camel-with.many/many!many_many,many|many$separators", false) == + "camelWithManyManyManyManyManyManySeparators"); + + REQUIRE( + ccf::nonstd::camel_case("1handling2of3.numbers") == + "1handling2of3Numbers"); + REQUIRE( + ccf::nonstd::camel_case("1handling2of3.numbers", false) == + "1handling2of3Numbers"); + + REQUIRE( + ccf::nonstd::camel_case( + "camel_With-Existing_mixed-casing_Is-1Perhaps_2Surprising") == + "Camel_With-ExistingMixedCasing_Is-1Perhaps_2Surprising"); + REQUIRE( + ccf::nonstd::camel_case( + "camel_With-Existing_mixed-casing_Is-1Perhaps_2Surprising", false) == + "camel_With-ExistingMixedCasing_Is-1Perhaps_2Surprising"); + } + { + INFO("Custom separators"); + REQUIRE(ccf::nonstd::camel_case("hello world", true, "_") == "Hello world"); + REQUIRE( + ccf::nonstd::camel_case("hello world", false, "_") == "hello world"); + + REQUIRE(ccf::nonstd::camel_case("hello_world", true, "_") == "HelloWorld"); + REQUIRE(ccf::nonstd::camel_case("hello_world", false, "_") == "helloWorld"); + + REQUIRE( + ccf::nonstd::camel_case("what-about-/mixed/separators", true, "-") == + "WhatAbout-/mixed/separators"); + REQUIRE( + ccf::nonstd::camel_case("what-about-/mixed/separators", false, "-") == + "whatAbout-/mixed/separators"); + + REQUIRE( + ccf::nonstd::camel_case("what-about-/mixed/separators", true, "/") == + "What-about-MixedSeparators"); + REQUIRE( + ccf::nonstd::camel_case("what-about-/mixed/separators", false, "/") == + "what-about-MixedSeparators"); + } } \ No newline at end of file From 06906a52337ec4949c88bb36668e1e548214304a Mon Sep 17 00:00:00 2001 From: Eddy Ashton Date: Wed, 10 Jul 2024 14:10:30 +0000 Subject: [PATCH 2/5] Canonical test case --- src/ds/test/nonstd.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ds/test/nonstd.cpp b/src/ds/test/nonstd.cpp index a39414dcc056..7d2122bf0bbe 100644 --- a/src/ds/test/nonstd.cpp +++ b/src/ds/test/nonstd.cpp @@ -332,6 +332,13 @@ TEST_CASE("camel_case" * doctest::test_suite("nonstd")) REQUIRE(ccf::nonstd::camel_case("hello world") == "HelloWorld"); REQUIRE(ccf::nonstd::camel_case("hello world", false) == "helloWorld"); + REQUIRE( + ccf::nonstd::camel_case("standard_snake_case_value") == + "StandardSnakeCaseValue"); + REQUIRE( + ccf::nonstd::camel_case("standard_snake_case_value", false) == + "standardSnakeCaseValue"); + REQUIRE( ccf::nonstd::camel_case( "camel-with.many/many!many_many,many|many$separators") == From 13baf579ddc532ee40023e5da843959e1a829546 Mon Sep 17 00:00:00 2001 From: Markus Alexander Kuppe Date: Wed, 3 Jul 2024 14:52:34 -0700 Subject: [PATCH 3/5] https://spec.openapis.org/oas/latest.html suggests that "operationId" (or "operationref") is mandatory. Signed-off-by: Markus Alexander Kuppe --- src/endpoints/endpoint_registry.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/endpoints/endpoint_registry.cpp b/src/endpoints/endpoint_registry.cpp index f5dd50b5f132..f45a5cff2053 100644 --- a/src/endpoints/endpoint_registry.cpp +++ b/src/endpoints/endpoint_registry.cpp @@ -34,6 +34,14 @@ namespace ccf::endpoints ds::openapi::path(document, endpoint->full_uri_path), http_verb.value()); + // Add what appears a *mandatory* operationId, which is expected to be + // unique across the spec. + std::string p = + std::regex_replace(endpoint->full_uri_path, std::regex("[/_]"), ""); + std::string s = llhttp_method_name(http_verb.value()); + ccf::nonstd::to_lower(s); + path_op["operationId"] = fmt::format("{}_{}", p, s); + // Path Operation must contain at least one response - if none has been // defined, assume this can return 200 if (ds::openapi::responses(path_op).empty()) From 1d7aac22b780099c65f5bec461763a928c7c27ef Mon Sep 17 00:00:00 2001 From: Amaury Chamayou Date: Thu, 4 Jul 2024 17:32:22 +0000 Subject: [PATCH 4/5] Update OpenAPI --- doc/schemas/app_openapi.json | 36 ++++++++++++++++++++- doc/schemas/gov_openapi.json | 54 +++++++++++++++++++++++++++++++- doc/schemas/node_openapi.json | 33 ++++++++++++++++++- samples/apps/logging/logging.cpp | 2 +- src/node/rpc/member_frontend.h | 2 +- src/node/rpc/node_frontend.h | 2 +- 6 files changed, 123 insertions(+), 6 deletions(-) diff --git a/doc/schemas/app_openapi.json b/doc/schemas/app_openapi.json index f87cd88370f6..527b80cf3b5c 100644 --- a/doc/schemas/app_openapi.json +++ b/doc/schemas/app_openapi.json @@ -263,12 +263,13 @@ "info": { "description": "This CCF sample app implements a simple logging application, securely recording messages at client-specified IDs. It demonstrates most of the features available to CCF apps.", "title": "CCF Sample Logging App", - "version": "2.3.1" + "version": "2.4.1" }, "openapi": "3.0.0", "paths": { "/app/api": { "get": { + "operationId": "appapi_get", "responses": { "200": { "content": { @@ -294,6 +295,7 @@ "get": { "deprecated": true, "description": "Permitted SGX code identities", + "operationId": "appcode_get", "responses": { "200": { "content": { @@ -318,6 +320,7 @@ "/app/commit": { "get": { "description": "Latest transaction ID that has been committed on the service", + "operationId": "appcommit_get", "parameters": [ { "in": "query", @@ -359,6 +362,7 @@ }, "/app/custom_auth": { "get": { + "operationId": "appcustomauth_get", "responses": { "200": { "content": { @@ -381,6 +385,7 @@ }, "/app/log/cose_signed_content": { "post": { + "operationId": "applogcosesignedcontent_post", "responses": { "200": { "content": { @@ -408,6 +413,7 @@ }, "/app/log/private": { "delete": { + "operationId": "applogprivate_delete", "parameters": [ { "in": "query", @@ -446,6 +452,7 @@ } }, "get": { + "operationId": "applogprivate_get", "parameters": [ { "in": "query", @@ -484,6 +491,7 @@ } }, "post": { + "operationId": "applogprivate_post", "requestBody": { "content": { "application/json": { @@ -524,6 +532,7 @@ }, "/app/log/private/admin_only": { "post": { + "operationId": "applogprivateadminonly_post", "requestBody": { "content": { "application/json": { @@ -556,6 +565,7 @@ }, "/app/log/private/all": { "delete": { + "operationId": "applogprivateall_delete", "responses": { "200": { "content": { @@ -586,6 +596,7 @@ }, "/app/log/private/anonymous": { "post": { + "operationId": "applogprivateanonymous_post", "requestBody": { "content": { "application/json": { @@ -618,6 +629,7 @@ }, "/app/log/private/anonymous/v2": { "post": { + "operationId": "applogprivateanonymousv2_post", "requestBody": { "content": { "application/json": { @@ -650,6 +662,7 @@ }, "/app/log/private/backup": { "get": { + "operationId": "applogprivatebackup_get", "parameters": [ { "in": "query", @@ -690,6 +703,7 @@ }, "/app/log/private/committed": { "get": { + "operationId": "applogprivatecommitted_get", "parameters": [ { "in": "query", @@ -722,6 +736,7 @@ }, "/app/log/private/count": { "get": { + "operationId": "applogprivatecount_get", "responses": { "200": { "content": { @@ -752,6 +767,7 @@ }, "/app/log/private/historical": { "get": { + "operationId": "applogprivatehistorical_get", "parameters": [ { "in": "query", @@ -792,6 +808,7 @@ }, "/app/log/private/historical/sparse": { "get": { + "operationId": "applogprivatehistoricalsparse_get", "parameters": [ { "in": "query", @@ -840,6 +857,7 @@ }, "/app/log/private/historical_receipt": { "get": { + "operationId": "applogprivatehistoricalreceipt_get", "parameters": [ { "in": "query", @@ -880,6 +898,7 @@ }, "/app/log/private/install_committed_index": { "post": { + "operationId": "applogprivateinstallcommittedindex_post", "responses": { "204": { "description": "Default response description" @@ -895,6 +914,7 @@ }, "/app/log/private/prefix_cert": { "post": { + "operationId": "applogprivateprefixcert_post", "requestBody": { "content": { "application/json": { @@ -937,6 +957,7 @@ } ], "post": { + "operationId": "applogprivaterawtext{id}_post", "responses": { "200": { "description": "Default response description" @@ -960,6 +981,7 @@ }, "/app/log/private/uninstall_committed_index": { "post": { + "operationId": "applogprivateuninstallcommittedindex_post", "responses": { "204": { "description": "Default response description" @@ -975,6 +997,7 @@ }, "/app/log/public": { "delete": { + "operationId": "applogpublic_delete", "parameters": [ { "in": "query", @@ -1013,6 +1036,7 @@ } }, "get": { + "operationId": "applogpublic_get", "parameters": [ { "in": "query", @@ -1051,6 +1075,7 @@ } }, "post": { + "operationId": "applogpublic_post", "requestBody": { "content": { "application/json": { @@ -1091,6 +1116,7 @@ }, "/app/log/public/all": { "delete": { + "operationId": "applogpublicall_delete", "responses": { "200": { "content": { @@ -1121,6 +1147,7 @@ }, "/app/log/public/backup": { "get": { + "operationId": "applogpublicbackup_get", "parameters": [ { "in": "query", @@ -1161,6 +1188,7 @@ }, "/app/log/public/count": { "get": { + "operationId": "applogpubliccount_get", "responses": { "200": { "content": { @@ -1191,6 +1219,7 @@ }, "/app/log/public/historical/range": { "get": { + "operationId": "applogpublichistoricalrange_get", "parameters": [ { "in": "query", @@ -1247,6 +1276,7 @@ }, "/app/log/public/historical_receipt": { "get": { + "operationId": "applogpublichistoricalreceipt_get", "parameters": [ { "in": "query", @@ -1287,6 +1317,7 @@ }, "/app/log/request_query": { "get": { + "operationId": "applogrequestquery_get", "responses": { "200": { "content": { @@ -1309,6 +1340,7 @@ }, "/app/multi_auth": { "post": { + "operationId": "appmultiauth_post", "responses": { "200": { "content": { @@ -1341,6 +1373,7 @@ "/app/receipt": { "get": { "description": "A signed statement from the service over a transaction entry in the ledger", + "operationId": "appreceipt_get", "parameters": [ { "in": "query", @@ -1375,6 +1408,7 @@ "/app/tx": { "get": { "description": "Possible statuses returned are Unknown, Pending, Committed or Invalid.", + "operationId": "apptx_get", "parameters": [ { "in": "query", diff --git a/doc/schemas/gov_openapi.json b/doc/schemas/gov_openapi.json index 855144deeb4a..352271ed7836 100644 --- a/doc/schemas/gov_openapi.json +++ b/doc/schemas/gov_openapi.json @@ -1351,12 +1351,13 @@ "info": { "description": "This API is used to submit and query proposals which affect CCF's public governance tables.", "title": "CCF Governance API", - "version": "4.1.8" + "version": "4.2.8" }, "openapi": "3.0.0", "paths": { "/gov/ack": { "post": { + "operationId": "govack_post", "requestBody": { "content": { "application/json": { @@ -1388,6 +1389,7 @@ }, "/gov/ack/update_state_digest": { "post": { + "operationId": "govackupdatestatedigest_post", "responses": { "200": { "content": { @@ -1416,6 +1418,7 @@ }, "/gov/api": { "get": { + "operationId": "govapi_get", "responses": { "200": { "content": { @@ -1441,6 +1444,7 @@ "get": { "deprecated": true, "description": "Permitted SGX code identities", + "operationId": "govcode_get", "responses": { "200": { "content": { @@ -1465,6 +1469,7 @@ "/gov/commit": { "get": { "description": "Latest transaction ID that has been committed on the service", + "operationId": "govcommit_get", "parameters": [ { "in": "query", @@ -1506,6 +1511,7 @@ }, "/gov/encrypted_recovery_share/{member_id}": { "get": { + "operationId": "govencryptedrecoveryshare{memberid}_get", "responses": { "200": { "content": { @@ -1540,6 +1546,7 @@ "/gov/jwt_keys/all": { "get": { "deprecated": true, + "operationId": "govjwtkeysall_get", "responses": { "200": { "content": { @@ -1563,6 +1570,7 @@ }, "/gov/kv/constitution": { "get": { + "operationId": "govkvconstitution_get", "responses": { "200": { "content": { @@ -1585,6 +1593,7 @@ }, "/gov/kv/cose_history": { "get": { + "operationId": "govkvcosehistory_get", "responses": { "200": { "content": { @@ -1607,6 +1616,7 @@ }, "/gov/kv/cose_recent_proposals": { "get": { + "operationId": "govkvcoserecentproposals_get", "responses": { "200": { "content": { @@ -1629,6 +1639,7 @@ }, "/gov/kv/endpoints": { "get": { + "operationId": "govkvendpoints_get", "responses": { "200": { "content": { @@ -1651,6 +1662,7 @@ }, "/gov/kv/history": { "get": { + "operationId": "govkvhistory_get", "responses": { "200": { "content": { @@ -1673,6 +1685,7 @@ }, "/gov/kv/interpreter/flush": { "get": { + "operationId": "govkvinterpreterflush_get", "responses": { "200": { "content": { @@ -1695,6 +1708,7 @@ }, "/gov/kv/js_runtime_options": { "get": { + "operationId": "govkvjsruntimeoptions_get", "responses": { "200": { "content": { @@ -1717,6 +1731,7 @@ }, "/gov/kv/jwt/issuers": { "get": { + "operationId": "govkvjwtissuers_get", "responses": { "200": { "content": { @@ -1739,6 +1754,7 @@ }, "/gov/kv/jwt/public_signing_key": { "get": { + "operationId": "govkvjwtpublicsigningkey_get", "responses": { "200": { "content": { @@ -1761,6 +1777,7 @@ }, "/gov/kv/jwt/public_signing_key_issuer": { "get": { + "operationId": "govkvjwtpublicsigningkeyissuer_get", "responses": { "200": { "content": { @@ -1783,6 +1800,7 @@ }, "/gov/kv/jwt/public_signing_keys_metadata": { "get": { + "operationId": "govkvjwtpublicsigningkeysmetadata_get", "responses": { "200": { "content": { @@ -1805,6 +1823,7 @@ }, "/gov/kv/members/acks": { "get": { + "operationId": "govkvmembersacks_get", "responses": { "200": { "content": { @@ -1827,6 +1846,7 @@ }, "/gov/kv/members/certs": { "get": { + "operationId": "govkvmemberscerts_get", "responses": { "200": { "content": { @@ -1849,6 +1869,7 @@ }, "/gov/kv/members/encryption_public_keys": { "get": { + "operationId": "govkvmembersencryptionpublickeys_get", "responses": { "200": { "content": { @@ -1871,6 +1892,7 @@ }, "/gov/kv/members/info": { "get": { + "operationId": "govkvmembersinfo_get", "responses": { "200": { "content": { @@ -1893,6 +1915,7 @@ }, "/gov/kv/modules": { "get": { + "operationId": "govkvmodules_get", "responses": { "200": { "content": { @@ -1915,6 +1938,7 @@ }, "/gov/kv/modules_quickjs_bytecode": { "get": { + "operationId": "govkvmodulesquickjsbytecode_get", "responses": { "200": { "content": { @@ -1937,6 +1961,7 @@ }, "/gov/kv/modules_quickjs_version": { "get": { + "operationId": "govkvmodulesquickjsversion_get", "responses": { "200": { "content": { @@ -1959,6 +1984,7 @@ }, "/gov/kv/nodes/code_ids": { "get": { + "operationId": "govkvnodescodeids_get", "responses": { "200": { "content": { @@ -1981,6 +2007,7 @@ }, "/gov/kv/nodes/endorsed_certificates": { "get": { + "operationId": "govkvnodesendorsedcertificates_get", "responses": { "200": { "content": { @@ -2003,6 +2030,7 @@ }, "/gov/kv/nodes/info": { "get": { + "operationId": "govkvnodesinfo_get", "responses": { "200": { "content": { @@ -2025,6 +2053,7 @@ }, "/gov/kv/nodes/snp/host_data": { "get": { + "operationId": "govkvnodessnphostdata_get", "responses": { "200": { "content": { @@ -2047,6 +2076,7 @@ }, "/gov/kv/nodes/snp/measurements": { "get": { + "operationId": "govkvnodessnpmeasurements_get", "responses": { "200": { "content": { @@ -2069,6 +2099,7 @@ }, "/gov/kv/nodes/snp/uvm_endorsements": { "get": { + "operationId": "govkvnodessnpuvmendorsements_get", "responses": { "200": { "content": { @@ -2091,6 +2122,7 @@ }, "/gov/kv/proposals": { "get": { + "operationId": "govkvproposals_get", "responses": { "200": { "content": { @@ -2113,6 +2145,7 @@ }, "/gov/kv/proposals_info": { "get": { + "operationId": "govkvproposalsinfo_get", "responses": { "200": { "content": { @@ -2135,6 +2168,7 @@ }, "/gov/kv/service/acme_certificates": { "get": { + "operationId": "govkvserviceacmecertificates_get", "responses": { "200": { "content": { @@ -2157,6 +2191,7 @@ }, "/gov/kv/service/config": { "get": { + "operationId": "govkvserviceconfig_get", "responses": { "200": { "content": { @@ -2179,6 +2214,7 @@ }, "/gov/kv/service/info": { "get": { + "operationId": "govkvserviceinfo_get", "responses": { "200": { "content": { @@ -2201,6 +2237,7 @@ }, "/gov/kv/service/previous_service_identity": { "get": { + "operationId": "govkvservicepreviousserviceidentity_get", "responses": { "200": { "content": { @@ -2223,6 +2260,7 @@ }, "/gov/kv/tls/ca_cert_bundles": { "get": { + "operationId": "govkvtlscacertbundles_get", "responses": { "200": { "content": { @@ -2245,6 +2283,7 @@ }, "/gov/kv/users/certs": { "get": { + "operationId": "govkvuserscerts_get", "responses": { "200": { "content": { @@ -2267,6 +2306,7 @@ }, "/gov/kv/users/info": { "get": { + "operationId": "govkvusersinfo_get", "responses": { "200": { "content": { @@ -2290,6 +2330,7 @@ "/gov/members": { "get": { "deprecated": true, + "operationId": "govmembers_get", "responses": { "200": { "content": { @@ -2313,6 +2354,7 @@ }, "/gov/proposals": { "get": { + "operationId": "govproposals_get", "responses": { "200": { "content": { @@ -2334,6 +2376,7 @@ } }, "post": { + "operationId": "govproposals_post", "requestBody": { "content": { "application/json": { @@ -2372,6 +2415,7 @@ }, "/gov/proposals/{proposal_id}": { "get": { + "operationId": "govproposals{proposalid}_get", "responses": { "200": { "content": { @@ -2405,6 +2449,7 @@ }, "/gov/proposals/{proposal_id}/actions": { "get": { + "operationId": "govproposals{proposalid}actions_get", "responses": { "200": { "content": { @@ -2448,6 +2493,7 @@ } ], "post": { + "operationId": "govproposals{proposalid}ballots_post", "requestBody": { "content": { "application/json": { @@ -2486,6 +2532,7 @@ }, "/gov/proposals/{proposal_id}/ballots/{member_id}": { "get": { + "operationId": "govproposals{proposalid}ballots{memberid}_get", "responses": { "200": { "content": { @@ -2537,6 +2584,7 @@ } ], "post": { + "operationId": "govproposals{proposalid}withdraw_post", "responses": { "200": { "content": { @@ -2566,6 +2614,7 @@ "/gov/receipt": { "get": { "description": "A signed statement from the service over a transaction entry in the ledger", + "operationId": "govreceipt_get", "parameters": [ { "in": "query", @@ -2600,6 +2649,7 @@ "/gov/recovery_share": { "get": { "deprecated": true, + "operationId": "govrecoveryshare_get", "responses": { "200": { "content": { @@ -2626,6 +2676,7 @@ } }, "post": { + "operationId": "govrecoveryshare_post", "requestBody": { "content": { "application/json": { @@ -2665,6 +2716,7 @@ "/gov/tx": { "get": { "description": "Possible statuses returned are Unknown, Pending, Committed or Invalid.", + "operationId": "govtx_get", "parameters": [ { "in": "query", diff --git a/doc/schemas/node_openapi.json b/doc/schemas/node_openapi.json index 53602354c9d4..4710d24ae518 100644 --- a/doc/schemas/node_openapi.json +++ b/doc/schemas/node_openapi.json @@ -896,12 +896,13 @@ "info": { "description": "This API provides public, uncredentialed access to service and node state.", "title": "CCF Public Node API", - "version": "4.9.2" + "version": "4.10.2" }, "openapi": "3.0.0", "paths": { "/node/api": { "get": { + "operationId": "nodeapi_get", "responses": { "200": { "content": { @@ -925,6 +926,7 @@ }, "/node/backup": { "get": { + "operationId": "nodebackup_get", "responses": { "200": { "description": "Default response description" @@ -942,6 +944,7 @@ "get": { "deprecated": true, "description": "Permitted SGX code identities", + "operationId": "nodecode_get", "responses": { "200": { "content": { @@ -966,6 +969,7 @@ "/node/commit": { "get": { "description": "Latest transaction ID that has been committed on the service", + "operationId": "nodecommit_get", "parameters": [ { "in": "query", @@ -1007,6 +1011,7 @@ }, "/node/config": { "get": { + "operationId": "nodeconfig_get", "responses": { "200": { "content": { @@ -1029,6 +1034,7 @@ }, "/node/consensus": { "get": { + "operationId": "nodeconsensus_get", "responses": { "200": { "content": { @@ -1051,6 +1057,7 @@ }, "/node/index/strategies": { "get": { + "operationId": "nodeindexstrategies_get", "responses": { "200": { "content": { @@ -1073,6 +1080,7 @@ }, "/node/js_metrics": { "get": { + "operationId": "nodejsmetrics_get", "responses": { "200": { "content": { @@ -1095,6 +1103,7 @@ }, "/node/jwt_keys/refresh/metrics": { "get": { + "operationId": "nodejwtkeysrefreshmetrics_get", "responses": { "200": { "content": { @@ -1117,6 +1126,7 @@ }, "/node/memory": { "get": { + "operationId": "nodememory_get", "responses": { "200": { "content": { @@ -1139,6 +1149,7 @@ }, "/node/metrics": { "get": { + "operationId": "nodemetrics_get", "responses": { "200": { "content": { @@ -1161,6 +1172,7 @@ }, "/node/network": { "get": { + "operationId": "nodenetwork_get", "responses": { "200": { "content": { @@ -1183,6 +1195,7 @@ }, "/node/network/nodes": { "get": { + "operationId": "nodenetworknodes_get", "parameters": [ { "in": "query", @@ -1231,6 +1244,7 @@ }, "/node/network/nodes/primary": { "get": { + "operationId": "nodenetworknodesprimary_get", "responses": { "200": { "content": { @@ -1253,6 +1267,7 @@ }, "/node/network/nodes/self": { "get": { + "operationId": "nodenetworknodesself_get", "responses": { "200": { "content": { @@ -1275,6 +1290,7 @@ }, "/node/network/nodes/{node_id}": { "delete": { + "operationId": "nodenetworknodes{nodeid}_delete", "responses": { "200": { "content": { @@ -1295,6 +1311,7 @@ } }, "get": { + "operationId": "nodenetworknodes{nodeid}_get", "responses": { "200": { "content": { @@ -1327,6 +1344,7 @@ }, "/node/network/removable_nodes": { "get": { + "operationId": "nodenetworkremovablenodes_get", "responses": { "200": { "content": { @@ -1349,6 +1367,7 @@ }, "/node/primary": { "get": { + "operationId": "nodeprimary_get", "responses": { "200": { "description": "Default response description" @@ -1362,6 +1381,7 @@ } }, "head": { + "operationId": "nodeprimary_head", "responses": { "200": { "description": "Default response description" @@ -1377,6 +1397,7 @@ }, "/node/quotes": { "get": { + "operationId": "nodequotes_get", "responses": { "200": { "content": { @@ -1399,6 +1420,7 @@ }, "/node/quotes/self": { "get": { + "operationId": "nodequotesself_get", "responses": { "200": { "content": { @@ -1421,6 +1443,7 @@ }, "/node/ready/app": { "get": { + "operationId": "nodereadyapp_get", "responses": { "204": { "description": "Default response description" @@ -1436,6 +1459,7 @@ }, "/node/ready/gov": { "get": { + "operationId": "nodereadygov_get", "responses": { "204": { "description": "Default response description" @@ -1452,6 +1476,7 @@ "/node/receipt": { "get": { "description": "A signed statement from the service over a transaction entry in the ledger", + "operationId": "nodereceipt_get", "parameters": [ { "in": "query", @@ -1485,6 +1510,7 @@ }, "/node/self_signed_certificate": { "get": { + "operationId": "nodeselfsignedcertificate_get", "responses": { "200": { "content": { @@ -1507,6 +1533,7 @@ }, "/node/service/configuration": { "get": { + "operationId": "nodeserviceconfiguration_get", "responses": { "200": { "content": { @@ -1529,6 +1556,7 @@ }, "/node/service/previous_identity": { "get": { + "operationId": "nodeservicepreviousidentity_get", "responses": { "200": { "content": { @@ -1551,6 +1579,7 @@ }, "/node/state": { "get": { + "operationId": "nodestate_get", "responses": { "200": { "content": { @@ -1574,6 +1603,7 @@ "/node/tx": { "get": { "description": "Possible statuses returned are Unknown, Pending, Committed or Invalid.", + "operationId": "nodetx_get", "parameters": [ { "in": "query", @@ -1607,6 +1637,7 @@ }, "/node/version": { "get": { + "operationId": "nodeversion_get", "responses": { "200": { "content": { diff --git a/samples/apps/logging/logging.cpp b/samples/apps/logging/logging.cpp index a690452b7c37..6465aa35116a 100644 --- a/samples/apps/logging/logging.cpp +++ b/samples/apps/logging/logging.cpp @@ -454,7 +454,7 @@ namespace loggingapp "recording messages at client-specified IDs. It demonstrates most of " "the features available to CCF apps."; - openapi_info.document_version = "2.3.1"; + openapi_info.document_version = "2.4.1"; index_per_public_key = std::make_shared( PUBLIC_RECORDS, context, 10000, 20); diff --git a/src/node/rpc/member_frontend.h b/src/node/rpc/member_frontend.h index 6d6262b8ae0b..5a0b1a778563 100644 --- a/src/node/rpc/member_frontend.h +++ b/src/node/rpc/member_frontend.h @@ -595,7 +595,7 @@ namespace ccf openapi_info.description = "This API is used to submit and query proposals which affect CCF's " "public governance tables."; - openapi_info.document_version = "4.1.8"; + openapi_info.document_version = "4.2.8"; } static std::optional get_caller_member_id( diff --git a/src/node/rpc/node_frontend.h b/src/node/rpc/node_frontend.h index 03b9e4f7037f..9544fc713901 100644 --- a/src/node/rpc/node_frontend.h +++ b/src/node/rpc/node_frontend.h @@ -404,7 +404,7 @@ namespace ccf openapi_info.description = "This API provides public, uncredentialed access to service and node " "state."; - openapi_info.document_version = "4.9.2"; + openapi_info.document_version = "4.10.2"; } void init_handlers() override From c940601dbd4981daf73932820824db389e60a737 Mon Sep 17 00:00:00 2001 From: Markus Alexander Kuppe Date: Wed, 10 Jul 2024 10:43:08 -0700 Subject: [PATCH 5/5] - Remove '_' as deliminator between http verb and path - Move http verb before path - Handle path templates - Camel-Case http path and verb Signed-off-by: Markus Alexander Kuppe --- doc/schemas/app_openapi.json | 68 +++++++++--------- doc/schemas/gov_openapi.json | 104 ++++++++++++++-------------- doc/schemas/node_openapi.json | 62 ++++++++--------- src/endpoints/endpoint_registry.cpp | 16 ++++- 4 files changed, 131 insertions(+), 119 deletions(-) diff --git a/doc/schemas/app_openapi.json b/doc/schemas/app_openapi.json index 527b80cf3b5c..125a1350bc49 100644 --- a/doc/schemas/app_openapi.json +++ b/doc/schemas/app_openapi.json @@ -269,7 +269,7 @@ "paths": { "/app/api": { "get": { - "operationId": "appapi_get", + "operationId": "GetAppApi", "responses": { "200": { "content": { @@ -295,7 +295,7 @@ "get": { "deprecated": true, "description": "Permitted SGX code identities", - "operationId": "appcode_get", + "operationId": "GetAppCode", "responses": { "200": { "content": { @@ -320,7 +320,7 @@ "/app/commit": { "get": { "description": "Latest transaction ID that has been committed on the service", - "operationId": "appcommit_get", + "operationId": "GetAppCommit", "parameters": [ { "in": "query", @@ -362,7 +362,7 @@ }, "/app/custom_auth": { "get": { - "operationId": "appcustomauth_get", + "operationId": "GetAppCustomAuth", "responses": { "200": { "content": { @@ -385,7 +385,7 @@ }, "/app/log/cose_signed_content": { "post": { - "operationId": "applogcosesignedcontent_post", + "operationId": "PostAppLogCoseSignedContent", "responses": { "200": { "content": { @@ -413,7 +413,7 @@ }, "/app/log/private": { "delete": { - "operationId": "applogprivate_delete", + "operationId": "DeleteAppLogPrivate", "parameters": [ { "in": "query", @@ -452,7 +452,7 @@ } }, "get": { - "operationId": "applogprivate_get", + "operationId": "GetAppLogPrivate", "parameters": [ { "in": "query", @@ -491,7 +491,7 @@ } }, "post": { - "operationId": "applogprivate_post", + "operationId": "PostAppLogPrivate", "requestBody": { "content": { "application/json": { @@ -532,7 +532,7 @@ }, "/app/log/private/admin_only": { "post": { - "operationId": "applogprivateadminonly_post", + "operationId": "PostAppLogPrivateAdminOnly", "requestBody": { "content": { "application/json": { @@ -565,7 +565,7 @@ }, "/app/log/private/all": { "delete": { - "operationId": "applogprivateall_delete", + "operationId": "DeleteAppLogPrivateAll", "responses": { "200": { "content": { @@ -596,7 +596,7 @@ }, "/app/log/private/anonymous": { "post": { - "operationId": "applogprivateanonymous_post", + "operationId": "PostAppLogPrivateAnonymous", "requestBody": { "content": { "application/json": { @@ -629,7 +629,7 @@ }, "/app/log/private/anonymous/v2": { "post": { - "operationId": "applogprivateanonymousv2_post", + "operationId": "PostAppLogPrivateAnonymousV2", "requestBody": { "content": { "application/json": { @@ -662,7 +662,7 @@ }, "/app/log/private/backup": { "get": { - "operationId": "applogprivatebackup_get", + "operationId": "GetAppLogPrivateBackup", "parameters": [ { "in": "query", @@ -703,7 +703,7 @@ }, "/app/log/private/committed": { "get": { - "operationId": "applogprivatecommitted_get", + "operationId": "GetAppLogPrivateCommitted", "parameters": [ { "in": "query", @@ -736,7 +736,7 @@ }, "/app/log/private/count": { "get": { - "operationId": "applogprivatecount_get", + "operationId": "GetAppLogPrivateCount", "responses": { "200": { "content": { @@ -767,7 +767,7 @@ }, "/app/log/private/historical": { "get": { - "operationId": "applogprivatehistorical_get", + "operationId": "GetAppLogPrivateHistorical", "parameters": [ { "in": "query", @@ -808,7 +808,7 @@ }, "/app/log/private/historical/sparse": { "get": { - "operationId": "applogprivatehistoricalsparse_get", + "operationId": "GetAppLogPrivateHistoricalSparse", "parameters": [ { "in": "query", @@ -857,7 +857,7 @@ }, "/app/log/private/historical_receipt": { "get": { - "operationId": "applogprivatehistoricalreceipt_get", + "operationId": "GetAppLogPrivateHistoricalReceipt", "parameters": [ { "in": "query", @@ -898,7 +898,7 @@ }, "/app/log/private/install_committed_index": { "post": { - "operationId": "applogprivateinstallcommittedindex_post", + "operationId": "PostAppLogPrivateInstallCommittedIndex", "responses": { "204": { "description": "Default response description" @@ -914,7 +914,7 @@ }, "/app/log/private/prefix_cert": { "post": { - "operationId": "applogprivateprefixcert_post", + "operationId": "PostAppLogPrivatePrefixCert", "requestBody": { "content": { "application/json": { @@ -957,7 +957,7 @@ } ], "post": { - "operationId": "applogprivaterawtext{id}_post", + "operationId": "PostAppLogPrivateRawTextId", "responses": { "200": { "description": "Default response description" @@ -981,7 +981,7 @@ }, "/app/log/private/uninstall_committed_index": { "post": { - "operationId": "applogprivateuninstallcommittedindex_post", + "operationId": "PostAppLogPrivateUninstallCommittedIndex", "responses": { "204": { "description": "Default response description" @@ -997,7 +997,7 @@ }, "/app/log/public": { "delete": { - "operationId": "applogpublic_delete", + "operationId": "DeleteAppLogPublic", "parameters": [ { "in": "query", @@ -1036,7 +1036,7 @@ } }, "get": { - "operationId": "applogpublic_get", + "operationId": "GetAppLogPublic", "parameters": [ { "in": "query", @@ -1075,7 +1075,7 @@ } }, "post": { - "operationId": "applogpublic_post", + "operationId": "PostAppLogPublic", "requestBody": { "content": { "application/json": { @@ -1116,7 +1116,7 @@ }, "/app/log/public/all": { "delete": { - "operationId": "applogpublicall_delete", + "operationId": "DeleteAppLogPublicAll", "responses": { "200": { "content": { @@ -1147,7 +1147,7 @@ }, "/app/log/public/backup": { "get": { - "operationId": "applogpublicbackup_get", + "operationId": "GetAppLogPublicBackup", "parameters": [ { "in": "query", @@ -1188,7 +1188,7 @@ }, "/app/log/public/count": { "get": { - "operationId": "applogpubliccount_get", + "operationId": "GetAppLogPublicCount", "responses": { "200": { "content": { @@ -1219,7 +1219,7 @@ }, "/app/log/public/historical/range": { "get": { - "operationId": "applogpublichistoricalrange_get", + "operationId": "GetAppLogPublicHistoricalRange", "parameters": [ { "in": "query", @@ -1276,7 +1276,7 @@ }, "/app/log/public/historical_receipt": { "get": { - "operationId": "applogpublichistoricalreceipt_get", + "operationId": "GetAppLogPublicHistoricalReceipt", "parameters": [ { "in": "query", @@ -1317,7 +1317,7 @@ }, "/app/log/request_query": { "get": { - "operationId": "applogrequestquery_get", + "operationId": "GetAppLogRequestQuery", "responses": { "200": { "content": { @@ -1340,7 +1340,7 @@ }, "/app/multi_auth": { "post": { - "operationId": "appmultiauth_post", + "operationId": "PostAppMultiAuth", "responses": { "200": { "content": { @@ -1373,7 +1373,7 @@ "/app/receipt": { "get": { "description": "A signed statement from the service over a transaction entry in the ledger", - "operationId": "appreceipt_get", + "operationId": "GetAppReceipt", "parameters": [ { "in": "query", @@ -1408,7 +1408,7 @@ "/app/tx": { "get": { "description": "Possible statuses returned are Unknown, Pending, Committed or Invalid.", - "operationId": "apptx_get", + "operationId": "GetAppTx", "parameters": [ { "in": "query", diff --git a/doc/schemas/gov_openapi.json b/doc/schemas/gov_openapi.json index 352271ed7836..5f17a2d971c8 100644 --- a/doc/schemas/gov_openapi.json +++ b/doc/schemas/gov_openapi.json @@ -1357,7 +1357,7 @@ "paths": { "/gov/ack": { "post": { - "operationId": "govack_post", + "operationId": "PostGovAck", "requestBody": { "content": { "application/json": { @@ -1389,7 +1389,7 @@ }, "/gov/ack/update_state_digest": { "post": { - "operationId": "govackupdatestatedigest_post", + "operationId": "PostGovAckUpdateStateDigest", "responses": { "200": { "content": { @@ -1418,7 +1418,7 @@ }, "/gov/api": { "get": { - "operationId": "govapi_get", + "operationId": "GetGovApi", "responses": { "200": { "content": { @@ -1444,7 +1444,7 @@ "get": { "deprecated": true, "description": "Permitted SGX code identities", - "operationId": "govcode_get", + "operationId": "GetGovCode", "responses": { "200": { "content": { @@ -1469,7 +1469,7 @@ "/gov/commit": { "get": { "description": "Latest transaction ID that has been committed on the service", - "operationId": "govcommit_get", + "operationId": "GetGovCommit", "parameters": [ { "in": "query", @@ -1511,7 +1511,7 @@ }, "/gov/encrypted_recovery_share/{member_id}": { "get": { - "operationId": "govencryptedrecoveryshare{memberid}_get", + "operationId": "GetGovEncryptedRecoveryShareMemberId", "responses": { "200": { "content": { @@ -1546,7 +1546,7 @@ "/gov/jwt_keys/all": { "get": { "deprecated": true, - "operationId": "govjwtkeysall_get", + "operationId": "GetGovJwtKeysAll", "responses": { "200": { "content": { @@ -1570,7 +1570,7 @@ }, "/gov/kv/constitution": { "get": { - "operationId": "govkvconstitution_get", + "operationId": "GetGovKvConstitution", "responses": { "200": { "content": { @@ -1593,7 +1593,7 @@ }, "/gov/kv/cose_history": { "get": { - "operationId": "govkvcosehistory_get", + "operationId": "GetGovKvCoseHistory", "responses": { "200": { "content": { @@ -1616,7 +1616,7 @@ }, "/gov/kv/cose_recent_proposals": { "get": { - "operationId": "govkvcoserecentproposals_get", + "operationId": "GetGovKvCoseRecentProposals", "responses": { "200": { "content": { @@ -1639,7 +1639,7 @@ }, "/gov/kv/endpoints": { "get": { - "operationId": "govkvendpoints_get", + "operationId": "GetGovKvEndpoints", "responses": { "200": { "content": { @@ -1662,7 +1662,7 @@ }, "/gov/kv/history": { "get": { - "operationId": "govkvhistory_get", + "operationId": "GetGovKvHistory", "responses": { "200": { "content": { @@ -1685,7 +1685,7 @@ }, "/gov/kv/interpreter/flush": { "get": { - "operationId": "govkvinterpreterflush_get", + "operationId": "GetGovKvInterpreterFlush", "responses": { "200": { "content": { @@ -1708,7 +1708,7 @@ }, "/gov/kv/js_runtime_options": { "get": { - "operationId": "govkvjsruntimeoptions_get", + "operationId": "GetGovKvJsRuntimeOptions", "responses": { "200": { "content": { @@ -1731,7 +1731,7 @@ }, "/gov/kv/jwt/issuers": { "get": { - "operationId": "govkvjwtissuers_get", + "operationId": "GetGovKvJwtIssuers", "responses": { "200": { "content": { @@ -1754,7 +1754,7 @@ }, "/gov/kv/jwt/public_signing_key": { "get": { - "operationId": "govkvjwtpublicsigningkey_get", + "operationId": "GetGovKvJwtPublicSigningKey", "responses": { "200": { "content": { @@ -1777,7 +1777,7 @@ }, "/gov/kv/jwt/public_signing_key_issuer": { "get": { - "operationId": "govkvjwtpublicsigningkeyissuer_get", + "operationId": "GetGovKvJwtPublicSigningKeyIssuer", "responses": { "200": { "content": { @@ -1800,7 +1800,7 @@ }, "/gov/kv/jwt/public_signing_keys_metadata": { "get": { - "operationId": "govkvjwtpublicsigningkeysmetadata_get", + "operationId": "GetGovKvJwtPublicSigningKeysMetadata", "responses": { "200": { "content": { @@ -1823,7 +1823,7 @@ }, "/gov/kv/members/acks": { "get": { - "operationId": "govkvmembersacks_get", + "operationId": "GetGovKvMembersAcks", "responses": { "200": { "content": { @@ -1846,7 +1846,7 @@ }, "/gov/kv/members/certs": { "get": { - "operationId": "govkvmemberscerts_get", + "operationId": "GetGovKvMembersCerts", "responses": { "200": { "content": { @@ -1869,7 +1869,7 @@ }, "/gov/kv/members/encryption_public_keys": { "get": { - "operationId": "govkvmembersencryptionpublickeys_get", + "operationId": "GetGovKvMembersEncryptionPublicKeys", "responses": { "200": { "content": { @@ -1892,7 +1892,7 @@ }, "/gov/kv/members/info": { "get": { - "operationId": "govkvmembersinfo_get", + "operationId": "GetGovKvMembersInfo", "responses": { "200": { "content": { @@ -1915,7 +1915,7 @@ }, "/gov/kv/modules": { "get": { - "operationId": "govkvmodules_get", + "operationId": "GetGovKvModules", "responses": { "200": { "content": { @@ -1938,7 +1938,7 @@ }, "/gov/kv/modules_quickjs_bytecode": { "get": { - "operationId": "govkvmodulesquickjsbytecode_get", + "operationId": "GetGovKvModulesQuickjsBytecode", "responses": { "200": { "content": { @@ -1961,7 +1961,7 @@ }, "/gov/kv/modules_quickjs_version": { "get": { - "operationId": "govkvmodulesquickjsversion_get", + "operationId": "GetGovKvModulesQuickjsVersion", "responses": { "200": { "content": { @@ -1984,7 +1984,7 @@ }, "/gov/kv/nodes/code_ids": { "get": { - "operationId": "govkvnodescodeids_get", + "operationId": "GetGovKvNodesCodeIds", "responses": { "200": { "content": { @@ -2007,7 +2007,7 @@ }, "/gov/kv/nodes/endorsed_certificates": { "get": { - "operationId": "govkvnodesendorsedcertificates_get", + "operationId": "GetGovKvNodesEndorsedCertificates", "responses": { "200": { "content": { @@ -2030,7 +2030,7 @@ }, "/gov/kv/nodes/info": { "get": { - "operationId": "govkvnodesinfo_get", + "operationId": "GetGovKvNodesInfo", "responses": { "200": { "content": { @@ -2053,7 +2053,7 @@ }, "/gov/kv/nodes/snp/host_data": { "get": { - "operationId": "govkvnodessnphostdata_get", + "operationId": "GetGovKvNodesSnpHostData", "responses": { "200": { "content": { @@ -2076,7 +2076,7 @@ }, "/gov/kv/nodes/snp/measurements": { "get": { - "operationId": "govkvnodessnpmeasurements_get", + "operationId": "GetGovKvNodesSnpMeasurements", "responses": { "200": { "content": { @@ -2099,7 +2099,7 @@ }, "/gov/kv/nodes/snp/uvm_endorsements": { "get": { - "operationId": "govkvnodessnpuvmendorsements_get", + "operationId": "GetGovKvNodesSnpUvmEndorsements", "responses": { "200": { "content": { @@ -2122,7 +2122,7 @@ }, "/gov/kv/proposals": { "get": { - "operationId": "govkvproposals_get", + "operationId": "GetGovKvProposals", "responses": { "200": { "content": { @@ -2145,7 +2145,7 @@ }, "/gov/kv/proposals_info": { "get": { - "operationId": "govkvproposalsinfo_get", + "operationId": "GetGovKvProposalsInfo", "responses": { "200": { "content": { @@ -2168,7 +2168,7 @@ }, "/gov/kv/service/acme_certificates": { "get": { - "operationId": "govkvserviceacmecertificates_get", + "operationId": "GetGovKvServiceAcmeCertificates", "responses": { "200": { "content": { @@ -2191,7 +2191,7 @@ }, "/gov/kv/service/config": { "get": { - "operationId": "govkvserviceconfig_get", + "operationId": "GetGovKvServiceConfig", "responses": { "200": { "content": { @@ -2214,7 +2214,7 @@ }, "/gov/kv/service/info": { "get": { - "operationId": "govkvserviceinfo_get", + "operationId": "GetGovKvServiceInfo", "responses": { "200": { "content": { @@ -2237,7 +2237,7 @@ }, "/gov/kv/service/previous_service_identity": { "get": { - "operationId": "govkvservicepreviousserviceidentity_get", + "operationId": "GetGovKvServicePreviousServiceIdentity", "responses": { "200": { "content": { @@ -2260,7 +2260,7 @@ }, "/gov/kv/tls/ca_cert_bundles": { "get": { - "operationId": "govkvtlscacertbundles_get", + "operationId": "GetGovKvTlsCaCertBundles", "responses": { "200": { "content": { @@ -2283,7 +2283,7 @@ }, "/gov/kv/users/certs": { "get": { - "operationId": "govkvuserscerts_get", + "operationId": "GetGovKvUsersCerts", "responses": { "200": { "content": { @@ -2306,7 +2306,7 @@ }, "/gov/kv/users/info": { "get": { - "operationId": "govkvusersinfo_get", + "operationId": "GetGovKvUsersInfo", "responses": { "200": { "content": { @@ -2330,7 +2330,7 @@ "/gov/members": { "get": { "deprecated": true, - "operationId": "govmembers_get", + "operationId": "GetGovMembers", "responses": { "200": { "content": { @@ -2354,7 +2354,7 @@ }, "/gov/proposals": { "get": { - "operationId": "govproposals_get", + "operationId": "GetGovProposals", "responses": { "200": { "content": { @@ -2376,7 +2376,7 @@ } }, "post": { - "operationId": "govproposals_post", + "operationId": "PostGovProposals", "requestBody": { "content": { "application/json": { @@ -2415,7 +2415,7 @@ }, "/gov/proposals/{proposal_id}": { "get": { - "operationId": "govproposals{proposalid}_get", + "operationId": "GetGovProposalsProposalId", "responses": { "200": { "content": { @@ -2449,7 +2449,7 @@ }, "/gov/proposals/{proposal_id}/actions": { "get": { - "operationId": "govproposals{proposalid}actions_get", + "operationId": "GetGovProposalsProposalIdActions", "responses": { "200": { "content": { @@ -2493,7 +2493,7 @@ } ], "post": { - "operationId": "govproposals{proposalid}ballots_post", + "operationId": "PostGovProposalsProposalIdBallots", "requestBody": { "content": { "application/json": { @@ -2532,7 +2532,7 @@ }, "/gov/proposals/{proposal_id}/ballots/{member_id}": { "get": { - "operationId": "govproposals{proposalid}ballots{memberid}_get", + "operationId": "GetGovProposalsProposalIdBallotsMemberId", "responses": { "200": { "content": { @@ -2584,7 +2584,7 @@ } ], "post": { - "operationId": "govproposals{proposalid}withdraw_post", + "operationId": "PostGovProposalsProposalIdWithdraw", "responses": { "200": { "content": { @@ -2614,7 +2614,7 @@ "/gov/receipt": { "get": { "description": "A signed statement from the service over a transaction entry in the ledger", - "operationId": "govreceipt_get", + "operationId": "GetGovReceipt", "parameters": [ { "in": "query", @@ -2649,7 +2649,7 @@ "/gov/recovery_share": { "get": { "deprecated": true, - "operationId": "govrecoveryshare_get", + "operationId": "GetGovRecoveryShare", "responses": { "200": { "content": { @@ -2676,7 +2676,7 @@ } }, "post": { - "operationId": "govrecoveryshare_post", + "operationId": "PostGovRecoveryShare", "requestBody": { "content": { "application/json": { @@ -2716,7 +2716,7 @@ "/gov/tx": { "get": { "description": "Possible statuses returned are Unknown, Pending, Committed or Invalid.", - "operationId": "govtx_get", + "operationId": "GetGovTx", "parameters": [ { "in": "query", diff --git a/doc/schemas/node_openapi.json b/doc/schemas/node_openapi.json index 4710d24ae518..a74b5b253b8e 100644 --- a/doc/schemas/node_openapi.json +++ b/doc/schemas/node_openapi.json @@ -902,7 +902,7 @@ "paths": { "/node/api": { "get": { - "operationId": "nodeapi_get", + "operationId": "GetNodeApi", "responses": { "200": { "content": { @@ -926,7 +926,7 @@ }, "/node/backup": { "get": { - "operationId": "nodebackup_get", + "operationId": "GetNodeBackup", "responses": { "200": { "description": "Default response description" @@ -944,7 +944,7 @@ "get": { "deprecated": true, "description": "Permitted SGX code identities", - "operationId": "nodecode_get", + "operationId": "GetNodeCode", "responses": { "200": { "content": { @@ -969,7 +969,7 @@ "/node/commit": { "get": { "description": "Latest transaction ID that has been committed on the service", - "operationId": "nodecommit_get", + "operationId": "GetNodeCommit", "parameters": [ { "in": "query", @@ -1011,7 +1011,7 @@ }, "/node/config": { "get": { - "operationId": "nodeconfig_get", + "operationId": "GetNodeConfig", "responses": { "200": { "content": { @@ -1034,7 +1034,7 @@ }, "/node/consensus": { "get": { - "operationId": "nodeconsensus_get", + "operationId": "GetNodeConsensus", "responses": { "200": { "content": { @@ -1057,7 +1057,7 @@ }, "/node/index/strategies": { "get": { - "operationId": "nodeindexstrategies_get", + "operationId": "GetNodeIndexStrategies", "responses": { "200": { "content": { @@ -1080,7 +1080,7 @@ }, "/node/js_metrics": { "get": { - "operationId": "nodejsmetrics_get", + "operationId": "GetNodeJsMetrics", "responses": { "200": { "content": { @@ -1103,7 +1103,7 @@ }, "/node/jwt_keys/refresh/metrics": { "get": { - "operationId": "nodejwtkeysrefreshmetrics_get", + "operationId": "GetNodeJwtKeysRefreshMetrics", "responses": { "200": { "content": { @@ -1126,7 +1126,7 @@ }, "/node/memory": { "get": { - "operationId": "nodememory_get", + "operationId": "GetNodeMemory", "responses": { "200": { "content": { @@ -1149,7 +1149,7 @@ }, "/node/metrics": { "get": { - "operationId": "nodemetrics_get", + "operationId": "GetNodeMetrics", "responses": { "200": { "content": { @@ -1172,7 +1172,7 @@ }, "/node/network": { "get": { - "operationId": "nodenetwork_get", + "operationId": "GetNodeNetwork", "responses": { "200": { "content": { @@ -1195,7 +1195,7 @@ }, "/node/network/nodes": { "get": { - "operationId": "nodenetworknodes_get", + "operationId": "GetNodeNetworkNodes", "parameters": [ { "in": "query", @@ -1244,7 +1244,7 @@ }, "/node/network/nodes/primary": { "get": { - "operationId": "nodenetworknodesprimary_get", + "operationId": "GetNodeNetworkNodesPrimary", "responses": { "200": { "content": { @@ -1267,7 +1267,7 @@ }, "/node/network/nodes/self": { "get": { - "operationId": "nodenetworknodesself_get", + "operationId": "GetNodeNetworkNodesSelf", "responses": { "200": { "content": { @@ -1290,7 +1290,7 @@ }, "/node/network/nodes/{node_id}": { "delete": { - "operationId": "nodenetworknodes{nodeid}_delete", + "operationId": "DeleteNodeNetworkNodesNodeId", "responses": { "200": { "content": { @@ -1311,7 +1311,7 @@ } }, "get": { - "operationId": "nodenetworknodes{nodeid}_get", + "operationId": "GetNodeNetworkNodesNodeId", "responses": { "200": { "content": { @@ -1344,7 +1344,7 @@ }, "/node/network/removable_nodes": { "get": { - "operationId": "nodenetworkremovablenodes_get", + "operationId": "GetNodeNetworkRemovableNodes", "responses": { "200": { "content": { @@ -1367,7 +1367,7 @@ }, "/node/primary": { "get": { - "operationId": "nodeprimary_get", + "operationId": "GetNodePrimary", "responses": { "200": { "description": "Default response description" @@ -1381,7 +1381,7 @@ } }, "head": { - "operationId": "nodeprimary_head", + "operationId": "HeadNodePrimary", "responses": { "200": { "description": "Default response description" @@ -1397,7 +1397,7 @@ }, "/node/quotes": { "get": { - "operationId": "nodequotes_get", + "operationId": "GetNodeQuotes", "responses": { "200": { "content": { @@ -1420,7 +1420,7 @@ }, "/node/quotes/self": { "get": { - "operationId": "nodequotesself_get", + "operationId": "GetNodeQuotesSelf", "responses": { "200": { "content": { @@ -1443,7 +1443,7 @@ }, "/node/ready/app": { "get": { - "operationId": "nodereadyapp_get", + "operationId": "GetNodeReadyApp", "responses": { "204": { "description": "Default response description" @@ -1459,7 +1459,7 @@ }, "/node/ready/gov": { "get": { - "operationId": "nodereadygov_get", + "operationId": "GetNodeReadyGov", "responses": { "204": { "description": "Default response description" @@ -1476,7 +1476,7 @@ "/node/receipt": { "get": { "description": "A signed statement from the service over a transaction entry in the ledger", - "operationId": "nodereceipt_get", + "operationId": "GetNodeReceipt", "parameters": [ { "in": "query", @@ -1510,7 +1510,7 @@ }, "/node/self_signed_certificate": { "get": { - "operationId": "nodeselfsignedcertificate_get", + "operationId": "GetNodeSelfSignedCertificate", "responses": { "200": { "content": { @@ -1533,7 +1533,7 @@ }, "/node/service/configuration": { "get": { - "operationId": "nodeserviceconfiguration_get", + "operationId": "GetNodeServiceConfiguration", "responses": { "200": { "content": { @@ -1556,7 +1556,7 @@ }, "/node/service/previous_identity": { "get": { - "operationId": "nodeservicepreviousidentity_get", + "operationId": "GetNodeServicePreviousIdentity", "responses": { "200": { "content": { @@ -1579,7 +1579,7 @@ }, "/node/state": { "get": { - "operationId": "nodestate_get", + "operationId": "GetNodeState", "responses": { "200": { "content": { @@ -1603,7 +1603,7 @@ "/node/tx": { "get": { "description": "Possible statuses returned are Unknown, Pending, Committed or Invalid.", - "operationId": "nodetx_get", + "operationId": "GetNodeTx", "parameters": [ { "in": "query", @@ -1637,7 +1637,7 @@ }, "/node/version": { "get": { - "operationId": "nodeversion_get", + "operationId": "GetNodeVersion", "responses": { "200": { "content": { diff --git a/src/endpoints/endpoint_registry.cpp b/src/endpoints/endpoint_registry.cpp index f45a5cff2053..e84a2bead4eb 100644 --- a/src/endpoints/endpoint_registry.cpp +++ b/src/endpoints/endpoint_registry.cpp @@ -36,11 +36,23 @@ namespace ccf::endpoints // Add what appears a *mandatory* operationId, which is expected to be // unique across the spec. + // A1) Eliminate '{' and '}' from the path but keep the string inbetween. std::string p = - std::regex_replace(endpoint->full_uri_path, std::regex("[/_]"), ""); + std::regex_replace(endpoint->full_uri_path, std::regex("[{}]"), ""); + // A2) Camel-Case what remains at the path separator. + p = ccf::nonstd::camel_case(p); + + // B1) Get the HTTP verb as a string (it's all caps). std::string s = llhttp_method_name(http_verb.value()); + // B2) Lowercase it. ccf::nonstd::to_lower(s); - path_op["operationId"] = fmt::format("{}_{}", p, s); + // B3) Camel-Case it, i.e., the first char. + s = ccf::nonstd::camel_case(s, true); + + // C) Concatenate the camel-cased verb and path. For example, this gives + // us "PostAppLogPrivateRawTextId" for the verb POST and the path + // "/app/log/private/raw_text/{id}". + path_op["operationId"] = fmt::format("{}{}", s, p); // Path Operation must contain at least one response - if none has been // defined, assume this can return 200