void DataReader::readList(pn_data_t* data, const qpid::amqp::Descriptor* descriptor) { size_t count = pn_data_get_list(data); bool skip = reader.onStartList(count, qpid::amqp::CharSequence(), qpid::amqp::CharSequence(), descriptor); if (!skip) { pn_data_enter(data); for (size_t i = 0; i < count && pn_data_next(data); ++i) { read(data); } pn_data_exit(data); reader.onEndList(count, descriptor); } }
encoder& operator<<(encoder& e, const start& s) { switch (s.type) { case ARRAY: pn_data_put_array(pn_cast(&e), s.is_described, pn_type_t(s.element)); break; case MAP: pn_data_put_map(pn_cast(&e)); break; case LIST: pn_data_put_list(pn_cast(&e)); break; case DESCRIBED: pn_data_put_described(pn_cast(&e)); break; default: throw encode_error(MSG("" << s.type << " is not a container type")); } pn_data_enter(pn_cast(&e)); return e; }
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; }
void DataReader::readOne(pn_data_t* data) { qpid::amqp::Descriptor descriptor(0); bool described = pn_data_is_described(data); if (described) { pn_data_enter(data); pn_data_next(data); if (pn_data_type(data) == PN_ULONG) { descriptor = qpid::amqp::Descriptor(pn_data_get_ulong(data)); } else if (pn_data_type(data) == PN_SYMBOL) { descriptor = qpid::amqp::Descriptor(convert(pn_data_get_symbol(data))); } else { QPID_LOG(notice, "Ignoring descriptor of type " << pn_data_type(data)); } pn_data_next(data); } switch (pn_data_type(data)) { case PN_NULL: reader.onNull(described ? &descriptor : 0); break; case PN_BOOL: reader.onBoolean(pn_data_get_bool(data), described ? &descriptor : 0); break; case PN_UBYTE: reader.onUByte(pn_data_get_ubyte(data), described ? &descriptor : 0); break; case PN_BYTE: reader.onByte(pn_data_get_byte(data), described ? &descriptor : 0); break; case PN_USHORT: reader.onUShort(pn_data_get_ushort(data), described ? &descriptor : 0); break; case PN_SHORT: reader.onShort(pn_data_get_short(data), described ? &descriptor : 0); break; case PN_UINT: reader.onUInt(pn_data_get_uint(data), described ? &descriptor : 0); break; case PN_INT: reader.onInt(pn_data_get_int(data), described ? &descriptor : 0); break; case PN_CHAR: pn_data_get_char(data); break; case PN_ULONG: reader.onULong(pn_data_get_ulong(data), described ? &descriptor : 0); break; case PN_LONG: reader.onLong(pn_data_get_long(data), described ? &descriptor : 0); break; case PN_TIMESTAMP: reader.onTimestamp(pn_data_get_timestamp(data), described ? &descriptor : 0); break; case PN_FLOAT: reader.onFloat(pn_data_get_float(data), described ? &descriptor : 0); break; case PN_DOUBLE: reader.onDouble(pn_data_get_double(data), described ? &descriptor : 0); break; case PN_DECIMAL32: pn_data_get_decimal32(data); break; case PN_DECIMAL64: pn_data_get_decimal64(data); break; case PN_DECIMAL128: pn_data_get_decimal128(data); break; case PN_UUID: reader.onUuid(convert(pn_data_get_uuid(data)), described ? &descriptor : 0); break; case PN_BINARY: reader.onBinary(convert(pn_data_get_binary(data)), described ? &descriptor : 0); break; case PN_STRING: reader.onString(convert(pn_data_get_string(data)), described ? &descriptor : 0); break; case PN_SYMBOL: reader.onSymbol(convert(pn_data_get_symbol(data)), described ? &descriptor : 0); break; case PN_DESCRIBED: break; case PN_ARRAY: readArray(data, described ? &descriptor : 0); break; case PN_LIST: readList(data, described ? &descriptor : 0); break; case PN_MAP: readMap(data, described ? &descriptor : 0); break; } if (described) pn_data_exit(data); }
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) { Options_t opts; Statistics_t stats; uint64_t sent = 0; uint64_t received = 0; int target_index = 0; int rc; pn_message_t *message = 0; pn_message_t *reply_message = 0; pn_messenger_t *messenger = 0; parse_options( argc, argv, &opts ); messenger = pn_messenger( opts.name ); if (opts.certificate) { rc = pn_messenger_set_certificate(messenger, opts.certificate); check( rc == 0, "Failed to set certificate" ); } if (opts.privatekey) { rc = pn_messenger_set_private_key(messenger, opts.privatekey); check( rc == 0, "Failed to set private key" ); } if (opts.password) { rc = pn_messenger_set_password(messenger, opts.password); free(opts.password); check( rc == 0, "Failed to set password" ); } if (opts.ca_db) { rc = pn_messenger_set_trusted_certificates(messenger, opts.ca_db); check( rc == 0, "Failed to set trusted CA database" ); } if (opts.outgoing_window) { pn_messenger_set_outgoing_window( messenger, opts.outgoing_window ); } pn_messenger_set_timeout( messenger, opts.timeout ); pn_messenger_start(messenger); message = pn_message(); check(message, "failed to allocate a message"); pn_message_set_reply_to(message, "~"); pn_data_t *body = pn_message_body(message); char *data = (char *)calloc(1, opts.msg_size); pn_data_put_binary(body, pn_bytes(opts.msg_size, data)); free(data); pn_atom_t id; id.type = PN_ULONG; #if 0 // TODO: how do we effectively benchmark header processing overhead??? pn_data_t *props = pn_message_properties(message); pn_data_put_map(props); pn_data_enter(props); // //pn_data_put_string(props, pn_bytes(6, "string")); //pn_data_put_string(props, pn_bytes(10, "this is awkward")); // //pn_data_put_string(props, pn_bytes(4, "long")); pn_data_put_long(props, 12345); // //pn_data_put_string(props, pn_bytes(9, "timestamp")); pn_data_put_timestamp(props, (pn_timestamp_t) 54321); pn_data_exit(props); #endif const int get_replies = opts.get_replies; if (get_replies) { // disable the timeout so that pn_messenger_recv() won't block reply_message = pn_message(); check(reply_message, "failed to allocate a message"); } statistics_start( &stats ); while (!opts.msg_count || (sent < opts.msg_count)) { // setup the message to send pn_message_set_address(message, opts.targets.addresses[target_index]); target_index = NEXT_ADDRESS(opts.targets, target_index); id.u.as_ulong = sent; pn_message_set_correlation_id( message, id ); pn_message_set_creation_time( message, msgr_now() ); pn_messenger_put(messenger, message); sent++; if (opts.send_batch && (pn_messenger_outgoing(messenger) >= (int)opts.send_batch)) { if (get_replies) { while (received < sent) { // this will also transmit any pending sent messages received += process_replies( messenger, reply_message, &stats, opts.recv_count ); } } else { LOG("Calling pn_messenger_send()\n"); rc = pn_messenger_send(messenger, -1); check((rc == 0 || rc == PN_TIMEOUT), "pn_messenger_send() failed"); } } check_messenger(messenger); } LOG("Messages received=%llu sent=%llu\n", received, sent); if (get_replies) { // wait for the last of the replies while (received < sent) { int count = process_replies( messenger, reply_message, &stats, opts.recv_count ); check( count > 0 || (opts.timeout == 0), "Error: timed out waiting for reply messages\n"); received += count; LOG("Messages received=%llu sent=%llu\n", received, sent); } } else if (pn_messenger_outgoing(messenger) > 0) { LOG("Calling pn_messenger_send()\n"); rc = pn_messenger_send(messenger, -1); check(rc == 0, "pn_messenger_send() failed"); } rc = pn_messenger_stop(messenger); check(rc == 0, "pn_messenger_stop() failed"); check_messenger(messenger); statistics_report( &stats, sent, received ); pn_messenger_free(messenger); pn_message_free(message); if (reply_message) pn_message_free( reply_message ); addresses_free( &opts.targets ); return 0; }