예제 #1
0
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);
    }
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
파일: publisher.c 프로젝트: antmd/OpenMAMA
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;
}
예제 #5
0
파일: DataReader.cpp 프로젝트: ncdc/qpid
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);
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}