Ejemplo n.º 1
0
static char* test_receive_from_messenger(void *context)
{
    nx_allocator_initialize(nx_allocator_default_config());

    pn_message_t *pn_msg = pn_message();
    pn_message_set_address(pn_msg, "test_addr_1");

    nx_buffer_t *buf  = nx_allocate_buffer();
    size_t       size = nx_buffer_capacity(buf);
    int result = pn_message_encode(pn_msg, (char*) nx_buffer_cursor(buf), &size);
    if (result != 0) return "Error in pn_message_encode";
    nx_buffer_insert(buf, size);

    nx_message_t *msg = nx_allocate_message();
    DEQ_INSERT_TAIL(msg->buffers, buf);
    int valid = nx_message_check(msg, NX_DEPTH_ALL);
    if (!valid) return "nx_message_check returns 'invalid'";

    nx_field_iterator_t *iter = nx_message_field_to(msg);
    if (iter == 0) return "Expected an iterator for the 'to' field";

    if (!nx_field_iterator_equal(iter, (unsigned char*) "test_addr_1"))
        return "Mismatched 'to' field contents";

    pn_message_free(pn_msg);
    nx_free_message(msg);

    nx_allocator_finalize();
    return 0;
}
Ejemplo n.º 2
0
static pn_message_t *build_request_message(pn_message_t *message,
                                           const char *command,
                                           const char *to,
                                           const char *reply_to,
                                           const char *new_fortune,
                                           unsigned int ttl)
{
    int rc;

    pn_message_set_address( message, to );
    if (reply_to) {
        LOG("setting reply-to %s\n", reply_to);
        rc = pn_message_set_reply_to( message, reply_to );
        check(rc == 0, "pn_message_set_reply_to() failed");
    }
    pn_message_set_delivery_count( message, 0 );
    if (ttl)
        pn_message_set_ttl( message, ttl * 1000 );


    pn_data_t *body = pn_message_body(message);
    pn_data_clear( body );
    rc = pn_data_fill( body, "{SSSSSS}",
                       "type", "request",
                       "command", command,
                       "value", (new_fortune) ? new_fortune : "" );
    check( rc == 0, "Failure to create request message" );
    return message;
}
Ejemplo n.º 3
0
static char* test_insufficient_check_depth(void *context)
{
    nx_allocator_initialize(nx_allocator_default_config());

    pn_message_t *pn_msg = pn_message();
    pn_message_set_address(pn_msg, "test_addr_2");

    nx_buffer_t *buf  = nx_allocate_buffer();
    size_t       size = nx_buffer_capacity(buf);
    int result = pn_message_encode(pn_msg, (char*) nx_buffer_cursor(buf), &size);
    if (result != 0) return "Error in pn_message_encode";
    nx_buffer_insert(buf, size);

    nx_message_t *msg = nx_allocate_message();
    DEQ_INSERT_TAIL(msg->buffers, buf);
    int valid = nx_message_check(msg, NX_DEPTH_DELIVERY_ANNOTATIONS);
    if (!valid) return "nx_message_check returns 'invalid'";

    nx_field_iterator_t *iter = nx_message_field_to(msg);
    if (iter) return "Expected no iterator for the 'to' field";

    nx_free_message(msg);

    nx_allocator_finalize();
    return 0;
}
Ejemplo n.º 4
0
void process_flow(ldp_connection_t *conn, pn_event_t *event) {
    fprintf(stderr, "flow event %s\n", pn_event_type_name(pn_event_type(event)));

    pn_link_t *sender = pn_event_link(event);

    pn_message_t *message = pn_message();
    pn_message_set_address(message, "amqp://foo/bar");
    pn_data_t *body = pn_message_body(message);
    char *msgtext = "hello world!";
    pn_data_put_string(body, pn_bytes(strlen(msgtext), msgtext));
    pn_buffer_t *buffer = pn_buffer(1000);
    char *encoded = pn_buffer_bytes(buffer).start;
    size_t size = pn_buffer_capacity(buffer);
    int err = pn_message_encode(message, encoded, &size);
    if (err) {
        fprintf(stderr, "trouble encoding message\n");
    } else {
        char tag[8];
        static uint64_t next_tag;
        *((uint64_t*)tag) = ++next_tag;
        pn_delivery_t *d = pn_delivery(sender, pn_dtag(tag, 8));
        pn_link_send(sender, encoded, size);
        pn_link_advance(sender);
    }
    pn_buffer_free(buffer);
    pn_message_free(message);
}
Ejemplo n.º 5
0
void amqp::Sender::send(IMessage const &message, Address const &address)
{
	pn_data_t *pnmessage_body = NULL;
	pn_message_t *pnmessage = pn_message();

	if (pnmessage == NULL) {
		throw std::exception("ERROR: Message could not be created.");
	}

	pn_message_set_address(pnmessage, address.toString().c_str());
	_addMetaToMessage(pnmessage, message);

	pnmessage_body = pn_message_body(pnmessage);
	pn_data_put_binary(pnmessage_body, pn_bytes(message.getSize(), message.getBytes()));
	pn_messenger_put(m_messenger, pnmessage);

	if (isError()) {
		_throwError();
	}

	// To avoid traffic flud and speed up the solution better to use blocking scokets in tracking mode
	if (isTraking()) {
		Log("Sending messages to %s\n", address.toString().c_str());
		m_tracker = pn_messenger_outgoing_tracker(m_messenger);
		pn_messenger_send(m_messenger, -1); // sync
	} 
	else {
		pn_messenger_send(m_messenger, 1); // async
	}

	if (isError()) {
		_throwError();
	}

	_checkTracking();

	pn_message_free(pnmessage);
}
Ejemplo n.º 6
0
int sendMessage(pn_messenger_t * messenger) {
    //char * address = (char *) "amqps://{SAS Key Name}:{SAS key}@{namespace name}.servicebus.windows.net/{event hub name}";
    char * address = (char *) "amqps://*****:*****@kelvin-flight.servicebus.windows.net/example";
    char * msgtext = (char *) "Hello from C!";

    pn_message_t * message;
    pn_data_t * body;
    message = pn_message();

    pn_message_set_address(message, address);
    pn_message_set_content_type(message, (char*) "application/octect-stream");
    pn_message_set_inferred(message, true);

    body = pn_message_body(message);
    pn_data_put_binary(body, pn_bytes(strlen(msgtext), msgtext));

    pn_messenger_put(messenger, message);
    check(messenger);
    pn_messenger_send(messenger, 1);
    check(messenger);

    pn_message_free(message);
}
Ejemplo n.º 7
0
int main(int argc, char** argv)
{
    Options_t opts;
    Statistics_t stats;
    uint64_t sent = 0;
    uint64_t received = 0;
    int forwarding_index = 0;
    int rc;

    pn_message_t *message;
    pn_messenger_t *messenger;

    parse_options( argc, argv, &opts );

    const int forward = opts.forwarding_targets.count != 0;

    message = pn_message();
    messenger = pn_messenger( opts.name );

    /* load the various command line options if they're set */
    if (opts.certificate) {
        rc = pn_messenger_set_certificate(messenger, opts.certificate);
        check_messenger(messenger);
        check( rc == 0, "Failed to set certificate" );
    }

    if (opts.privatekey) {
        rc = pn_messenger_set_private_key(messenger, opts.privatekey);
        check_messenger(messenger);
        check( rc == 0, "Failed to set private key" );
    }

    if (opts.password) {
        rc = pn_messenger_set_password(messenger, opts.password);
        check_messenger(messenger);
        check( rc == 0, "Failed to set password" );
    }

    if (opts.ca_db) {
        rc = pn_messenger_set_trusted_certificates(messenger, opts.ca_db);
        check_messenger(messenger);
        check( rc == 0, "Failed to set trusted CA database" );
    }

    if (opts.incoming_window) {
        // RAFI: seems to cause receiver to hang:
        pn_messenger_set_incoming_window( messenger, opts.incoming_window );
    }

    pn_messenger_set_timeout( messenger, opts.timeout );

    pn_messenger_start(messenger);
    check_messenger(messenger);

    int i;
    for (i = 0; i < opts.subscriptions.count; i++) {
        pn_messenger_subscribe(messenger, opts.subscriptions.addresses[i]);
        check_messenger(messenger);
        LOG("Subscribing to '%s'\n", opts.subscriptions.addresses[i]);
    }

    // hack to let test scripts know when the receivers are ready (so
    // that the senders may be started)
    if (opts.ready_text) {
        fprintf(stdout, "%s\n", opts.ready_text);
        fflush(stdout);
    }

    while (!opts.msg_count || received < opts.msg_count) {

        LOG("Calling pn_messenger_recv(%d)\n", opts.recv_count);
        rc = pn_messenger_recv(messenger, opts.recv_count);
        check_messenger(messenger);
        check(rc == 0 || (opts.timeout == 0 && rc == PN_TIMEOUT), "pn_messenger_recv() failed");

        // start the timer only after receiving the first msg
        if (received == 0) statistics_start( &stats );

        LOG("Messages on incoming queue: %d\n", pn_messenger_incoming(messenger));
        while (pn_messenger_incoming(messenger)) {
            pn_messenger_get(messenger, message);
            check_messenger(messenger);
            received++;
            // TODO: header decoding?
            // uint64_t id = pn_message_get_correlation_id( message ).u.as_ulong;
            statistics_msg_received( &stats, message );

            if (opts.reply) {
                const char *reply_addr = pn_message_get_reply_to( message );
                if (reply_addr) {
                    LOG("Replying to: %s\n", reply_addr );
                    pn_message_set_address( message, reply_addr );
                    pn_message_set_creation_time( message, msgr_now() );
                    pn_messenger_put(messenger, message);
                    sent++;
                }
            }

            if (forward) {
                const char *forward_addr = opts.forwarding_targets.addresses[forwarding_index];
                forwarding_index = NEXT_ADDRESS(opts.forwarding_targets, forwarding_index);
                LOG("Forwarding to: %s\n", forward_addr );
                pn_message_set_address( message, forward_addr );
                pn_message_set_reply_to( message, NULL );       // else points to origin sender
                pn_message_set_creation_time( message, msgr_now() );
                pn_messenger_put(messenger, message);
                sent++;
            }

        }
        LOG("Messages received=%llu sent=%llu\n", received, sent);
    }

    // this will flush any pending sends
    if (pn_messenger_outgoing(messenger) > 0) {
        LOG("Calling pn_messenger_send()\n");
        rc = pn_messenger_send(messenger, -1);
        check_messenger(messenger);
        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);
    addresses_free( &opts.subscriptions );
    addresses_free( &opts.forwarding_targets );

    return 0;
}
Ejemplo n.º 8
0
void connection_dispatch(pn_handler_t *h, pn_event_t *event, pn_event_type_t type)
{
  connection_context_t *cc = connection_context(h);
  bool replying = cc->global->opts->reply;

  switch (type) {
  case PN_LINK_REMOTE_OPEN:
    {
      pn_link_t *link = pn_event_link(event);
      if (pn_link_is_receiver(link)) {
        check(cc->recv_link == NULL, "Multiple incomming links on one connection");
        cc->recv_link = link;
        pn_connection_t *conn = pn_event_connection(event);
        pn_list_add(cc->global->active_connections, conn);
        if (cc->global->shutting_down) {
          pn_connection_close(conn);
          break;
        }
        if (replying) {
          // Set up a reply link and defer granting credit to the incoming link
          pn_connection_t *conn = pn_session_connection(pn_link_session(link));
          pn_session_t *ssn = pn_session(conn);
          pn_session_open(ssn);
          char name[100]; // prefer a multiplatform uuid generator
          sprintf(name, "reply_sender_%d", cc->connection_id);
          cc->reply_link = pn_sender(ssn, name);
          pn_link_open(cc->reply_link);
        }
        else {
          pn_flowcontroller_t *fc = pn_flowcontroller(1024);
          pn_handler_add(h, fc);
          pn_decref(fc);
        }
      }
    }
    break;
  case PN_LINK_FLOW:
    {
      if (replying) {
        pn_link_t *reply_link = pn_event_link(event);
        // pn_flowcontroller handles the non-reply case
        check(reply_link == cc->reply_link, "internal error");

        // Grant the sender as much credit as just given to us for replies
        int delta = pn_link_credit(reply_link) - pn_link_credit(cc->recv_link);
        if (delta > 0)
          pn_link_flow(cc->recv_link, delta);
      }
    }
    break;
  case PN_DELIVERY:
    {
      pn_link_t *recv_link = pn_event_link(event);
      pn_delivery_t *dlv = pn_event_delivery(event);
      if (pn_link_is_receiver(recv_link) && !pn_delivery_partial(dlv)) {
        if (cc->global->received == 0) statistics_start(cc->global->stats);

        size_t encoded_size = pn_delivery_pending(dlv);
        cc->global->encoded_data = ensure_buffer(cc->global->encoded_data, encoded_size,
                                                 &cc->global->encoded_data_size);
        check(cc->global->encoded_data, "decoding buffer realloc failure");

        ssize_t n = pn_link_recv(recv_link, cc->global->encoded_data, encoded_size);
        check(n == (ssize_t) encoded_size, "message data read fail");
        pn_message_t *msg = cc->global->message;
        int err = pn_message_decode(msg, cc->global->encoded_data, n);
        check(err == 0, "message decode error");
        cc->global->received++;
        pn_delivery_settle(dlv);
        statistics_msg_received(cc->global->stats, msg);

        if (replying) {
          const char *reply_addr = pn_message_get_reply_to(msg);
          if (reply_addr) {
            pn_link_t *rl = cc->reply_link;
            check(pn_link_credit(rl) > 0, "message received without corresponding reply credit");
            LOG("Replying to: %s\n", reply_addr );

            pn_message_set_address(msg, reply_addr);
            pn_message_set_creation_time(msg, msgr_now());

            char tag[8];
            void *ptr = &tag;
            *((uint64_t *) ptr) = cc->global->sent;
            pn_delivery_t *dlv = pn_delivery(rl, pn_dtag(tag, 8));
            size_t size = cc->global->encoded_data_size;
            int err = pn_message_encode(msg, cc->global->encoded_data, &size);
            check(err == 0, "message encoding error");
            pn_link_send(rl, cc->global->encoded_data, size);
            pn_delivery_settle(dlv);

            cc->global->sent++;
          }
        }
      }
      if (cc->global->received >= cc->global->opts->msg_count) {
        global_shutdown(cc->global);
      }
    }
    break;
  case PN_CONNECTION_UNBOUND:
    {
      pn_connection_t *conn = pn_event_connection(event);
      pn_list_remove(cc->global->active_connections, conn);
      pn_connection_release(conn);
    }
    break;
  default:
    break;
  }
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
mama_status
qpidBridgeMamaSubscription_create (subscriptionBridge* subscriber,
                                   const char*         source,
                                   const char*         symbol,
                                   mamaTransport       tport,
                                   mamaQueue           queue,
                                   mamaMsgCallbacks    callback,
                                   mamaSubscription    subscription,
                                   void*               closure)
{
    qpidSubscription*       impl        = NULL;
    qpidTransportBridge*    transport   = NULL;
    mama_status             status      = MAMA_STATUS_OK;
    pn_data_t*              data        = NULL;

    if ( NULL == subscriber || NULL == subscription || NULL == tport )
    {
        mama_log (MAMA_LOG_LEVEL_ERROR,
                "qpidBridgeMamaSubscription_create(): something NULL");
        return MAMA_STATUS_NULL_ARG;
    }

    status = mamaTransport_getBridgeTransport (tport,
                                               (transportBridge*) &transport);

    if (MAMA_STATUS_OK != status || NULL == transport)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR,
                "qpidBridgeMamaSubscription_create(): something NULL");
        return MAMA_STATUS_NULL_ARG;
    }

    /* Allocate memory for qpid subscription implementation */
    impl = (qpidSubscription*) calloc (1, sizeof (qpidSubscription));
    if (NULL == impl)
    {
        return MAMA_STATUS_NOMEM;
    }

    mamaQueue_getNativeHandle(queue, &impl->mQpidQueue);
    impl->mMamaCallback        = callback;
    impl->mMamaSubscription    = subscription;
    impl->mMamaQueue           = queue;
    impl->mTransport           = (mamaTransport)transport;
    impl->mSymbol              = symbol;
    impl->mClosure             = closure;
    impl->mIsNotMuted          = 1;
    impl->mIsTportDisconnected = 1;
    impl->mSubjectKey          = NULL;

    /* Use a standard centralized method to determine a topic key */
    qpidBridgeMamaSubscriptionImpl_generateSubjectKey (NULL,
                                                       source,
                                                       symbol,
                                                       &impl->mSubjectKey);

    /* Register the endpoint */
    endpointPool_registerWithoutIdentifier (transport->mSubEndpoints,
                                            impl->mSubjectKey,
                                            &impl->mEndpointIdentifier,
                                            impl);

    /* Notify the publisher that you have an interest in this topic */
    pn_message_clear        (transport->mMsg);

    /* Set the message meta data to reflect a subscription request */
    qpidBridgePublisherImpl_setMessageType (transport->mMsg,
                                            QPID_MSG_SUB_REQUEST);

    /* Set the outgoing address as provided by the transport configuration */
    pn_message_set_address  (transport->mMsg,
                             transport->mOutgoingAddress);

    /* Set the reply address */
    pn_message_set_reply_to (transport->mMsg,
                             transport->mReplyAddress);

    /* Get the proton message's body data for writing */
    data = pn_message_body  (transport->mMsg);

    /* Add in the subject key as the only string inside */
    pn_data_put_string      (data, pn_bytes (strlen (impl->mSubjectKey),
                                             impl->mSubjectKey));

    /* Send out the subscription registration of interest message */
    if (NULL != transport->mOutgoingAddress)
    {
        pn_messenger_put    (transport->mOutgoing, transport->mMsg);

        if (0 != PN_MESSENGER_SEND (transport->mOutgoing))
        {
            const char* qpid_error = PN_MESSENGER_ERROR (transport->mOutgoing);
            mama_log (MAMA_LOG_LEVEL_SEVERE,
                      "qpidBridgeMamaSubscription_create(): "
                      "pn_messenger_send Error:[%s]", qpid_error);
            return MAMA_STATUS_PLATFORM;
        }
    }

    mama_log (MAMA_LOG_LEVEL_FINEST,
              "qpidBridgeMamaSubscription_create(): "
              "created interest for %s.",
              impl->mSubjectKey);

    /* Mark this subscription as valid */
    impl->mIsValid = 1;

    *subscriber =  (subscriptionBridge) impl;

    return MAMA_STATUS_OK;
}
Ejemplo n.º 12
0
void sender_dispatch(pn_handler_t *h, pn_event_t *event, pn_event_type_t type)
{
  sender_context_t *sc = sender_context(h);

  switch (type) {
  case PN_CONNECTION_INIT:
    {
      pn_connection_t *conn = pn_event_connection(event);
      pn_connection_set_container(conn, pn_string_get(sc->container_id));
      pn_connection_set_hostname(conn, pn_string_get(sc->hostname));
      pn_connection_open(conn);
      pn_session_t *ssn = pn_session(conn);
      pn_session_open(ssn);
      pn_link_t *snd = pn_sender(ssn, "sender");
      const char *path = pn_url_get_path(sc->send_url);
      if (path && strlen(path)) {
        pn_terminus_set_address(pn_link_target(snd), path);
        pn_terminus_set_address(pn_link_source(snd), path);
      }
      pn_link_open(snd);
    }
    break;
  case PN_LINK_FLOW:
    {
      pn_link_t *snd = pn_event_link(event);
      while (pn_link_credit(snd) > 0 && sc->sent < sc->opts->msg_count) {
        if (sc->sent == 0)
          statistics_start(sc->stats);

        char tag[8];
        void *ptr = &tag;
        *((uint64_t *) ptr) = sc->sent;
        pn_delivery_t *dlv = pn_delivery(snd, pn_dtag(tag, 8));

        // setup the message to send
        pn_message_t *msg = sc->message;
        pn_message_set_address(msg, sc->opts->targets.addresses[0]);
        sc->id.u.as_ulong = sc->sent;
        pn_message_set_correlation_id(msg, sc->id);
        pn_message_set_creation_time(msg, msgr_now());

        size_t size = sc->encoded_data_size;
        int err = pn_message_encode(msg, sc->encoded_data, &size);
        check(err == 0, "message encoding error");
        pn_link_send(snd, sc->encoded_data, size);
        pn_delivery_settle(dlv);
        sc->sent++;
      }
      if (sc->sent == sc->opts->msg_count && !sc->opts->get_replies) {
        pn_link_close(snd);
        pn_connection_t *conn = pn_event_connection(event);
        pn_connection_close(conn);
      }
    }
    break;
  case PN_LINK_INIT:
    {
      pn_link_t *link = pn_event_link(event);
      if (pn_link_is_receiver(link)) {
        // Response messages link.  Could manage credit and deliveries in this handler but
        // a dedicated handler also works.
        pn_handler_t *replyto = replyto_handler(sc);
        pn_flowcontroller_t *fc = pn_flowcontroller(1024);
        pn_handler_add(replyto, fc);
        pn_decref(fc);
        pn_handshaker_t *handshaker = pn_handshaker();
        pn_handler_add(replyto, handshaker);
        pn_decref(handshaker);
        pn_record_t *record = pn_link_attachments(link);
        pn_record_set_handler(record, replyto);
        pn_decref(replyto);
      }
    }
    break;
  case PN_CONNECTION_LOCAL_CLOSE:
    {
      statistics_report(sc->stats, sc->sent, sc->received);
    }
    break;
  default:
    break;
  }
}
Ejemplo n.º 13
0
void message::address(const std::string &addr) {
  check(pn_message_set_address(pn_msg(), addr.c_str()));
}
Ejemplo n.º 14
0
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;
}