bool get_message_timestamp ( pn_message_t * msg, double * timestamp ) { pn_data_t * annotations = pn_message_annotations ( msg ); pn_data_rewind ( annotations ); pn_data_next ( annotations ); if ( PN_MAP == pn_data_type ( annotations ) ) { int len = pn_data_get_map ( annotations ); pn_data_enter ( annotations ); for (int i = 0; i < len; i += 2 ) { pn_data_next ( annotations ); pn_type_t type = pn_data_type ( annotations ); if ( PN_STRING == type ) { pn_bytes_t string = pn_data_get_symbol ( annotations ); if ( ! strncmp ( "timestamp", string.start, string.size ) ) { pn_data_next ( annotations ); type = pn_data_type ( annotations ); if ( type == PN_DOUBLE ) { * timestamp = pn_data_get_double ( annotations ); return true; } } } } } return false; }
static void AMQP_opened_handler(qd_router_t *router, qd_connection_t *conn, bool inbound) { qdr_connection_role_t role = 0; int cost = 1; int remote_cost = 1; bool strip_annotations_in = false; bool strip_annotations_out = false; int link_capacity = 1; const char *name = 0; uint64_t connection_id = qd_connection_connection_id(conn); pn_connection_t *pn_conn = qd_connection_pn(conn); qd_router_connection_get_config(conn, &role, &cost, &name, &strip_annotations_in, &strip_annotations_out, &link_capacity); if (role == QDR_ROLE_INTER_ROUTER) { // // Check the remote properties for an inter-router cost value. // pn_data_t *props = pn_conn ? pn_connection_remote_properties(pn_conn) : 0; if (props) { pn_data_rewind(props); pn_data_next(props); if (props && pn_data_type(props) == PN_MAP) { pn_data_enter(props); while (pn_data_next(props)) { if (pn_data_type(props) == PN_SYMBOL) { pn_bytes_t sym = pn_data_get_symbol(props); if (sym.size == strlen(QD_CONNECTION_PROPERTY_COST_KEY) && strcmp(sym.start, QD_CONNECTION_PROPERTY_COST_KEY) == 0) { pn_data_next(props); if (pn_data_type(props) == PN_INT) remote_cost = pn_data_get_int(props); break; } } } } } // // Use the larger of the local and remote costs for this connection // if (remote_cost > cost) cost = remote_cost; } qdr_connection_t *qdrc = qdr_connection_opened(router->router_core, inbound, role, cost, connection_id, name, pn_connection_remote_container(pn_conn), strip_annotations_in, strip_annotations_out, link_capacity); qd_connection_set_context(conn, qdrc); qdr_connection_set_context(qdrc, conn); }
bool qdr_terminus_has_capability(qdr_terminus_t *term, const char *capability) { pn_data_t *cap = term->capabilities; pn_data_rewind(cap); pn_data_next(cap); if (cap && pn_data_type(cap) == PN_SYMBOL) { pn_bytes_t sym = pn_data_get_symbol(cap); if (sym.size == strlen(capability) && strcmp(sym.start, capability) == 0) return true; } return false; }
qd_field_iterator_t *qdr_terminus_dnp_address(qdr_terminus_t *term) { pn_data_t *props = term->properties; if (!props) return 0; pn_data_rewind(props); if (pn_data_next(props) && pn_data_enter(props) && pn_data_next(props)) { pn_bytes_t sym = pn_data_get_symbol(props); if (sym.start && strcmp(QD_DYNAMIC_NODE_PROPERTY_ADDRESS, sym.start) == 0) { if (pn_data_next(props)) { pn_bytes_t val = pn_data_get_string(props); if (val.start && *val.start != '\0') return qd_field_iterator_binary(val.start, val.size); } } } return 0; }
void qpidBridgePublisherImpl_setMessageType (pn_message_t* message, qpidMsgType type) { /* Get the properties */ pn_data_t* properties = pn_message_properties (message); /* Ensure position is at the start */ pn_data_rewind (properties); /* Container for application properties is a map */ pn_data_put_map(properties); pn_data_enter(properties); /* Add the type */ pn_data_put_string(properties,pn_bytes(strlen(QPID_KEY_MSGTYPE),QPID_KEY_MSGTYPE)); pn_data_put_ubyte(properties,type); pn_data_exit (properties); return; }
mama_status qpidBridgeMsgCodec_pack (msgBridge bridgeMessage, mamaMsg target, pn_message_t** protonMessage) { pn_data_t* properties = NULL; pn_data_t* body = NULL; mamaPayloadType payloadType = MAMA_PAYLOAD_UNKNOWN; const void* buffer = NULL; mama_size_t bufferLen = 0; char* subject = NULL; char* destination = NULL; char* inboxName = NULL; char* replyTo = NULL; char* targetSubject = NULL; mama_status status = MAMA_STATUS_OK; qpidMsgType type = QPID_MSG_PUB_SUB; if (NULL == bridgeMessage || NULL == target) { return MAMA_STATUS_NULL_ARG; } /* Get the underlying payload type */ mamaMsg_getPayloadType (target, &payloadType); /* If this is a qpid payload, we don't need to serialize */ if (MAMA_PAYLOAD_QPID == payloadType) { /* This will extract only the underlying handle */ mamaMsgImpl_getPayloadBuffer (target, &buffer, &bufferLen); /* Don't use function's proton message - use the one just extracted */ *protonMessage = (pn_message_t*) buffer; } else { const void* buffer = NULL; mama_size_t bufferLen = 0; /* This will extract a serialized version of the payload */ mamaMsg_getByteBuffer (target, &buffer, &bufferLen); /* Use the function's proton message if this is not a qpid payload */ body = pn_message_body (*protonMessage); pn_data_put_binary (body, pn_bytes(bufferLen, (char*)buffer)); } /* Set the subject for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getSendSubject (bridgeMessage, &subject); if (MAMA_STATUS_OK != status) { return status; } pn_message_set_subject (*protonMessage, subject); /* Set the URL destination for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getDestination (bridgeMessage, &destination); if (MAMA_STATUS_OK != status) { return status; } pn_message_set_address (*protonMessage, destination); /* Get the properties from the message */ properties = pn_message_properties (*protonMessage); /* Ensure position is at the start */ pn_data_rewind (properties); /* Main container for meta data should be a list to allow expansion */ pn_data_put_list (properties); /* Enter into the list for access to its elements */ pn_data_enter (properties); /* Set the message type for the middleware according to the bridge msg */ status = qpidBridgeMamaMsgImpl_getMsgType (bridgeMessage, &type); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_ubyte (properties, type); switch (type) { /* For inbox requests, set inbox name and reply to URLs */ case QPID_MSG_INBOX_REQUEST: status = qpidBridgeMamaMsgImpl_getInboxName (bridgeMessage, &inboxName); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(inboxName), inboxName)); status = qpidBridgeMamaMsgImpl_getReplyTo (bridgeMessage, &replyTo); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(replyTo), replyTo)); break; /* For inbox responses, set the target subject (e.g. initial for XX) */ case QPID_MSG_INBOX_RESPONSE: status = qpidBridgeMamaMsgImpl_getTargetSubject (bridgeMessage, &targetSubject); if (MAMA_STATUS_OK != status) { return status; } pn_data_put_string (properties, pn_bytes (strlen(targetSubject), targetSubject)); break; /* The following message types require no further meta data */ case QPID_MSG_TERMINATE: case QPID_MSG_SUB_REQUEST: case QPID_MSG_PUB_SUB: default: break; } /* Exit out of the list previously entered */ pn_data_exit (properties); return MAMA_STATUS_OK; }
mama_status qpidBridgeMsgCodec_unpack (msgBridge bridgeMessage, mamaMsg target, pn_message_t* protonMessage) { pn_data_t* properties = NULL; pn_data_t* body = NULL; mama_status status = MAMA_STATUS_OK; qpidMsgType type = QPID_MSG_PUB_SUB; pn_bytes_t prop; pn_atom_t firstAtom; if (NULL == bridgeMessage || NULL == protonMessage) { return MAMA_STATUS_NULL_ARG; } /* grab the body */ body = pn_message_body (protonMessage); /* Ensure position is at the start */ pn_data_rewind (body); /* Skip over the initial null atom */ pn_data_next (body); /* Grab the first atom and see what it is - PN_LIST = qpid */ firstAtom = pn_data_get_atom (body); /* If this is a proton message */ if (PN_LIST == firstAtom.type) { status = mamaMsgImpl_setMsgBuffer (target, (void*) protonMessage, sizeof (pn_message_t*), MAMA_PAYLOAD_QPID); } /* If this looks like another MAMA payload type */ else if (PN_BINARY == firstAtom.type) { mamaPayloadType payloadType = MAMA_PAYLOAD_UNKNOWN; if (firstAtom.u.as_bytes.size == 0) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Binary blob of zero length found - not processing"); return MAMA_STATUS_INVALID_ARG; } /* The payload type is the first character */ payloadType = (mamaPayloadType) firstAtom.u.as_bytes.start[0]; /* Use byte buffer to populate MAMA message */ status = mamaMsgImpl_setMsgBuffer ( target, (void*) firstAtom.u.as_bytes.start, (mama_size_t) firstAtom.u.as_bytes.size, payloadType); if (MAMA_STATUS_OK != status) { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Could not set msg buffer. Cannot unpack (%s).", mamaStatus_stringForStatus (status)); return status; } } /* If this looks like something we cannot handle */ else { mama_log (MAMA_LOG_LEVEL_ERROR, "qpidBridgeMamaMsgImpl_unpack(): " "Unable to unpack data received: incompatible format %s", pn_type_name (firstAtom.type)); } /* Get the properties */ properties = pn_message_properties (protonMessage); /* Ensure position is at the start */ pn_data_rewind (properties); /* Skip over the initial null atom */ pn_data_next (properties); /* Main container should be a list to allow expansion */ pn_data_get_list (properties); pn_data_enter (properties); /* Get the message type out */ pn_data_next (properties); type = (qpidMsgType) pn_data_get_ubyte (properties); qpidBridgeMamaMsgImpl_setMsgType (bridgeMessage, type); switch (type) { case QPID_MSG_INBOX_REQUEST: /* Move onto inbox name and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setInboxName (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } /* Move onto reply to url and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setReplyTo (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } break; case QPID_MSG_INBOX_RESPONSE: /* Move onto target subject and extract / copy */ pn_data_next (properties); prop = pn_data_get_string (properties); status = qpidBridgeMamaMsgImpl_setTargetSubject (bridgeMessage, prop.start); if (MAMA_STATUS_OK != status) { return status; } break; /* The following message types require no further meta data */ case QPID_MSG_TERMINATE: case QPID_MSG_SUB_REQUEST: case QPID_MSG_PUB_SUB: default: break; } pn_data_exit (properties); return status; }
int main(int argc, char** argv) { const char *address = "localhost"; const char *msgtext = "Hello World!"; const char *container = "SendExample"; int c; pn_message_t *message = NULL; pn_data_t *body = NULL; pn_reactor_t *reactor = NULL; pn_url_t *url = NULL; pn_connection_t *conn = NULL; /* Create a handler for the connection's events. event_handler() will be * called for each event and delete_handler will be called when the * connection is released. The handler will allocate an app_data_t * instance which can be accessed when the event_handler is called. */ pn_handler_t *handler = pn_handler_new(event_handler, sizeof(app_data_t), delete_handler); /* set up the application data with defaults */ app_data_t *app_data = GET_APP_DATA(handler); memset(app_data, 0, sizeof(app_data_t)); app_data->count = 1; app_data->target = "examples"; /* Attach the pn_handshaker() handler. This handler deals with endpoint * events from the peer so we don't have to. */ { pn_handler_t *handshaker = pn_handshaker(); pn_handler_add(handler, handshaker); pn_decref(handshaker); } /* command line options */ opterr = 0; while((c = getopt(argc, argv, "i:a:c:t:nhq")) != -1) { switch(c) { case 'h': usage(); break; case 'a': address = optarg; break; case 'c': app_data->count = atoi(optarg); if (app_data->count < 1) usage(); break; case 't': app_data->target = optarg; break; case 'n': app_data->anon = 1; break; case 'i': container = optarg; break; case 'q': quiet = 1; break; default: usage(); break; } } if (optind < argc) msgtext = argv[optind]; // create a single message and pre-encode it so we only have to do that // once. All transmits will use the same pre-encoded message simply for // speed. // message = pn_message(); pn_message_set_address(message, app_data->target); body = pn_message_body(message); pn_data_clear(body); // This message's body contains a single string if (pn_data_fill(body, "S", msgtext)) { fprintf(stderr, "Error building message!\n"); exit(1); } pn_data_rewind(body); { // encode the message, expanding the encode buffer as needed // size_t len = 128; char *buf = (char *)malloc(len); int rc = 0; do { rc = pn_message_encode(message, buf, &len); if (rc == PN_OVERFLOW) { free(buf); len *= 2; buf = (char *)malloc(len); } } while (rc == PN_OVERFLOW); app_data->msg_len = len; app_data->msg_data = buf; } pn_decref(message); // message no longer needed reactor = pn_reactor(); url = pn_url_parse(address); if (url == NULL) { fprintf(stderr, "Invalid host address %s\n", address); exit(1); } conn = pn_reactor_connection_to_host(reactor, pn_url_get_host(url), pn_url_get_port(url), handler); pn_decref(url); pn_decref(handler); // the container name should be unique for each client pn_connection_set_container(conn, container); // wait up to 5 seconds for activity before returning from // pn_reactor_process() pn_reactor_set_timeout(reactor, 5000); pn_reactor_start(reactor); while (pn_reactor_process(reactor)) { /* Returns 'true' until the connection is shut down. * pn_reactor_process() will return true at least once every 5 seconds * (due to the timeout). If no timeout was configured, * pn_reactor_process() returns as soon as it finishes processing all * pending I/O and events. Once the connection has closed, * pn_reactor_process() will return false. */ } pn_decref(reactor); return 0; }