org.eclipse.hono.util.RequestResponseApiConstants.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.hono.util.RequestResponseApiConstants.java

Source

/**
 * Copyright (c) 2017 Bosch Software Innovations GmbH.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Bosch Software Innovations GmbH - initial creation
 */
package org.eclipse.hono.util;

import io.vertx.core.json.JsonObject;
import io.vertx.proton.ProtonHelper;
import org.apache.qpid.proton.amqp.Symbol;
import org.apache.qpid.proton.amqp.messaging.AmqpValue;
import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
import org.apache.qpid.proton.amqp.messaging.MessageAnnotations;
import org.apache.qpid.proton.message.Message;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.eclipse.hono.util.MessageHelper;

/**
 * Constants & utility methods that are common to APIs that follow the request response pattern.
 */
public class RequestResponseApiConstants {

    /* message payload fields */
    public static final String FIELD_PAYLOAD = "payload";
    public static final String FIELD_ENABLED = "enabled";
    public static final String FIELD_DEVICE_ID = "device-id";
    public static final String FIELD_TENANT_ID = "tenant-id";

    /* message property names */
    public static final String APP_PROPERTY_KEY = "key";

    /**
     * Build a Proton message as a reply for an endpoint from the json payload that e.g. is received from the vert.x eventbus
     * from the implementing service.
     *
     * @param endpoint The endpoint the reply message will be built for.
     * @param payload The json payload received.
     * @return Message The built Proton message.
     */
    public static final Message getAmqpReply(final String endpoint, final JsonObject payload) {
        final String tenantId = payload.getString(FIELD_TENANT_ID);
        final String deviceId = payload.getString(FIELD_DEVICE_ID);
        final String status = payload.getString(MessageHelper.APP_PROPERTY_STATUS);
        final JsonObject correlationIdJson = payload.getJsonObject(MessageHelper.SYS_PROPERTY_CORRELATION_ID);
        final Object correlationId = MessageHelper.decodeIdFromJson(correlationIdJson);
        final boolean isApplCorrelationId = payload.getBoolean(MessageHelper.ANNOTATION_X_OPT_APP_CORRELATION_ID,
                false);
        return getAmqpReply(endpoint, status, correlationId, tenantId, deviceId, isApplCorrelationId,
                payload.getJsonObject(CredentialsConstants.FIELD_PAYLOAD));
    }

    /**
     * Build a Proton message containing the reply to a request for the provided endpoint.
     *
     * @param endpoint The endpoint the reply message will be built for.
     * @param status The status from the service that processed the message.
     * @param correlationId The UUID to correlate the reply with the originally sent message.
     * @param tenantId The tenant for which the message was processed.
     * @param deviceId The device that the message relates to.
     * @param isApplCorrelationId Flag to inidicate if the correlationId has to be available as application property
     *        {@link MessageHelper#ANNOTATION_X_OPT_APP_CORRELATION_ID}.
     * @param payload The payload of the message reply as json object.
     * @return Message The built Proton message. Maybe null. In that case, the message reply will not contain a body.
     */
    public static final Message getAmqpReply(final String endpoint, final String status, final Object correlationId,
            final String tenantId, final String deviceId, final boolean isApplCorrelationId,
            final JsonObject payload) {

        final ResourceIdentifier address = ResourceIdentifier.from(endpoint, tenantId, deviceId);
        final Message message = ProtonHelper.message();
        message.setMessageId(UUID.randomUUID().toString());
        message.setCorrelationId(correlationId);
        message.setAddress(address.toString());

        final Map<String, Object> map = new HashMap<>();
        map.put(MessageHelper.APP_PROPERTY_DEVICE_ID, deviceId);
        map.put(MessageHelper.APP_PROPERTY_TENANT_ID, tenantId);
        map.put(MessageHelper.APP_PROPERTY_STATUS, status);
        message.setApplicationProperties(new ApplicationProperties(map));

        if (isApplCorrelationId) {
            Map<Symbol, Object> annotations = new HashMap<>();
            annotations.put(Symbol.valueOf(MessageHelper.ANNOTATION_X_OPT_APP_CORRELATION_ID), true);
            message.setMessageAnnotations(new MessageAnnotations(annotations));
        }

        if (payload != null) {
            message.setContentType("application/json; charset=utf-8");
            message.setBody(new AmqpValue(payload.encode()));
        }
        return message;
    }

