/* * bronx_marshall.c -- Message marshalling functionality. * * Copyright (C) 2008 Groundwork Open Source * Written by Daniel Emmanuel Feinsmith * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301, USA. * * Change Log: * DEF Created on September 17, 2007, 1:00 PM */ #include "bronx.h" #include "bronx_route.h" #include "bronx_config.h" #include "bronx_log.h" /* * Globals. */ int _msg_sequence=1; /* * Functionality. */ char * marshall_properties(route_definition *route, message *msg) { filter_message(route, msg); return(marshall_properties_to_xml(msg)); } /* * marshall_properties_to_xml(message *msg) * * Marshall hash set to XML */ char* marshall_properties_to_xml(message *msg) { apr_pool_t *pool; apr_hash_index_t *hi; char *val, *temp, *key, *marshalled_properties, *packet; apr_ssize_t klen; /* * Create temp pool for this function's use */ apr_pool_create(&pool, NULL); /* * Check our type and create the XML header. */ switch(msg->type) { case MSG_TYPE_HOST_STATUS: bronx_log("{marshall_properties_to_xml} Marshalling HOST_CHECK to XML", BRONX_LOGGING_DEBUG); packet = apr_psprintf(pool, "type); apr_pool_destroy(pool); return(NULL); } /* * Here is where we create our message. * * This is done by iterating through each property, and creating * the name/value pair associated with each one. */ for (hi = apr_hash_first(pool, msg->properties); hi; hi = apr_hash_next(hi)) { apr_hash_this(hi, (void *)&key, (apr_ssize_t*)&klen, (void *)&val); temp = packet; packet = apr_psprintf(pool, "%s %s=\"%s\"", temp, (char *)key, (char *)val); } // // Finally, put the XML footer on the message. // switch(msg->type) { case MSG_TYPE_ACKNOWLEDGEMENT: packet = apr_psprintf(pool, "%s />\n", packet); break; default: packet = apr_psprintf(pool, "%s />\n", packet); break; } marshalled_properties = apr_pstrdup(msg->pool, packet); apr_pool_destroy(pool); bronx_logprintf(BRONX_LOGGING_DEBUG, "{marshall_properties_to_xml} marshalled_properties='%s'", packet); return(marshalled_properties); } apr_status_t marshall_xml_and_route_all_in_queue(route_definition *route) { apr_pool_t *pool; message *queue_msg; char *header, *body, *footer, *transaction; apr_status_t queue_rv, rv; int number_of_items_in_transaction=0; apr_hash_index_t *hi; char *val, *key; apr_ssize_t klen; int in_command=0, in_modify=0; // Create temp pool for this function's use apr_pool_create(&pool, route->pool); header = apr_psprintf(pool, "", _msg_sequence); footer = apr_psprintf(pool, ""); body = apr_pstrdup(pool, ""); do { ++number_of_items_in_transaction; apr_thread_mutex_lock(route->aggregation_queue_mutex); queue_rv = apr_queue_trypop(route->aggregation_queue, (void *)(&queue_msg)); apr_thread_mutex_unlock(route->aggregation_queue_mutex); if (queue_msg && queue_rv == APR_SUCCESS) { bronx_logprintf(BRONX_LOGGING_DEBUG, "{marshall_xml_and_route_all_in_queue} marshalling item#%d",number_of_items_in_transaction); /* * Check our type and create the XML header. */ switch(queue_msg->type) { case MSG_TYPE_HOST_STATUS: if (in_command) if (in_modify) body = apr_psprintf(pool, "%sproperties); for (hi = apr_hash_first(pool, queue_msg->properties); hi; hi = apr_hash_next(hi)) { apr_hash_this(hi, (void *)&key, (apr_ssize_t*)&klen, (void *)&val); body = apr_psprintf(pool, "%s %s=\"%s\"", body, (char *)key, (char *)val); } body = apr_psprintf(pool, "%s />", body); apr_pool_destroy(queue_msg->pool); } } while (queue_msg && queue_rv == APR_SUCCESS); if (strlen(body) != 0) { transaction = apr_psprintf(pool, "%s%s%s\n", header, body, footer); bronx_logprintf(BRONX_LOGGING_DEBUG, "{marshall_xml_and_route_all_in_queue} routing it, transaction size=%d", strlen(transaction)); rv = route_marshalled_message(route, transaction, TRUE); } else { bronx_log("{marshall_xml_and_route_all_in_queue} Length of message body is 0.", BRONX_LOGGING_DEBUG); rv = ERROR; } apr_pool_destroy(pool); bronx_logprintf(BRONX_LOGGING_DEBUG, "{marshall_xml_and_route_all_in_queue} total items=%d", number_of_items_in_transaction); return(rv); }