зеркало из https://github.com/microsoft/CCF.git
Primary endpoint (#1439)
This commit is contained in:
Родитель
bf3a5f1930
Коммит
122f6a284e
|
@ -341,6 +341,7 @@ class RequestClient:
|
|||
"url": f"https://{self.host}:{self.port}{request.path}",
|
||||
"auth": auth_value,
|
||||
"headers": extra_headers,
|
||||
"allow_redirects": False,
|
||||
}
|
||||
|
||||
if request.params is not None:
|
||||
|
@ -491,6 +492,9 @@ class CCFClient:
|
|||
def delete(self, *args, **kwargs):
|
||||
return self.call(*args, http_verb="DELETE", **kwargs)
|
||||
|
||||
def head(self, *args, **kwargs):
|
||||
return self.call(*args, http_verb="HEAD", **kwargs)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def client(
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace ccf
|
|||
{
|
||||
Sometimes,
|
||||
Always,
|
||||
Never
|
||||
};
|
||||
|
||||
/** The EndpointRegistry records the user-defined endpoints for a given
|
||||
|
|
|
@ -335,6 +335,11 @@ namespace ccf
|
|||
{
|
||||
switch (endpoint->forwarding_required)
|
||||
{
|
||||
case ForwardingRequired::Never:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case ForwardingRequired::Sometimes:
|
||||
{
|
||||
if (ctx->session->is_forwarding)
|
||||
|
|
|
@ -317,6 +317,33 @@ namespace ccf
|
|||
make_read_only_endpoint(
|
||||
"network", HTTP_GET, json_read_only_adapter(network_status))
|
||||
.install();
|
||||
|
||||
auto is_primary = [this](ReadOnlyEndpointContext& args) {
|
||||
if (this->node.is_primary())
|
||||
{
|
||||
args.rpc_ctx->set_response_status(HTTP_STATUS_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.rpc_ctx->set_response_status(HTTP_STATUS_PERMANENT_REDIRECT);
|
||||
if (consensus != nullptr)
|
||||
{
|
||||
NodeId primary_id = consensus->primary();
|
||||
auto nodes_view = args.tx.get_read_only_view(this->network.nodes);
|
||||
auto info = nodes_view->get(primary_id);
|
||||
if (info)
|
||||
{
|
||||
args.rpc_ctx->set_response_header(
|
||||
"Location",
|
||||
fmt::format(
|
||||
"https://{}:{}/node/primary", info->pubhost, info->rpcport));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
make_read_only_endpoint("primary", HTTP_HEAD, is_primary)
|
||||
.set_forwarding_required(ForwardingRequired::Never)
|
||||
.install();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -539,6 +539,28 @@ def test_tx_statuses(network, args):
|
|||
return network
|
||||
|
||||
|
||||
@reqs.description("Primary and redirection")
|
||||
@reqs.at_least_n_nodes(2)
|
||||
def test_primary(network, args, notifications_queue=None, verify=True):
|
||||
LOG.error(network.nodes)
|
||||
primary, _ = network.find_primary()
|
||||
LOG.error(f"PRIMARY {primary.pubhost}")
|
||||
with primary.client() as c:
|
||||
r = c.head("/node/primary")
|
||||
assert r.status == http.HTTPStatus.OK.value
|
||||
|
||||
backup = network.find_any_backup()
|
||||
LOG.error(f"BACKUP {backup.pubhost}")
|
||||
with backup.client() as c:
|
||||
r = c.head("/node/primary")
|
||||
assert r.status == http.HTTPStatus.PERMANENT_REDIRECT.value
|
||||
assert (
|
||||
r.headers["location"]
|
||||
== f"https://{primary.pubhost}:{primary.rpc_port}/node/primary"
|
||||
)
|
||||
return network
|
||||
|
||||
|
||||
def run(args):
|
||||
hosts = ["localhost"] * (3 if args.consensus == "pbft" else 2)
|
||||
|
||||
|
@ -573,6 +595,7 @@ def run(args):
|
|||
network = test_raw_text(network, args)
|
||||
network = test_historical_query(network, args)
|
||||
network = test_view_history(network, args)
|
||||
network = test_primary(network, args)
|
||||
network = test_metrics(network, args)
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче