Example #1
0
bool
get_message_timestamp ( pn_message_t * msg, double * timestamp )
{
  pn_data_t * annotations = pn_message_annotations ( msg );
  pn_data_rewind ( annotations );
  pn_data_next   ( annotations );
  if ( PN_MAP == pn_data_type ( annotations ) )
  {
    int len = pn_data_get_map ( annotations );
    pn_data_enter ( annotations );
    for (int i = 0; i < len; i += 2 ) 
    {
      pn_data_next ( annotations );
      pn_type_t type = pn_data_type ( annotations );
      if ( PN_STRING == type ) 
      {
        pn_bytes_t string = pn_data_get_symbol ( annotations );
        if ( ! strncmp ( "timestamp", string.start, string.size ) )
        {
          pn_data_next ( annotations );
          type = pn_data_type ( annotations );
          if ( type == PN_DOUBLE )
          {
            * timestamp = pn_data_get_double ( annotations );
            return true;
          }
        }
      }
    }
  }

  return false;
}
Example #2
0
static void AMQP_opened_handler(qd_router_t *router, qd_connection_t *conn, bool inbound)
{
    qdr_connection_role_t  role = 0;
    int                    cost = 1;
    int                    remote_cost = 1;
    bool                   strip_annotations_in = false;
    bool                   strip_annotations_out = false;
    int                    link_capacity = 1;
    const char            *name = 0;
    uint64_t               connection_id = qd_connection_connection_id(conn);
    pn_connection_t       *pn_conn = qd_connection_pn(conn);

    qd_router_connection_get_config(conn, &role, &cost, &name,
                                    &strip_annotations_in, &strip_annotations_out, &link_capacity);

    if (role == QDR_ROLE_INTER_ROUTER) {
        //
        // Check the remote properties for an inter-router cost value.
        //
        pn_data_t *props = pn_conn ? pn_connection_remote_properties(pn_conn) : 0;
        if (props) {
            pn_data_rewind(props);
            pn_data_next(props);
            if (props && pn_data_type(props) == PN_MAP) {
                pn_data_enter(props);
                while (pn_data_next(props)) {
                    if (pn_data_type(props) == PN_SYMBOL) {
                        pn_bytes_t sym = pn_data_get_symbol(props);
                        if (sym.size == strlen(QD_CONNECTION_PROPERTY_COST_KEY) &&
                            strcmp(sym.start, QD_CONNECTION_PROPERTY_COST_KEY) == 0) {
                            pn_data_next(props);
                            if (pn_data_type(props) == PN_INT)
                                remote_cost = pn_data_get_int(props);
                            break;
                        }
                    }
                }
            }
        }

        //
        // Use the larger of the local and remote costs for this connection
        //
        if (remote_cost > cost)
            cost = remote_cost;
    }

    qdr_connection_t *qdrc = qdr_connection_opened(router->router_core, inbound, role, cost, connection_id, name,
                                                   pn_connection_remote_container(pn_conn),
                                                   strip_annotations_in, strip_annotations_out, link_capacity);

    qd_connection_set_context(conn, qdrc);
    qdr_connection_set_context(qdrc, conn);
}
Example #3
0
bool qdr_terminus_has_capability(qdr_terminus_t *term, const char *capability)
{
    pn_data_t *cap = term->capabilities;
    pn_data_rewind(cap);
    pn_data_next(cap);
    if (cap && pn_data_type(cap) == PN_SYMBOL) {
        pn_bytes_t sym = pn_data_get_symbol(cap);
        if (sym.size == strlen(capability) && strcmp(sym.start, capability) == 0)
            return true;
    }

    return false;
}
Example #4
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;
}
Example #5
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;
}
Example #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;
}
Example #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;
}
Example #8
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;
}