bridging: Add creation timestamps
This small feature will help to checking the bridge's status to figure out which bridge is in old/zombie or not. Also added detail items for the 'bridge show *' cli to provide more detail info. And added creation item to the ARI as well. ASTERISK-28279 Change-Id: I460238c488eca4d216b9176576211cb03286e040
This commit is contained in:
parent
61585af9bd
commit
0d7012044a
|
@ -358,6 +358,8 @@ struct ast_bridge {
|
|||
|
||||
/*! Type mapping used for media routing */
|
||||
struct ast_vector_int media_types;
|
||||
/*! The time of bridge creation */
|
||||
struct timeval creationtime;
|
||||
};
|
||||
|
||||
/*! \brief Bridge base class virtual method table. */
|
||||
|
|
|
@ -62,6 +62,8 @@ struct ast_bridge_snapshot {
|
|||
unsigned int num_active;
|
||||
/*! The video mode of the bridge */
|
||||
enum ast_bridge_video_mode_type video_mode;
|
||||
/*! The time of bridge creation */
|
||||
struct timeval creationtime;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -847,6 +847,8 @@ struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabiliti
|
|||
}
|
||||
}
|
||||
|
||||
self->creationtime = ast_tvnow();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -5102,8 +5104,8 @@ static char *complete_bridge_stasis(const char *word)
|
|||
|
||||
static char *handle_bridge_show_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
{
|
||||
#define FORMAT_HDR "%-36s %5s %-15s %s\n"
|
||||
#define FORMAT_ROW "%-36s %5u %-15s %s\n"
|
||||
#define FORMAT_HDR "%-36s %5s %-15s %-15s %s\n"
|
||||
#define FORMAT_ROW "%-36s %5u %-15s %-15s %s\n"
|
||||
|
||||
RAII_VAR(struct ao2_container *, cached_bridges, NULL, ao2_cleanup);
|
||||
struct ao2_iterator iter;
|
||||
|
@ -5126,17 +5128,21 @@ static char *handle_bridge_show_all(struct ast_cli_entry *e, int cmd, struct ast
|
|||
return CLI_SUCCESS;
|
||||
}
|
||||
|
||||
ast_cli(a->fd, FORMAT_HDR, "Bridge-ID", "Chans", "Type", "Technology");
|
||||
ast_cli(a->fd, FORMAT_HDR, "Bridge-ID", "Chans", "Type", "Technology", "Duration");
|
||||
|
||||
iter = ao2_iterator_init(cached_bridges, 0);
|
||||
for (; (msg = ao2_iterator_next(&iter)); ao2_ref(msg, -1)) {
|
||||
struct ast_bridge_snapshot *snapshot = stasis_message_data(msg);
|
||||
char print_time[32];
|
||||
|
||||
ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
|
||||
|
||||
ast_cli(a->fd, FORMAT_ROW,
|
||||
snapshot->uniqueid,
|
||||
snapshot->num_channels,
|
||||
S_OR(snapshot->subclass, "<unknown>"),
|
||||
S_OR(snapshot->technology, "<unknown>"));
|
||||
S_OR(snapshot->technology, "<unknown>"),
|
||||
print_time);
|
||||
}
|
||||
ao2_iterator_destroy(&iter);
|
||||
return CLI_SUCCESS;
|
||||
|
@ -5168,6 +5174,7 @@ static char *handle_bridge_show_specific(struct ast_cli_entry *e, int cmd, struc
|
|||
{
|
||||
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
||||
struct ast_bridge_snapshot *snapshot;
|
||||
char print_time[32];
|
||||
|
||||
switch (cmd) {
|
||||
case CLI_INIT:
|
||||
|
@ -5194,10 +5201,18 @@ static char *handle_bridge_show_specific(struct ast_cli_entry *e, int cmd, struc
|
|||
}
|
||||
|
||||
snapshot = stasis_message_data(msg);
|
||||
ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
|
||||
|
||||
ast_cli(a->fd, "Id: %s\n", snapshot->uniqueid);
|
||||
ast_cli(a->fd, "Type: %s\n", S_OR(snapshot->subclass, "<unknown>"));
|
||||
ast_cli(a->fd, "Technology: %s\n", S_OR(snapshot->technology, "<unknown>"));
|
||||
ast_cli(a->fd, "Subclass: %s\n", snapshot->subclass);
|
||||
ast_cli(a->fd, "Creator: %s\n", snapshot->creator);
|
||||
ast_cli(a->fd, "Name: %s\n", snapshot->name);
|
||||
ast_cli(a->fd, "Video-Source-Id: %s\n", snapshot->video_source_id);
|
||||
ast_cli(a->fd, "Num-Channels: %u\n", snapshot->num_channels);
|
||||
ast_cli(a->fd, "Num-Active: %u\n", snapshot->num_active);
|
||||
ast_cli(a->fd, "Duration: %s\n", print_time);
|
||||
ao2_callback(snapshot->channels, OBJ_NODATA, bridge_show_specific_print_channel, a);
|
||||
|
||||
return CLI_SUCCESS;
|
||||
|
|
|
@ -278,6 +278,7 @@ struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge
|
|||
snapshot->capabilities = bridge->technology->capabilities;
|
||||
snapshot->num_channels = bridge->num_channels;
|
||||
snapshot->num_active = bridge->num_active;
|
||||
snapshot->creationtime = bridge->creationtime;
|
||||
snapshot->video_mode = bridge->softmix.video_mode.mode;
|
||||
if (snapshot->video_mode == AST_BRIDGE_VIDEO_MODE_SINGLE_SRC
|
||||
&& bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc) {
|
||||
|
@ -620,7 +621,7 @@ struct ast_json *ast_bridge_snapshot_to_json(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
json_bridge = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o, s: s}",
|
||||
json_bridge = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o, s: o, s: s}",
|
||||
"id", snapshot->uniqueid,
|
||||
"technology", snapshot->technology,
|
||||
"bridge_type", capability2str(snapshot->capabilities),
|
||||
|
@ -628,6 +629,7 @@ struct ast_json *ast_bridge_snapshot_to_json(
|
|||
"creator", snapshot->creator,
|
||||
"name", snapshot->name,
|
||||
"channels", json_channels,
|
||||
"creationtime", ast_json_timeval(snapshot->creationtime, NULL),
|
||||
"video_mode", ast_bridge_video_mode_to_string(snapshot->video_mode));
|
||||
if (!json_bridge) {
|
||||
return NULL;
|
||||
|
|
|
@ -1360,6 +1360,7 @@ int ast_ari_validate_bridge(struct ast_json *json)
|
|||
int has_bridge_class = 0;
|
||||
int has_bridge_type = 0;
|
||||
int has_channels = 0;
|
||||
int has_creationtime = 0;
|
||||
int has_creator = 0;
|
||||
int has_id = 0;
|
||||
int has_name = 0;
|
||||
|
@ -1397,6 +1398,16 @@ int ast_ari_validate_bridge(struct ast_json *json)
|
|||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("creationtime", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_creationtime = 1;
|
||||
prop_is_valid = ast_ari_validate_date(
|
||||
ast_json_object_iter_value(iter));
|
||||
if (!prop_is_valid) {
|
||||
ast_log(LOG_ERROR, "ARI Bridge field creationtime failed validation\n");
|
||||
res = 0;
|
||||
}
|
||||
} else
|
||||
if (strcmp("creator", ast_json_object_iter_key(iter)) == 0) {
|
||||
int prop_is_valid;
|
||||
has_creator = 1;
|
||||
|
@ -1478,6 +1489,11 @@ int ast_ari_validate_bridge(struct ast_json *json)
|
|||
res = 0;
|
||||
}
|
||||
|
||||
if (!has_creationtime) {
|
||||
ast_log(LOG_ERROR, "ARI Bridge missing required field creationtime\n");
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (!has_creator) {
|
||||
ast_log(LOG_ERROR, "ARI Bridge missing required field creator\n");
|
||||
res = 0;
|
||||
|
|
|
@ -1488,6 +1488,7 @@ ari_validator ast_ari_validate_application_fn(void);
|
|||
* - bridge_class: string (required)
|
||||
* - bridge_type: string (required)
|
||||
* - channels: List[string] (required)
|
||||
* - creationtime: Date (required)
|
||||
* - creator: string (required)
|
||||
* - id: string (required)
|
||||
* - name: string (required)
|
||||
|
|
|
@ -753,6 +753,11 @@
|
|||
"type": "string",
|
||||
"description": "The ID of the channel that is the source of video in this bridge, if one exists.",
|
||||
"required": false
|
||||
},
|
||||
"creationtime": {
|
||||
"required": true,
|
||||
"type": "Date",
|
||||
"description": "Timestamp when bridge was created"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue