switch_status_t mod_amqp_command_create(char *name, switch_xml_t cfg) { mod_amqp_command_profile_t *profile = NULL; switch_xml_t params, param, connections, connection; switch_threadattr_t *thd_attr = NULL; switch_memory_pool_t *pool; char *exchange = NULL, *binding_key = NULL, *queue = NULL; if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { goto err; } profile = switch_core_alloc(pool, sizeof(mod_amqp_command_profile_t)); profile->pool = pool; profile->name = switch_core_strdup(profile->pool, name); profile->running = 1; profile->reconnect_interval_ms = 1000; if ((params = switch_xml_child(cfg, "params")) != NULL) { for (param = switch_xml_child(params, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!var) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param missing 'name' attribute\n", profile->name); continue; } if (!val) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param[%s] missing 'value' attribute\n", profile->name, var); continue; } if (!strncmp(var, "reconnect_interval_ms", 21)) { int interval = atoi(val); if ( interval && interval > 0 ) { profile->reconnect_interval_ms = interval; } } else if (!strncmp(var, "exchange-name", 13)) { exchange = switch_core_strdup(profile->pool, val); } else if (!strncmp(var, "queue-name", 10)) { queue = switch_core_strdup(profile->pool, val); } else if (!strncmp(var, "binding_key", 11)) { binding_key = switch_core_strdup(profile->pool, val); } } } /* Handle defaults of string types */ profile->exchange = exchange ? exchange : switch_core_strdup(profile->pool, "TAP.Commands"); profile->queue = queue ? queue : NULL; profile->binding_key = binding_key ? binding_key : switch_core_strdup(profile->pool, "commandBindingKey"); if ((connections = switch_xml_child(cfg, "connections")) != NULL) { for (connection = switch_xml_child(connections, "connection"); connection; connection = connection->next) { if ( ! profile->conn_root ) { /* Handle first root node */ if (mod_amqp_connection_create(&(profile->conn_root), connection, profile->pool) != SWITCH_STATUS_SUCCESS) { /* Handle connection create failure */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create connection\n", profile->name); continue; } profile->conn_active = profile->conn_root; } else { if (mod_amqp_connection_create(&(profile->conn_active->next), connection, profile->pool) != SWITCH_STATUS_SUCCESS) { /* Handle connection create failure */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create connection\n", profile->name); continue; } profile->conn_active = profile->conn_active->next; } } } profile->conn_active = NULL; /* We are not going to open the command queue connection on create, but instead wait for the running thread to open it */ /* Start the worker threads */ switch_threadattr_create(&thd_attr, profile->pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); if (switch_thread_create(&profile->command_thread, thd_attr, mod_amqp_command_thread, profile, profile->pool)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create 'amqp event sender' thread!\n"); goto err; } if ( switch_core_hash_insert(globals.command_hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to insert new profile [%s] into mod_amqp profile hash\n", name); goto err; } return SWITCH_STATUS_SUCCESS; err: /* Cleanup */ mod_amqp_command_destroy(&profile); return SWITCH_STATUS_GENERR; }
switch_status_t mod_amqp_logging_create(char *name, switch_xml_t cfg) { mod_amqp_logging_profile_t *profile = NULL; switch_xml_t params, param, connections, connection; switch_threadattr_t *thd_attr = NULL; char *exchange = NULL, *exchange_type = NULL; int exchange_durable = 1; /* durable */ switch_memory_pool_t *pool; if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) { goto err; } profile = switch_core_alloc(pool, sizeof(mod_amqp_logging_profile_t)); profile->pool = pool; profile->name = switch_core_strdup(profile->pool, name); profile->running = 1; profile->conn_root = NULL; profile->conn_active = NULL; profile->log_level_mask = 0; profile->send_queue_size = 5000; if ((params = switch_xml_child(cfg, "params")) != NULL) { for (param = switch_xml_child(params, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if (!var) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param missing 'name' attribute\n", profile->name); continue; } if (!val) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] param[%s] missing 'value' attribute\n", profile->name, var); continue; } if (!strncmp(var, "reconnect_interval_ms", 21)) { int interval = atoi(val); if ( interval && interval > 0 ) { profile->reconnect_interval_ms = interval; } } else if (!strncmp(var, "send_queue_size", 15)) { int interval = atoi(val); if ( interval && interval > 0 ) { profile->send_queue_size = interval; } } else if (!strncmp(var, "exchange-type", 13)) { exchange_type = switch_core_strdup(profile->pool, val); } else if (!strncmp(var, "exchange-name", 13)) { exchange = switch_core_strdup(profile->pool, val); } else if (!strncmp(var, "exchange-durable", 16)) { exchange_durable = switch_true(val); } else if (!strncmp(var, "log-levels", 10)) { profile->log_level_mask = switch_log_str2mask(val); } } /* params for loop */ } /* Handle defaults of string types */ profile->exchange = exchange ? exchange : switch_core_strdup(profile->pool, "TAP.Events"); profile->exchange_type = exchange_type ? exchange_type : switch_core_strdup(profile->pool, "topic"); profile->exchange_durable = exchange_durable; if ((connections = switch_xml_child(cfg, "connections")) != NULL) { for (connection = switch_xml_child(connections, "connection"); connection; connection = connection->next) { if ( ! profile->conn_root ) { /* Handle first root node */ if (mod_amqp_connection_create(&(profile->conn_root), connection, profile->pool) != SWITCH_STATUS_SUCCESS) { /* Handle connection create failure */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create connection\n", profile->name); continue; } profile->conn_active = profile->conn_root; } else { if (mod_amqp_connection_create(&(profile->conn_active->next), connection, profile->pool) != SWITCH_STATUS_SUCCESS) { /* Handle connection create failure */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create connection\n", profile->name); continue; } profile->conn_active = profile->conn_active->next; } } } profile->conn_active = NULL; if ( mod_amqp_connection_open(profile->conn_root, &(profile->conn_active), profile->name, profile->custom_attr) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] was unable to connect to any connection\n", profile->name); goto err; } amqp_exchange_declare(profile->conn_active->state, 1, amqp_cstring_bytes(profile->exchange), amqp_cstring_bytes(profile->exchange_type), 0, /* passive */ profile->exchange_durable, amqp_empty_table); if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Declaring exchange")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] failed to create exchange\n", profile->name); goto err; } /* Create a bounded FIFO queue for sending messages */ if (switch_queue_create(&(profile->send_queue), profile->send_queue_size, profile->pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create send queue of size %d!\n", profile->send_queue_size); goto err; } /* Start the event send thread. This will set up the initial connection */ switch_threadattr_create(&thd_attr, profile->pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); if (switch_thread_create(&profile->logging_thread, thd_attr, mod_amqp_logging_thread, profile, profile->pool)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create 'amqp event sender' thread!\n"); goto err; } if ( switch_core_hash_insert(globals.logging_hash, name, (void *) profile) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to insert new profile [%s] into mod_amqp profile hash\n", name); goto err; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] Successfully started\n", profile->name); return SWITCH_STATUS_SUCCESS; err: /* Cleanup */ mod_amqp_logging_destroy(&profile); return SWITCH_STATUS_GENERR; }