Skip to content

Commit

Permalink
implement support for paging controller requests (#181)
Browse files Browse the repository at this point in the history
* implement paging for /sevices and /sessions requests

* up uv-mbed
  • Loading branch information
ekoby authored Nov 24, 2020
1 parent 2faf1e0 commit cca7a1b
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 24 deletions.
2 changes: 1 addition & 1 deletion deps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ include(FetchContent)

FetchContent_Declare(uv-mbed
GIT_REPOSITORY https://github.com/netfoundry/uv-mbed.git
GIT_TAG v0.9.0
GIT_TAG v0.9.1
)
set(ENABLE_UM_TESTS OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(uv-mbed)
Expand Down
4 changes: 2 additions & 2 deletions inc_internal/ziti_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ void ziti_ctrl_get_net_session(
ziti_controller *ctrl, const char *service_id, const char *type,
void (*cb)(ziti_net_session *, ziti_error *, void *), void *ctx);

void ziti_ctrl_get_net_sessions(
ziti_controller *ctrl, void (*cb)(ziti_net_session **, ziti_error*, void*), void* ctx);
void ziti_ctrl_get_sessions(
ziti_controller *ctrl, void (*cb)(ziti_net_session **, ziti_error *, void *), void *ctx);

void ziti_ctrl_get_well_known_certs(ziti_controller *ctrl, void (*cb)(char *, ziti_error *, void *), void *ctx);

Expand Down
4 changes: 2 additions & 2 deletions library/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ static uint64_t clock_offset;
void ziti_set_log(FILE *log, uv_loop_t *loop) {
init_debug(loop);
ziti_debug_out = log;
uv_mbed_set_debug(ziti_debug_level, log);
// uv_mbed_set_debug(ziti_debug_level, log);
}

void init_debug(uv_loop_t *loop) {
Expand All @@ -130,7 +130,7 @@ void init_debug(uv_loop_t *loop) {
ziti_debug_level = (int) strtol(level, NULL, 10);
}
ziti_debug_out = stderr;
uv_mbed_set_debug(ziti_debug_level, ziti_debug_out);
//uv_mbed_set_debug(ziti_debug_level, ziti_debug_out);

starttime = uv_now(loop);
uv_timeval64_t clock;
Expand Down
94 changes: 81 additions & 13 deletions library/ziti_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,40 @@ limitations under the License.

#endif

#define DEFAULT_PAGE_SIZE 25

const char *const PC_DOMAIN_TYPE = "DOMAIN";
const char *const PC_OS_TYPE = "OS";
const char *const PC_PROCESS_TYPE = "PROCESS";
const char *const PC_MAC_TYPE = "MAC";

#define CTRL_REQ_MODEL(XX, ...) \
XX(meta, json, none, meta, __VA_ARGS__) \
#undef MODEL_API
#define MODEL_API static

#define PAGINATION_MODEL(XX, ...) \
XX(limit, int, none, limit, __VA_ARGS__) \
XX(offset, int, none, offset, __VA_ARGS__) \
XX(total, int, none, totalCount, __VA_ARGS__) \

DECLARE_MODEL(resp_pagination, PAGINATION_MODEL)

#define RESP_META_MODEL(XX, ...) \
XX(pagination,resp_pagination,none,pagination, __VA_ARGS__)

DECLARE_MODEL(resp_meta, RESP_META_MODEL)

#define API_RESP_MODEL(XX, ...) \
XX(meta, resp_meta, none, meta, __VA_ARGS__) \
XX(data, json, none, data, __VA_ARGS__) \
XX(error, ziti_error, ptr, error, __VA_ARGS__)

#define MODEL_API static
DECLARE_MODEL(ctrl_resp, CTRL_REQ_MODEL)
DECLARE_MODEL(api_resp, API_RESP_MODEL)

IMPL_MODEL(resp_pagination, PAGINATION_MODEL)

IMPL_MODEL(resp_meta, RESP_META_MODEL)

IMPL_MODEL(ctrl_resp, CTRL_REQ_MODEL)
IMPL_MODEL(api_resp, API_RESP_MODEL)

int code_to_error(const char *code) {

Expand Down Expand Up @@ -69,6 +89,13 @@ struct ctrl_resp {
bool resp_chunked;
bool resp_text_plain;

bool paging;
const char *base_path;
int limit;
int total;
int recd;
void **resp_array;

int (*body_parse_func)(void *, const char *, size_t);

void (*resp_cb)(void *, ziti_error *, void *);
Expand All @@ -80,6 +107,8 @@ struct ctrl_resp {
void (*ctrl_cb)(void *, ziti_error *, struct ctrl_resp *);
};

static void ctrl_paging_req(struct ctrl_resp *resp);

static char *str_array_to_json(const char **arr);

static void ctrl_default_cb(void *s, ziti_error *e, struct ctrl_resp *resp);
Expand Down Expand Up @@ -178,25 +207,49 @@ static void ctrl_body_cb(um_http_req_t *req, const char *b, ssize_t len) {
} else if (len == UV_EOF) {
void *resp_obj = NULL;

ctrl_resp cr = {0};
api_resp cr = {0};
if (resp->resp_text_plain && resp->status < 300) {
resp_obj = calloc(1, resp->received + 1);
memcpy(resp_obj, resp->body, resp->received);
} else {
int rc = parse_ctrl_resp(&cr, resp->body, resp->received);
int rc = parse_api_resp(&cr, resp->body, resp->received);
if (rc < 0) {
ZITI_LOG(ERROR, "failed to parse controller response of req[%s]", req->path);
cr.error = alloc_ziti_error();
cr.error->code = strdup("INVALID_CONTROLLER_RESPONSE");
cr.error->message = strdup(req->resp.status);
} else if (resp->body_parse_func && cr.data != NULL) {
}
else if (resp->body_parse_func && cr.data != NULL) {
if (resp->body_parse_func(&resp_obj, cr.data, strlen(cr.data)) != 0) {
ZITI_LOG(ERROR, "error parsing result of req[%s]", req->path);
}

if (resp->paging) {
bool last_page = cr.meta.pagination.total <= cr.meta.pagination.offset + cr.meta.pagination.limit;
if (cr.meta.pagination.total > resp->total) {
resp->total = cr.meta.pagination.total;
resp->resp_array = realloc(resp->resp_array, (resp->total + 1) * sizeof(void *));
}
void **chunk = resp_obj;
while (*chunk != NULL) {
resp->resp_array[resp->recd++] = *chunk++;
}
resp->resp_array[resp->recd] = NULL;
FREE(resp_obj);
resp->received = 0;
FREE(resp->body);

free_api_resp(&cr);
if (!last_page) {
ctrl_paging_req(resp);
return;
}
resp_obj = resp->resp_array;
}
}
}
FREE(cr.meta);
FREE(cr.data);

free_api_resp(&cr);
FREE(resp->body);

resp->ctrl_cb(resp_obj, cr.error, resp);
Expand Down Expand Up @@ -306,7 +359,9 @@ void ziti_ctrl_get_services(ziti_controller *ctrl, void (*cb)(ziti_service_array
resp->ctrl = ctrl;
resp->ctrl_cb = (void (*)(void *, ziti_error *, struct ctrl_resp *)) ctrl_services_cb;

um_http_req(&ctrl->client, "GET", "/services?limit=1000", ctrl_resp_cb, resp);
resp->paging = true;
resp->base_path = "/services";
ctrl_paging_req(resp);
}

void
Expand Down Expand Up @@ -346,7 +401,7 @@ void ziti_ctrl_get_net_session(
um_http_req_data(req, content, len, free_body_cb);
}

void ziti_ctrl_get_net_sessions(
void ziti_ctrl_get_sessions(
ziti_controller *ctrl, void (*cb)(ziti_net_session **, ziti_error *, void *), void *ctx) {

struct ctrl_resp *resp = calloc(1, sizeof(struct ctrl_resp));
Expand All @@ -356,7 +411,9 @@ void ziti_ctrl_get_net_sessions(
resp->ctrl = ctrl;
resp->ctrl_cb = ctrl_default_cb;

um_http_req(&ctrl->client, "GET", "/sessions", ctrl_resp_cb, resp);
resp->paging = true;
resp->base_path = "/sessions";
ctrl_paging_req(resp);
}

static void enroll_pem_cb(void *body, ziti_error *err, struct ctrl_resp *resp) {
Expand Down Expand Up @@ -567,3 +624,14 @@ void ziti_ctrl_pr_post_process(ziti_controller *ctrl, char *id, bool is_running,

free(null_term_signers);
}

static void ctrl_paging_req(struct ctrl_resp *resp) {
if (resp->limit == 0) {
resp->limit = DEFAULT_PAGE_SIZE;
}
char query = strchr(resp->base_path, '?') ? '&' : '?';
char path[128];
snprintf(path, sizeof(path), "%s%climit=%d&offset=%d", resp->base_path, query, resp->limit, resp->recd);
ZITI_LOG(VERBOSE, "requesting %s", path);
um_http_req(&resp->ctrl->client, "GET", path, ctrl_resp_cb, resp);
}
10 changes: 4 additions & 6 deletions tests/ctrl_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ TEST_CASE("invalid_controller", "[controller][GH-44]") {
}

TEST_CASE("controller_test","[integ]") {
uv_mbed_set_debug(5, stdout);

char *conf = getenv("ZITI_SDK_CONFIG");
if (conf == nullptr) {
FAIL("ZITI_SDK_CONFIG environment variable is not set");
Expand All @@ -103,7 +101,7 @@ TEST_CASE("controller_test","[integ]") {
WHEN("get version and login") {

ziti_ctrl_get_version(&ctrl, resp_cb, &version);
ziti_ctrl_login(&ctrl, NULL, resp_cb, &session);
ziti_ctrl_login(&ctrl, nullptr, resp_cb, &session);

uv_run(loop, UV_RUN_DEFAULT);

Expand All @@ -122,7 +120,7 @@ TEST_CASE("controller_test","[integ]") {

ziti_ctrl_get_service(&ctrl, "wttr.in", resp_cb, &service);

int rc = uv_run(loop, UV_RUN_DEFAULT);
uv_run(loop, UV_RUN_DEFAULT);
THEN("should get error") {
REQUIRE(service.resp == nullptr);
REQUIRE(service.error != nullptr);
Expand All @@ -133,7 +131,7 @@ TEST_CASE("controller_test","[integ]") {
WHEN("try to login and get non-existing service") {
resp_capture<ziti_service> service2;

ziti_ctrl_login(&ctrl, NULL, resp_cb, &session);
ziti_ctrl_login(&ctrl, nullptr, resp_cb, &session);
ziti_ctrl_get_service(&ctrl, "this-service-should-not-exist", resp_cb, &service2);

int rc = uv_run(loop, UV_RUN_DEFAULT);
Expand Down Expand Up @@ -164,7 +162,7 @@ TEST_CASE("controller_test","[integ]") {
ziti_ctrl_logout(re->c, logout_cb, &re->logout);

};
ziti_ctrl_login(&ctrl, NULL, resp_cb, &r.session);
ziti_ctrl_login(&ctrl, nullptr, resp_cb, &r.session);
ziti_ctrl_get_service(&ctrl, "wttr.in", serv_cb, &r);

int rc = uv_run(loop, UV_RUN_DEFAULT);
Expand Down

0 comments on commit cca7a1b

Please sign in to comment.