Search in sources :

Example 1 with DownstreamMessageProperties

use of org.eclipse.hono.client.util.DownstreamMessageProperties in project hono by eclipse.

the class DownstreamAmqpMessageFactory method newMessage.

/**
 * Creates a new AMQP 1.0 message.
 * <p>
 * This method creates a new {@code Message} and sets
 * <ul>
 * <li>its <em>to</em> property to the address consisting of the target's endpoint and tenant</li>
 * <li>its <em>creation-time</em> to the current system time,</li>
 * <li>its <em>content-type</em> to the given value,</li>
 * <li>its payload as an AMQP <em>Data</em> section</li>
 * </ul>
 *
 * In addition, this method
 * <ul>
 * <li>augments the message with the given message properties.</li>
 * <li>augments the message with missing (application) properties corresponding to the default properties
 * registered at the tenant and device level. Default properties defined at the device level take precedence
 * over properties with the same name defined at the tenant level.</li>
 * <li>optionally adds JMS vendor properties.</li>
 * <li>sets the message's <em>content-type</em> to the {@linkplain MessageHelper#CONTENT_TYPE_OCTET_STREAM fall
 * back content type}, if the payload is not {@code null} but the given content type is {@code null} and the
 * default properties do not contain a content type property.</li>
 * <li>sets the message's <em>ttl</em> header field based on the (device provided) <em>time-to-live</em> duration
 * as specified by the <a href="https://www.eclipse.org/hono/docs/api/tenant/#resource-limits-configuration-format">
 * Tenant API</a>.</li>
 * </ul>
 *
 * @param target The target address of the message. The target address is used to determine if the message
 *               represents an event or not.
 * @param contentType The content type describing the message's payload. If {@code null}, the message's
 *                    <em>content-type</em> property will either be derived from the given properties or
 *                    deviceDefaultProperties (if set there) or it will be set to the
 *                    {@linkplain MessageHelper#CONTENT_TYPE_OCTET_STREAM default content type} if the
 *                    given payload isn't {@code null}.
 * @param payload The message payload or {@code null} if the message has no payload.
 * @param tenant The information registered for the tenant that the device belongs to or {@code null}
 *               if no information about the tenant is available.
 * @param tenantLevelDefaults The default properties registered at the tenant level or {@code null}
 *                            if no default properties are registered for the tenant.
 * @param deviceLevelDefaults The device's default properties registered at the device level or {@code null}
 *                            if no default properties are registered for the device.
 * @param messageProperties Additional message properties or {@code null} if the message has no additional properties.
 * @param addJmsVendorProps {@code true} if
 *                          <a href="https://www.oasis-open.org/committees/download.php/60574/amqp-bindmap-jms-v1.0-wd09.pdf">
 *                          JMS Vendor Properties</a> should be added to the message.
 *
 * @return The newly created message.
 * @throws NullPointerException if target is {@code null}.
 */
public static Message newMessage(final ResourceIdentifier target, final String contentType, final Buffer payload, final TenantObject tenant, final Map<String, Object> tenantLevelDefaults, final Map<String, Object> deviceLevelDefaults, final Map<String, Object> messageProperties, final boolean addJmsVendorProps) {
    Objects.requireNonNull(target);
    final Message message = ProtonHelper.message();
    MessageHelper.setCreationTime(message);
    message.setAddress(target.getBasePath());
    MessageHelper.annotate(message, target);
    Optional.ofNullable(payload).map(Buffer::getBytes).map(Binary::new).map(Data::new).ifPresent(message::setBody);
    final Map<String, Object> effectiveMessageProperties = Optional.ofNullable(messageProperties).map(HashMap::new).orElseGet(HashMap::new);
    Optional.ofNullable(contentType).ifPresent(ct -> effectiveMessageProperties.put(MessageHelper.SYS_PROPERTY_CONTENT_TYPE, ct));
    final DownstreamMessageProperties props = new DownstreamMessageProperties(target.getEndpoint(), tenantLevelDefaults, deviceLevelDefaults, effectiveMessageProperties, Optional.ofNullable(tenant).map(TenantObject::getResourceLimits).orElse(null));
    addDefaults(message, props.asMap());
    // and message payload isn't null
    if (Strings.isNullOrEmpty(message.getContentType()) && message.getBody() != null) {
        message.setContentType(MessageHelper.CONTENT_TYPE_OCTET_STREAM);
    }
    if (addJmsVendorProps) {
        addJmsVendorProperties(message);
    }
    return message;
}
Also used : TenantObject(org.eclipse.hono.util.TenantObject) Message(org.apache.qpid.proton.message.Message) HashMap(java.util.HashMap) TenantObject(org.eclipse.hono.util.TenantObject) Binary(org.apache.qpid.proton.amqp.Binary) DownstreamMessageProperties(org.eclipse.hono.client.util.DownstreamMessageProperties)

Example 2 with DownstreamMessageProperties

use of org.eclipse.hono.client.util.DownstreamMessageProperties in project hono by eclipse.

the class ProtonBasedCommandResponseSender method createDownstreamMessage.

