/*
* 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);
}