示例#1
0
static ssize_t pn_input_read_sasl_encrypt(pn_transport_t* transport, unsigned int layer, const char* bytes, size_t available)
{
  pn_buffer_t *in = transport->sasl->decoded_buffer;
  const size_t max_buffer = transport->sasl->max_encrypt_size;
  for (size_t processed = 0; processed<available;) {
    pn_bytes_t decoded = pn_bytes(0, NULL);
    size_t decode_size = (available-processed)<=max_buffer?(available-processed):max_buffer;
    ssize_t size = pni_sasl_impl_decode(transport, pn_bytes(decode_size, bytes+processed), &decoded);
    if (size<0) return size;
    if (size>0) {
      size = pn_buffer_append(in, decoded.start, decoded.size);
      if (size) return size;
    }
    processed += decode_size;
  }
  pn_bytes_t decoded = pn_buffer_bytes(in);
  size_t processed_size = 0;
  while (processed_size < decoded.size) {
    ssize_t size = pni_passthru_layer.process_input(transport, layer, decoded.start+processed_size, decoded.size-processed_size);
    if (size==0) break;
    if (size<0) return size;
    pn_buffer_trim(in, size, 0);
    processed_size += size;
  }
  return available;
}
示例#2
0
// This takes a space separated list and zero terminates it in place
// whilst adding pointers to the existing strings in a string array.
// This means that you can't free the original storage until you have
// finished with the resulting list.
void pni_split_mechs(char *mechlist, const char* included_mechs, char *mechs[], int *count)
{
  char *start = mechlist;
  char *end = start;

  while (*end) {
    if (*end == ' ') {
      if (start != end) {
        *end = '\0';
        if (pni_included_mech(included_mechs, pn_bytes(end-start, start))) {
          mechs[(*count)++] = start;
        }
      }
      end++;
      start = end;
    } else {
      end++;
    }
  }

  if (start != end) {
    if (pni_included_mech(included_mechs, pn_bytes(end-start, start))) {
      mechs[(*count)++] = start;
    }
  }
}
示例#3
0
文件: buffer.c 项目: MZDN/qpid-proton
pn_bytes_t pn_buffer_bytes(pn_buffer_t *buf)
{
  if (buf) {
    pn_buffer_defrag(buf);
    return pn_bytes(buf->size, buf->bytes);
  } else {
    return pn_bytes(0, NULL);
  }
}
示例#4
0
pn_bytes_t pn_bytes_dup(size_t size, const char *start)
{
  if (size && start)
  {
    char *dup = malloc(size);
    memmove(dup, start, size);
    return pn_bytes(size, dup);
  } else {
    return pn_bytes(0, NULL);
  }
}
示例#5
0
void sender_context_init(sender_context_t *sc, Options_t *opts, Statistics_t *stats)
{
  sc->opts = opts;
  sc->stats = stats;
  sc->sent = 0;
  sc->received = 0;
  sc->id.type = PN_ULONG;
  sc->reply_message = 0;
  // 4096 extra bytes should easily cover the message metadata
  sc->encoded_data_size = sc->opts->msg_size + 4096;
  sc->encoded_data = (char *)calloc(1, sc->encoded_data_size);
  check(sc->encoded_data, "failed to allocate encoding buffer");
  sc->container_id = pn_string("reactor-send"); // prefer uuid-like name

  sc->reply_message = (sc->opts->get_replies) ? pn_message() : 0;
  sc->message = pn_message();
  check(sc->message, "failed to allocate a message");
  pn_string_t *rpto = pn_string("amqp://");
  pn_string_addf(rpto, "%s", pn_string_get(sc->container_id));
  pn_message_set_reply_to(sc->message, pn_string_get(rpto));
  pn_free(rpto);
  pn_data_t *body = pn_message_body(sc->message);
  // borrow the encoding buffer this one time
  char *data = sc->encoded_data;
  pn_data_put_binary(body, pn_bytes(sc->opts->msg_size, data));

  check(sc->opts->targets.count > 0, "no specified address");
  sc->send_url = pn_url_parse(sc->opts->targets.addresses[0]);
  const char *host = pn_url_get_host(sc->send_url);
  const char *port = pn_url_get_port(sc->send_url);
  sc->hostname = pn_string(host);
  if (port && strlen(port))
    pn_string_addf(sc->hostname, ":%s", port);
}
示例#6
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);
}
示例#7
0
void pn_client_init(pn_sasl_t *sasl)
{
  pn_post_frame(sasl->disp, 0, "DL[sz]", SASL_INIT, sasl->mechanisms,
                sasl->send_data.size, sasl->send_data.start);
  if (sasl->send_data.start) {
    free(sasl->send_data.start);
    sasl->send_data = pn_bytes(0, NULL);
  }
}
示例#8
0
ssize_t pn_message_data(char *dst, size_t available, const char *src, size_t size)
{
  pn_bytes_t bytes = pn_bytes(available, dst);
  pn_atom_t buf[16];
  pn_atoms_t atoms = {16, buf};

  int err = pn_fill_atoms(&atoms, "DLz", 0x75, size, src);
  if (err) return err;
  err = pn_encode_atoms(&bytes, &atoms);
  if (err) return err;
  return bytes.size;
}
示例#9
0
static ssize_t pn_output_write_sasl_encrypt(pn_transport_t* transport, unsigned int layer, char* bytes, size_t available)
{
  ssize_t clear_size = pni_passthru_layer.process_output(transport, layer, bytes, available );
  if (clear_size<0) return clear_size;

  const ssize_t max_buffer = transport->sasl->max_encrypt_size;
  pn_buffer_t *out = transport->sasl->encoded_buffer;
  for (ssize_t processed = 0; processed<clear_size;) {
    pn_bytes_t encoded = pn_bytes(0, NULL);
    ssize_t encode_size = (clear_size-processed)<=max_buffer?(clear_size-processed):max_buffer;
    ssize_t size = pni_sasl_impl_encode(transport, pn_bytes(encode_size, bytes+processed), &encoded);
    if (size<0) return size;
    if (size>0) {
      size = pn_buffer_append(out, encoded.start, encoded.size);
      if (size) return size;
    }
    processed += encode_size;
  }
  ssize_t size = pn_buffer_get(out, 0, available, bytes);
  pn_buffer_trim(out, size, 0);
  return size;
}
示例#10
0
ssize_t pn_sasl_recv(pn_sasl_t *sasl, char *bytes, size_t size)
{
  if (!sasl) return PN_ARG_ERR;

  if (sasl->recv_data.start) {
    if (sasl->recv_data.size > size) return PN_OVERFLOW;
    memmove(bytes, sasl->recv_data.start, sasl->recv_data.size);
    free(sasl->recv_data.start);
    sasl->recv_data = pn_bytes(0, NULL);
    return sasl->recv_data.size;
  } else {
    return PN_EOS;
  }
}
示例#11
0
ssize_t pni_sasl_impl_decode(pn_transport_t *transport, pn_bytes_t in, pn_bytes_t *out)
{
  if ( in.size==0 ) return 0;
  sasl_conn_t *cyrus_conn = (sasl_conn_t*)transport->sasl->impl_context;
  const char *output;
  unsigned int outlen;
  int r = sasl_decode(cyrus_conn, in.start, in.size, &output, &outlen);
  if (outlen==0) return 0;
  if ( r==SASL_OK ) {
    *out = pn_bytes(outlen, output);
    return outlen;
  }
  if (transport->trace & PN_TRACE_DRV)
    pn_transport_logf(transport, "SASL decode error: %s", sasl_errdetail(cyrus_conn));
  return PN_ERR;
}
示例#12
0
void pni_process_init(pn_transport_t *transport, const char *mechanism, const pn_bytes_t *recv)
{
    pni_sasl_t *sasl = transport->sasl;

    int result = pni_wrap_server_start(sasl, mechanism, recv);
    if (result==SASL_OK) {
        // We need to filter out a supplied mech in in the inclusion list
        // as the client could have used a mech that we support, but that
        // wasn't on the list we sent.
        if (!pni_included_mech(sasl->included_mechanisms, pn_bytes(strlen(mechanism), mechanism))) {
            sasl_conn_t *cyrus_conn = (sasl_conn_t*)sasl->impl_context;
            sasl_seterror(cyrus_conn, 0, "Client mechanism not in mechanism inclusion list.");
            result = SASL_FAIL;
        }
    }
    pni_process_server_result(transport, result);
}
示例#13
0
/* Test sending/receiving a message in chunks */
static void test_message_stream(test_t *t) {
  test_proactor_t tps[] ={
    test_proactor(t, message_stream_handler),
    test_proactor(t, message_stream_handler)
  };
  pn_proactor_t *client = tps[0].proactor;
  pn_listener_t *l = test_listen(&tps[1], "");
  struct message_stream_context ctx = { 0 };
  tps[0].handler.context = &ctx;
  tps[1].handler.context = &ctx;

  /* Encode a large (not very) message to send in chunks */
  char *body = (char*)malloc(BODY);
  memset(body, 'x', BODY);
  pn_message_t *m = pn_message();
  pn_data_put_binary(pn_message_body(m), pn_bytes(BODY, body));
  free(body);
  ctx.size = message_encode(m, &ctx.send_buf);
  pn_message_free(m);

  pn_connection_t *c = pn_connection();
  pn_proactor_connect2(client, c, NULL, listener_info(l).connect);
  pn_session_t *ssn = pn_session(c);
  pn_session_open(ssn);
  pn_link_t *snd = pn_sender(ssn, "x");
  pn_link_open(snd);
  TEST_PROACTORS_RUN_UNTIL(tps, PN_LINK_FLOW);

  /* Send and receive the message in chunks */
  do {
    pn_connection_wake(c);      /* Initiate send/receive of one chunk */
    do {                        /* May be multiple receives for one send */
      TEST_PROACTORS_RUN_UNTIL(tps, PN_DELIVERY);
    } while (ctx.received < ctx.sent);
  } while (!ctx.complete);
  TEST_CHECK(t, ctx.received == ctx.size);
  TEST_CHECK(t, ctx.sent == ctx.size);
  TEST_CHECK(t, !memcmp(ctx.send_buf.start, ctx.recv_buf.start, ctx.size));

  free(ctx.send_buf.start);
  free(ctx.recv_buf.start);
  TEST_PROACTORS_DESTROY(tps);
}
示例#14
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;
}
示例#15
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);
}
示例#16
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);
}
示例#17
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;
}
示例#18
0
pn_bytes_t pn_message_get_user_id(pn_message_t *msg)
{
  return msg && msg->user_id ? pn_buffer_bytes(msg->user_id) : pn_bytes(0, NULL);
}
示例#19
0
void scalar_base::set(const binary& x, pn_type_t t) {
    atom_.type = t;
    bytes_ = x;
    atom_.u.as_bytes = pn_bytes(bytes_);
}
示例#20
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;
}
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;
}
示例#22
0
int main(int argc, char** argv)
{
    Options_t opts;
    int rc;

    pn_message_t *response_msg = pn_message();
    check( response_msg, "Failed to allocate a Message");
    pn_message_t *request_msg = pn_message();
    check( request_msg, "Failed to allocate a Message");
    pn_messenger_t *messenger = pn_messenger( 0 );
    check( messenger, "Failed to allocate a Messenger");

    parse_options( argc, argv, &opts );

    // no need to track outstanding messages
    pn_messenger_set_outgoing_window( messenger, 0 );
    pn_messenger_set_incoming_window( messenger, 0 );

    pn_messenger_set_timeout( messenger, opts.timeout );

    if (opts.gateway_addr) {
        LOG( "routing all messages via %s\n", opts.gateway_addr );
        rc = pn_messenger_route( messenger,
                                 "*", opts.gateway_addr );
        check( rc == 0, "pn_messenger_route() failed" );
    }

    pn_messenger_start(messenger);

    char *reply_to = NULL;
    if (opts.reply_to) {
        LOG("subscribing to %s for replies\n", opts.reply_to);
        pn_messenger_subscribe(messenger, opts.reply_to);
        reply_to = _strdup(opts.reply_to);
        check( reply_to, "Out of memory" );
#if 1
        // need to 'fix' the reply-to for use in the message itself:
        // no '~' is allowed in that case
        char *tilde = strstr( reply_to, "://~" );
        if (tilde) {
            tilde += 3;  // overwrite '~'
            memmove( tilde, tilde + 1, strlen( tilde + 1 ) + 1 );
        }
#endif
    }

    // Create a request message
    //
    const char *command = opts.new_fortune ? "set" : "get";
    build_request_message( request_msg,
                           opts.send_bad_msg ? "bad-command" : command,
                           opts.address, reply_to,
                           opts.new_fortune, opts.ttl );

    // set a unique identifier for this message, so remote can
    // de-duplicate when we re-transmit
    uuid_t uuid;
    uuid_generate(uuid);
    char uuid_str[37];
    uuid_unparse_upper(uuid, uuid_str);
    pn_data_put_string( pn_message_id( request_msg ),
                        pn_bytes( sizeof(uuid_str), uuid_str ));

    // set the correlation id so we can ensure the response matches
    // our request. (re-use uuid just 'cause it's easy!)
    pn_data_put_string( pn_message_correlation_id( request_msg ),
                        pn_bytes( sizeof(uuid_str), uuid_str ));

    int send_count = 0;
    bool done = false;

    // keep re-transmitting until something arrives
    do {
        LOG("sending request message...\n");
        rc = pn_messenger_put( messenger, request_msg );
        check(rc == 0, "pn_messenger_put() failed");
        send_count++;
        if (opts.retry) opts.retry--;

        LOG("waiting for response...\n");
        rc = pn_messenger_recv( messenger, -1 );
        if (rc == PN_TIMEOUT) {
            LOG( "Timed-out waiting for a response, retransmitting...\n" );
            pn_message_set_delivery_count( request_msg, send_count );
        } else {
            check(rc == 0, "pn_messenger_recv() failed\n");

            while (pn_messenger_incoming( messenger ) > 0) {
                rc = pn_messenger_get( messenger, response_msg );
                check(rc == 0, "pn_messenger_get() failed");

                LOG("response received!\n");
                // validate the correlation id
                pn_bytes_t cid = pn_data_get_string( pn_message_correlation_id( response_msg ) );
                if (cid.size == 0 || strncmp( uuid_str, cid.start, cid.size )) {
                    LOG( "Correlation Id mismatch!  Ignoring this response!\n" );
                } else {
                    process_reply( messenger, response_msg );
                    done = true;
                }
            }
        }
    } while (!done && opts.retry);

    if (!done) {
        fprintf( stderr, "Retries exhausted, no response received from server!\n" );
    }

    rc = pn_messenger_stop(messenger);
    check(rc == 0, "pn_messenger_stop() failed");

    pn_messenger_free(messenger);
    pn_message_free( response_msg );
    pn_message_free( request_msg );

    if (reply_to) free(reply_to);

    return 0;
}
示例#23
0
void qdr_terminus_add_capability(qdr_terminus_t *term, const char *capability)
{
    pn_data_put_symbol(term->capabilities, pn_bytes(strlen(capability), capability));
}
示例#24
0
void message::user(const std::string &id) {
    check(pn_message_set_user_id(pn_msg(), pn_bytes(id)));
}