    /**
     * Build a Json object as a reply for internal communication via the vert.x event bus.
     * Service implementations may use this method to build their response when replying to a request that was received for processing.
     *
     * @param status The status from the service that processed the message.
     * @param tenantId The tenant for which the message was processed.
     * @param deviceId The device that the message relates to.
     * @return JsonObject The json reply object that is to be sent back via the vert.x event bus.
     */
    public static final JsonObject getServiceReplyAsJson(final int status, final String tenantId,
            final String deviceId) {
        return getServiceReplyAsJson(status, tenantId, deviceId, null);
    }

    /**
     * Build a Json object as a reply for internal communication via the vert.x event bus.
     * Services use this object to build their response when replying to a request that was received for processing.
     *
     * @param status The status from the service that processed the message.
     * @param tenantId The tenant for which the message was processed.
     * @param deviceId The device that the message relates to.
     * @param payload The payload of the message reply as json object.
     * @return JsonObject The json reply object that is to be sent back via the vert.x event bus.
     */
    public static final JsonObject getServiceReplyAsJson(final int status, final String tenantId,
            final String deviceId, final JsonObject payload) {
        final JsonObject jsonObject = new JsonObject();
        jsonObject.put(FIELD_TENANT_ID, tenantId);
        if (deviceId != null) {
            jsonObject.put(FIELD_DEVICE_ID, deviceId);
        }
        jsonObject.put(MessageHelper.APP_PROPERTY_STATUS, Integer.toString(status));
        if (payload != null) {
            jsonObject.put(FIELD_PAYLOAD, payload);
        }
        return jsonObject;
    }

    /**
     * Build a Json object as a reply for internal communication via the vert.x event bus.
     * Services use this object to build their response when replying to a request that was received for processing.
     *
     * @param operation The operation that shall be processed by the service.
     * @param tenantId The tenant for which the message was processed.
     * @param deviceId The device that the message relates to.
     * @return JsonObject The json object for the request that is to be sent via the vert.x event bus.
     */
    public static final JsonObject getServiceRequestAsJson(final String operation, final String tenantId,
            final String deviceId) {
        return getServiceRequestAsJson(operation, tenantId, deviceId, null);
    }

    /**
     * Build a Json object as a reply for internal communication via the vert.x event bus.
     * Services use this object to build their response when replying to a request that was received for processing.
     *
     * @param operation The operation that shall be processed by the service.
     * @param tenantId The tenant for which the message was processed.
     * @param deviceId The device that the message relates to. Maybe null - then no deviceId will be contained.
     * @param payload The payload from the request that is passed to the processing service.
     * @return JsonObject The json object for the request that is to be sent via the vert.x event bus.
     */
    public static final JsonObject getServiceRequestAsJson(final String operation, final String tenantId,
            final String deviceId, final JsonObject payload) {
        return getServiceRequestAsJson(operation, tenantId, deviceId, null, payload);
    }

    /**
     * Build a Json object as a reply for internal communication via the vert.x event bus.
     * Services use this object to build their response when replying to a request that was received for processing.
     *
     * @param operation The operation that shall be processed by the service.
     * @param tenantId The tenant for which the message was processed.
     * @param deviceId The device that the message relates to. Maybe null - then no deviceId will be contained.
     * @param valueForKeyProperty The value for the application property {@link #APP_PROPERTY_KEY}.
     *                            If null, the key will not be set.
     * @param payload The payload from the request that is passed to the processing service.
     * @return JsonObject The json object for the request that is to be sent via the vert.x event bus.
     */
    public static final JsonObject getServiceRequestAsJson(final String operation, final String tenantId,
            final String deviceId, final String valueForKeyProperty, final JsonObject payload) {
        final JsonObject msg = new JsonObject();
        msg.put(MessageHelper.SYS_PROPERTY_SUBJECT, operation);
        if (deviceId != null) {
            msg.put(FIELD_DEVICE_ID, deviceId);
        }
        msg.put(FIELD_TENANT_ID, tenantId);
        if (valueForKeyProperty != null) {
            msg.put(RegistrationConstants.APP_PROPERTY_KEY, valueForKeyProperty);
        }
        if (payload != null) {
            msg.put(RegistrationConstants.FIELD_PAYLOAD, payload);
        }
        return msg;
    }
}