private Message createDownstreamMessage(final CommandResponse response, final TenantObject tenant, final RegistrationAssertion device, final Map<String, Object> properties) {
    final var props = new DownstreamMessageProperties(CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT, tenant.getDefaults().getMap(), device.getDefaults(), properties, tenant.getResourceLimits()).asMap();
    final Message msg = ProtonHelper.message();
    DownstreamAmqpMessageFactory.addDefaults(msg, props);
    MessageHelper.setCreationTime(msg);
    msg.setCorrelationId(response.getCorrelationId());
    MessageHelper.setPayload(msg, response.getContentType(), response.getPayload());
    MessageHelper.addStatus(msg, response.getStatus());
    msg.setAddress(AddressHelper.getTargetAddress(CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT, response.getTenantId(), response.getReplyToId(), null));
    MessageHelper.addTenantId(msg, response.getTenantId());
    MessageHelper.addDeviceId(msg, response.getDeviceId());
    if (jmsVendorPropsEnabled) {
        DownstreamAmqpMessageFactory.addJmsVendorProperties(msg);
    }
    return msg;
}
Also used : Message(org.apache.qpid.proton.message.Message) DownstreamMessageProperties(org.eclipse.hono.client.util.DownstreamMessageProperties)

Example 3 with DownstreamMessageProperties

use of org.eclipse.hono.client.util.DownstreamMessageProperties in project hono by eclipse.

the class AbstractKafkaBasedDownstreamSender method addDefaults.

/**
 * Adds default properties defined either at the device or tenant level are added to the message headers.
 *
 * @param endpointName The endpoint that the message is targeted at.
 * @param tenant The tenant that the device belongs to.
 * @param device The registration assertion for the device that the data originates from.
 * @param qos The delivery semantics to use for sending the data.
 * @param contentType The content type of the data. If {@code null}, the content type will be determined
 *            from the following sources (in that order, the first one that is present is used):
 *            <ol>
 *            <li>the <em>contentType</em> parameter</li>
 *            <li>the property with key {@value org.eclipse.hono.util.MessageHelper#SYS_PROPERTY_CONTENT_TYPE} in the
 *            <em>properties</em> parameter</li>
 *            <li>the device default</li>
 *            <li>the tenant default</li>
 *            <li>the default content type ({@value org.eclipse.hono.util.MessageHelper#CONTENT_TYPE_OCTET_STREAM}
 *            if payload is not {@code null}</li>
 *            </ol>
 * @param payload The data to send in the message or {@code null}.
 * @param properties Additional meta data that should be included in the downstream message.
 * @return The augmented properties.
 * @throws NullPointerException if endpoint name, tenant, device or qos are {@code null}.
 */
protected final Map<String, Object> addDefaults(final String endpointName, final TenantObject tenant, final RegistrationAssertion device, final QoS qos, final String contentType, final Buffer payload, final Map<String, Object> properties) {
    Objects.requireNonNull(endpointName);
    Objects.requireNonNull(tenant);
    Objects.requireNonNull(device);
    Objects.requireNonNull(qos);
    final Map<String, Object> messageProperties = Optional.ofNullable(properties).map(HashMap::new).orElseGet(HashMap::new);
    messageProperties.put(MessageHelper.APP_PROPERTY_DEVICE_ID, device.getDeviceId());
    messageProperties.put(MessageHelper.APP_PROPERTY_QOS, qos.ordinal());
    final var propsWithDefaults = new DownstreamMessageProperties(endpointName, isDefaultsEnabled ? tenant.getDefaults().getMap() : null, isDefaultsEnabled ? device.getDefaults() : null, messageProperties, tenant.getResourceLimits()).asMap();
    if (contentType != null) {
        propsWithDefaults.put(MessageHelper.SYS_PROPERTY_CONTENT_TYPE, contentType);
    } else if (payload != null) {
        propsWithDefaults.putIfAbsent(MessageHelper.SYS_PROPERTY_CONTENT_TYPE, MessageHelper.CONTENT_TYPE_OCTET_STREAM);
    }
    return propsWithDefaults;
}
Also used : HashMap(java.util.HashMap) TenantObject(org.eclipse.hono.util.TenantObject) DownstreamMessageProperties(org.eclipse.hono.client.util.DownstreamMessageProperties)

Example 4 with DownstreamMessageProperties

use of org.eclipse.hono.client.util.DownstreamMessageProperties in project hono by eclipse.

the class KafkaBasedCommandResponseSender method getHeaders.

private Map<String, Object> getHeaders(final CommandResponse response, final TenantObject tenant, final RegistrationAssertion device) {
    final var headers = new DownstreamMessageProperties(CommandConstants.NORTHBOUND_COMMAND_RESPONSE_ENDPOINT, tenant.getDefaults().getMap(), device.getDefaults(), response.getAdditionalProperties(), tenant.getResourceLimits()).asMap();
    headers.put(MessageHelper.SYS_PROPERTY_CORRELATION_ID, response.getCorrelationId());
    headers.put(MessageHelper.APP_PROPERTY_TENANT_ID, response.getTenantId());
    headers.put(MessageHelper.APP_PROPERTY_DEVICE_ID, response.getDeviceId());
    headers.put(MessageHelper.APP_PROPERTY_STATUS, response.getStatus());
    if (response.getContentType() != null) {
        headers.put(MessageHelper.SYS_PROPERTY_CONTENT_TYPE, response.getContentType());
    } else if (response.getPayload() != null) {
        headers.put(MessageHelper.SYS_PROPERTY_CONTENT_TYPE, MessageHelper.CONTENT_TYPE_OCTET_STREAM);
    }
    return headers;
}
Also used : DownstreamMessageProperties(org.eclipse.hono.client.util.DownstreamMessageProperties)

Aggregations

DownstreamMessageProperties (org.eclipse.hono.client.util.DownstreamMessageProperties)4 HashMap (java.util.HashMap)2 Message (org.apache.qpid.proton.message.Message)2 TenantObject (org.eclipse.hono.util.TenantObject)2 Binary (org.apache.qpid.proton.amqp.Binary)1