static int noit_stomp_submit(iep_thread_driver_t *dr, const char *payload, size_t payloadlen) { struct stomp_driver *driver = (struct stomp_driver *)dr; apr_pool_t *dummy; apr_status_t rc; stomp_frame out; if(apr_pool_create(&dummy, NULL) != APR_SUCCESS) return -1; out.command = "SEND"; out.headers = apr_hash_make(dummy); if (driver->exchange) apr_hash_set(out.headers, "exchange", APR_HASH_KEY_STRING, driver->exchange); apr_hash_set(out.headers, "destination", APR_HASH_KEY_STRING, driver->destination); apr_hash_set(out.headers, "ack", APR_HASH_KEY_STRING, "auto"); out.body_length = -1; out.body = (char *)payload; rc = stomp_write(driver->connection, &out, dummy); if(rc != APR_SUCCESS) { noitL(noit_error, "STOMP send failed, disconnecting\n"); if(driver->connection) stomp_disconnect(&driver->connection); driver->connection = NULL; } else noitL(noit_debug, "STOMP send succeeded\n"); apr_pool_destroy(dummy); return (rc == APR_SUCCESS) ? 0 : -1; }
static int noit_stomp_disconnect(iep_thread_driver_t *d) { struct stomp_driver *dr = (struct stomp_driver *)d; if(dr->connection) { stomp_disconnect(&dr->connection); return 0; } return -1; }
static void afstomp_dd_disconnect(LogThrDestDriver *s) { STOMPDestDriver *self = (STOMPDestDriver *)s; stomp_disconnect(&self->conn); self->conn = NULL; }
static void noit_stomp_deallocate(iep_thread_driver_t *d) { struct stomp_driver *dr = (struct stomp_driver *)d; if(dr->connection) stomp_disconnect(&dr->connection); if(dr->pool) apr_pool_destroy(dr->pool); if(dr->exchange) free(dr->exchange); if(dr->destination) free(dr->destination); if(dr->user) free(dr->user); if(dr->pass) free(dr->pass); if(dr->hostname) free(dr->hostname); free(dr); }
static int noit_stomp_connect(iep_thread_driver_t *dr) { struct stomp_driver *driver = (struct stomp_driver *)dr; apr_status_t rc; stomp_frame frame; if(!driver->connection) { if(stomp_connect(&driver->connection, driver->hostname, driver->port, driver->pool)!= APR_SUCCESS) { noitL(noit_error, "MQ connection failed\n"); stomp_disconnect(&driver->connection); return -1; } frame.command = "CONNECT"; frame.headers = apr_hash_make(driver->pool); /* This is for RabbitMQ Support */ if(driver->user && driver->pass) { apr_hash_set(frame.headers, "login", APR_HASH_KEY_STRING, driver->user); apr_hash_set(frame.headers, "passcode", APR_HASH_KEY_STRING, driver->pass); } if(driver->exchange) apr_hash_set(frame.headers, "exchange", APR_HASH_KEY_STRING, driver->exchange); frame.body = NULL; frame.body_length = -1; rc = stomp_write(driver->connection, &frame, driver->pool); if(rc != APR_SUCCESS) { noitL(noit_error, "MQ STOMP CONNECT failed, %d\n", rc); stomp_disconnect(&driver->connection); return -1; } noitL(noit_debug, "MQ STOMP connection established.\n"); return 0; } /* 1 means already connected */ return 1; }
static int stomp_read_ack(void) { struct timeval tv; fd_set fds, readyfds; int nready, sts; FD_ZERO(&fds); FD_SET(fd, &fds); tv.tv_sec = timeout; tv.tv_usec = 0; memcpy(&readyfds, &fds, sizeof(readyfds)); nready = select(fd + 1, &readyfds, NULL, NULL, &tv); if (nready <= 0) { if (nready == 0) __pmNotifyErr(LOG_ERR, "Timed out waiting for server %s:%d - %s", hostname, port, netstrerror()); else __pmNotifyErr(LOG_ERR, "Error waiting for server %s:%d - %s", hostname, port, netstrerror()); stomp_disconnect(); return -1; } do { sts = recv(fd, buffer, sizeof(buffer), 0); if (sts < 0) { __pmNotifyErr(LOG_ERR, "Error recving from server %s:%d - %s", hostname, port, netstrerror()); stomp_disconnect(); return -1; } /* check for anything else we need to read to clear this ACK */ memset(&tv, 0, sizeof(tv)); memcpy(&readyfds, &fds, sizeof(readyfds)); } while (select(fd + 1, &readyfds, NULL, NULL, &tv) > 0); return 0; }
static int stomp_write(const char *buffer, int length) { int sts; do { sts = send(fd, buffer, length, 0); if (sts < 0) { __pmNotifyErr(LOG_ERR, "Write error to JMS server %s:%d - %s", hostname, port, netstrerror()); stomp_disconnect(); return -1; } else if (sts == 0) break; length -= sts; } while (length > 0); return 0; }
int main(int argc, char **argv) { stomp_status_code_t stat; /* * Initializes the messenger */ stomp_messenger_t *messenger = stomp_messenger_init(); if (!messenger) { fprintf(stderr, "%s\n", messenger->status.message); goto failure_without_message; } /* * Sets the endpoint address */ char *url = argv[1]; if (url == NULL) { url = "stomp://localhost:61613/queue/test.stomp.queue"; } stat = stomp_set_endpoint(messenger, url); if (stat != STOMP_SUCCESS) { fprintf(stderr, "%s\n", messenger->status.message); goto failure_without_message; } /* * Connects to the endpoint */ stat = stomp_connect(messenger, NULL, 1000); if (stat != STOMP_SUCCESS) { fprintf(stderr, "%s\n", messenger->status.message); goto failure_without_message; } /* * Creates a message to be sent */ stomp_message_t *message = stomp_message_create(&messenger->status); if (!message) { fprintf(stderr, "%s\n", messenger->status.message); goto failure_with_message; } /* * Formats the message */ char *text = "HIGH LEVEL API TEST"; stomp_message_format(message, text, strlen(text)); stomp_send_header_t send_header = {0}; send_header.transaction_id = -1; send_header.receipt = 124; // Sets an arbitrary property to the exchange stomp_exchange_add(messenger->exchange_properties, "test", "123"); stat = stomp_exchange_util_ctime(messenger->exchange_properties, &messenger->status); if (stat != STOMP_SUCCESS) { fprintf(stderr, "%s\n", messenger->status.message); goto failure_with_message; } /* * Sends the message */ stat = stomp_send(messenger, &send_header, message); if (stat != STOMP_SUCCESS) { fprintf(stderr, "%s\n", messenger->status.message); goto failure_with_message; } /* * Disconnects from the broker after receiving the receipt response */ stomp_disconnection_header_t disconn = {0}; disconn.receipt = 124; stat = stomp_disconnect(messenger, &disconn); if (stat != STOMP_SUCCESS) { fprintf(stderr, "%s\n", messenger->status.message); goto failure_with_message; } /* * Cleanup the objects */ stomp_message_destroy(&message); stomp_messenger_destroy(&messenger); return EXIT_SUCCESS; failure_with_message: stomp_message_destroy(&message); failure_without_message: stomp_messenger_destroy(&messenger); return EXIT_FAILURE; }
static void perform(void) { int rc; time_t last_report; last_report = time(NULL) / REPORT_INTERVAL; // Initialise database db_init(conf.db_server, conf.db_user, conf.db_pass, conf.db_name); log_message(""); log_message(""); log_message("trustdb started."); create_database(); while(run) { stats[ConnectAttempt]++; _log(GENERAL, "Connecting socket ..."); rc=stomp_connect("datafeeds.networkrail.co.uk", 61618); if(rc) { sprintf(zs,"Failed to connect. Error %d %s", rc, report_error(rc)); _log(CRITICAL, zs); } else { _log(GENERAL, "Connected."); holdoff = 0; { strcpy(headers, "CONNECT\n"); strcat(headers, "login:"******"\npasscode:"); strcat(headers, conf.nr_pass); strcat(headers, "\n"); if(debug) { sprintf(zs, "client-id:%s-trustdb-debug\n", conf.nr_user); strcat(headers, zs); } else { sprintf(zs, "client-id:%s-trustdb-%s\n", conf.nr_user, abbreviated_host_id()); strcat(headers, zs); } strcat(headers, "heart-beat:0,20000\n"); strcat(headers, "\n"); rc = stomp_tx(headers); } if(rc) { sprintf(zs,"Failed to transmit CONNECT message. Error %d %s", rc, report_error(rc)); _log(CRITICAL, zs); } else { _log(GENERAL, "Sent CONNECT message. Reading response."); rc = stomp_rx(headers, sizeof(headers), body, sizeof(body)); if(rc) { sprintf(zs,"Failed to receive. Error %d %s", rc, report_error(rc)); _log(CRITICAL, zs); } else { sprintf(zs, "Response: Body=\"%s\", Headers:", body); _log(GENERAL, zs); dump_headers(); { strcpy(headers, "SUBSCRIBE\n"); // Headers strcat(headers, "destination:/topic/TRAIN_MVT_ALL_TOC\n"); if(debug) { sprintf(zs, "activemq.subscriptionName:%s-trustdb-debug\n", conf.nr_user); strcat(headers, zs); } else { sprintf(zs, "activemq.subscriptionName:%s-trustdb-%s\n", conf.nr_user, abbreviated_host_id()); strcat(headers, zs); } strcat(headers, "id:1\n"); strcat(headers, "ack:client\n"); strcat(headers, "\n"); rc = stomp_tx(headers); } if(rc) { sprintf(zs,"Failed to transmit SUBSCRIBE message. Error %d %s", rc, report_error(rc)); _log(CRITICAL, zs); } else { _log(GENERAL, "Sent SUBSCRIBE message. Waiting for messages ..."); int run_receive = 1; while(run && run_receive) { time_t waited = time(NULL); if( waited / REPORT_INTERVAL != last_report) { report_stats(); last_report = waited / REPORT_INTERVAL; } rc = stomp_rx(headers, sizeof(headers), body, sizeof(body)); run_receive = (rc == 0); if(rc && run) { // Don't report if the error is due to an interrupt sprintf(zs, "Error receiving frame: %d %s", rc, report_error(rc)); _log(MAJOR, zs); } if(run_receive) { time_t now = time(NULL); waited = now - waited; if(waited > 1) { last_idle = now; if(high_load) _log(MINOR, "Ceasing task shedding."); high_load = false; } else { if(!high_load && now - last_idle > 64) { // Enter high load high_load = true; _log(MINOR, "High load detected. Shedding tasks."); } } if(debug || waited < 2) { sprintf(zs, "Message receive wait time was %ld seconds.", waited); _log(MINOR, zs); } char message_id[256]; message_id[0] = '\0'; stats[Bytes] += strlen(headers); stats[Bytes] += strlen(body); if(!strstr(headers, "MESSAGE")) { _log(MAJOR, "Frame received is not a MESSAGE:"); dump_headers(); run_receive = false; stats[NotMessage]++; } // Find message ID char * message_id_header = strstr(headers, "message-id:"); if(run_receive) { if(message_id_header) { size_t i = 0; message_id_header += 11; while(*message_id_header != '\n') message_id[i++] = *message_id_header++; message_id[i++] = '\0'; } else { _log(MAJOR, "No message ID found:"); dump_headers(); } } //sprintf(zs, "Message id = \"%s\"", message_id); //_log(GENERAL, zs); // Process the message if(run_receive) process_message(body); // Send ACK if(run_receive && message_id[0]) { strcpy(headers, "ACK\n"); strcat(headers, "subscription:1\n"); strcat(headers, "message-id:"); strcat(headers, message_id); strcat(headers, "\n\n"); rc = stomp_tx(headers); if(rc) { sprintf(zs,"Failed to transmit ACK message. Error %d %s", rc, report_error(rc)); _log(CRITICAL, zs); run_receive = false; } else { //_log(GENERAL, "Ack sent OK."); } //sprintf(zs, "%d messages, total size %ld bytes.", count, size); //_log(GENERAL, zs); } } } // while(run && run_receive) } } } } strcpy(headers, "DISCONNECT\n\n"); rc = stomp_tx(headers); if(rc) { sprintf(zs, "Failed to send DISCONNECT: Error %d %s", rc, report_error(rc)); _log(GENERAL, zs); } else _log(GENERAL, "Sent DISCONNECT."); _log(GENERAL, "Disconnecting socket ..."); rc = stomp_disconnect(); if(rc) { sprintf(zs, "Failed to disconnect: Error %d %s", rc, report_error(rc)); _log(GENERAL, zs); } else _log(GENERAL, "Disconnected."); { word i; if(holdoff < 128) holdoff += 16; else holdoff = 128; for(i = 0; i < holdoff && run; i++) sleep(1); } } // while(run) db_disconnect(); if(interrupt) { _log(CRITICAL, "Terminating due to interrupt."); } report_stats(); }
/* * Setup the connection to the stomp server, and handle initial protocol * negotiations (sending user/passcode over to the server in particular). * Stomp protocol is clear text... (we don't need no stinkin' security!). * Note: this routine is used for both the initial connection and also for * any subsequent reconnect attempts. */ void stompInit(void) { time_t thistime; static time_t lasttime; static int firsttime = 1; if (firsttime) { /* initial connection attempt */ stomp_parse(); if (!topic) topic = pmietopic; atexit(stomp_disconnect); } else { /* reconnect attempt, if not too soon */ time(&thistime); if (thistime < lasttime + 60) goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "Connecting to %s, port %d", hostname, port); if (stomp_connect(hostname, port) < 0) { __pmNotifyErr(LOG_ERR, "Could not connect to the message server"); goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "Connected; sending stomp connect message"); if (stomp_authenticate() < 0) { __pmNotifyErr(LOG_ERR, "Could not sent STOMP CONNECT frame to server"); goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "Sent; waiting for server ACK"); if (stomp_read_ack() < 0) { __pmNotifyErr(LOG_ERR, "Could not read STOMP ACK frame."); goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "ACK; sending initial PMIE topic and hello"); if (stomp_destination() < 0) { __pmNotifyErr(LOG_ERR, "Could not read TOPIC frame."); goto disconnect; } if (stomp_hello() < 0) { __pmNotifyErr(LOG_ERR, "Could not send HELLO frame."); goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "Sent; waiting for server ACK"); if (stomp_read_ack() < 0) { __pmNotifyErr(LOG_ERR, "Could not read STOMP ACK frame"); goto disconnect; } if (!firsttime) __pmNotifyErr(LOG_INFO, "Reconnected to STOMP protocol server"); else if (verbose) __pmNotifyErr(LOG_INFO, "Initial STOMP protocol setup complete"); firsttime = 0; goto finished; disconnect: stomp_disconnect(); if (firsttime) exit(1); /* otherwise, we attempt reconnect on next message firing (>1min) */ finished: lasttime = thistime; }
int main(int argc, char *argv[]) { apr_status_t rc; apr_pool_t *pool; stomp_connection *connection; setbuf(stdout, NULL); rc = apr_initialize(); rc==APR_SUCCESS || die(-2, "Could not initialize", rc); atexit(terminate); rc = apr_pool_create(&pool, NULL); rc==APR_SUCCESS || die(-2, "Could not allocate pool", rc); fprintf(stdout, "Connecting......"); rc=stomp_connect( &connection, "localhost", 61613, pool); rc==APR_SUCCESS || die(-2, "Could not connect", rc); fprintf(stdout, "OK\n"); fprintf(stdout, "Sending connect message."); { stomp_frame frame; frame.command = "CONNECT"; frame.headers = apr_hash_make(pool); apr_hash_set(frame.headers, "login", APR_HASH_KEY_STRING, "hchirino"); apr_hash_set(frame.headers, "passcode", APR_HASH_KEY_STRING, "letmein"); frame.body = NULL; frame.body_length = -1; rc = stomp_write(connection, &frame, pool); rc==APR_SUCCESS || die(-2, "Could not send frame", rc); } fprintf(stdout, "OK\n"); fprintf(stdout, "Reading Response."); { stomp_frame *frame; rc = stomp_read(connection, &frame, pool); rc==APR_SUCCESS || die(-2, "Could not read frame", rc); fprintf(stdout, "Response: %s, %s\n", frame->command, frame->body); } fprintf(stdout, "OK\n"); fprintf(stdout, "Sending Subscribe."); { stomp_frame frame; frame.command = "SUB"; frame.headers = apr_hash_make(pool); apr_hash_set(frame.headers, "destination", APR_HASH_KEY_STRING, "/queue/FOO.BAR"); frame.body_length = -1; frame.body = NULL; rc = stomp_write(connection, &frame, pool); rc==APR_SUCCESS || die(-2, "Could not send frame", rc); } fprintf(stdout, "OK\n"); fprintf(stdout, "Sending Message."); { stomp_frame frame; frame.command = "SEND"; frame.headers = apr_hash_make(pool); apr_hash_set(frame.headers, "destination", APR_HASH_KEY_STRING, "/queue/test"); frame.body_length = -1; frame.body = "This is the message"; rc = stomp_write(connection, &frame, pool); rc==APR_SUCCESS || die(-2, "Could not send frame", rc); } fprintf(stdout, "OK\n"); fprintf(stdout, "Reading Response."); { stomp_frame *frame; rc = stomp_read(connection, &frame, pool); rc==APR_SUCCESS || die(-2, "Could not read frame", rc); fprintf(stdout, "Response: %s, %s\n", frame->command, frame->body); } fprintf(stdout, "OK\n"); fprintf(stdout, "Sending Disconnect."); { stomp_frame frame; frame.command = "DISCONNECT"; frame.headers = NULL; frame.body_length = -1; frame.body = NULL; rc = stomp_write(connection, &frame, pool); rc==APR_SUCCESS || die(-2, "Could not send frame", rc); } fprintf(stdout, "OK\n"); fprintf(stdout, "Disconnecting..."); rc=stomp_disconnect(&connection); rc==APR_SUCCESS || die(-2, "Could not disconnect", rc); fprintf(stdout, "OK\n"); apr_pool_destroy(pool); return 0; }