Search in sources :

Example 1 with ProtonBasedCommandContext

use of org.eclipse.hono.client.command.amqp.ProtonBasedCommandContext in project hono by eclipse.

the class ProtonBasedMappingAndDelegatingCommandHandler method mapAndDelegateIncomingCommandMessage.

/**
 * Delegates an incoming command to the protocol adapter instance that the target
 * device is connected to.
 * <p>
 * Determines the target gateway (if applicable) and protocol adapter instance for an incoming command
 * and delegates the command to the resulting protocol adapter instance.
 *
 * @param tenantId The tenant that the command target must belong to.
 * @param messageDelivery The delivery of the command message.
 * @param message The command message.
 * @throws NullPointerException if any of the parameters is {@code null}.
 */
public void mapAndDelegateIncomingCommandMessage(final String tenantId, final ProtonDelivery messageDelivery, final Message message) {
    Objects.requireNonNull(tenantId);
    Objects.requireNonNull(messageDelivery);
    Objects.requireNonNull(message);
    final Timer.Sample timer = getMetrics().startTimer();
    // this is the place where a command message on the "command/${tenant}" address arrives *first*
    if (!ResourceIdentifier.isValid(message.getAddress())) {
        log.debug("command message has no valid address");
        final Rejected rejected = new Rejected();
        rejected.setError(new ErrorCondition(Constants.AMQP_BAD_REQUEST, "missing or invalid command target address"));
        messageDelivery.disposition(rejected, true);
        return;
    }
    final ResourceIdentifier targetAddress = ResourceIdentifier.fromString(message.getAddress());
    final String deviceId = targetAddress.getResourceId();
    if (!tenantId.equals(targetAddress.getTenantId())) {
        log.debug("command message address contains invalid tenant [expected: {}, found: {}]", tenantId, targetAddress.getTenantId());
        final Rejected rejected = new Rejected();
        rejected.setError(new ErrorCondition(AmqpError.UNAUTHORIZED_ACCESS, "unauthorized to send command to tenant"));
        messageDelivery.disposition(rejected, true);
        return;
    } else if (Strings.isNullOrEmpty(deviceId)) {
        log.debug("invalid command message address: {}", message.getAddress());
        final Rejected rejected = new Rejected();
        rejected.setError(new ErrorCondition(Constants.AMQP_BAD_REQUEST, "invalid command target address"));
        messageDelivery.disposition(rejected, true);
        return;
    }
    final ProtonBasedCommand command = ProtonBasedCommand.from(message);
    if (command.isValid()) {
        log.trace("received valid command message: {}", command);
    } else {
        log.debug("received invalid command message: {}", command);
    }
    final SpanContext spanContext = TracingHelper.extractSpanContext(tracer, message);
    final Span currentSpan = createSpan(tenantId, deviceId, spanContext);
    command.logToSpan(currentSpan);
    final ProtonBasedCommandContext commandContext = new ProtonBasedCommandContext(command, messageDelivery, currentSpan);
    if (command.isValid()) {
        mapAndDelegateIncomingCommand(commandContext, timer);
    } else {
        // command message is invalid
        commandContext.reject("malformed command message");
        reportInvalidCommand(commandContext, timer);
    }
}
Also used : ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) SpanContext(io.opentracing.SpanContext) Timer(io.micrometer.core.instrument.Timer) ProtonBasedCommandContext(org.eclipse.hono.client.command.amqp.ProtonBasedCommandContext) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ProtonBasedCommand(org.eclipse.hono.client.command.amqp.ProtonBasedCommand) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) Span(io.opentracing.Span)

Aggregations

Timer (io.micrometer.core.instrument.Timer)1 Span (io.opentracing.Span)1 SpanContext (io.opentracing.SpanContext)1 Rejected (org.apache.qpid.proton.amqp.messaging.Rejected)1 ErrorCondition (org.apache.qpid.proton.amqp.transport.ErrorCondition)1 ProtonBasedCommand (org.eclipse.hono.client.command.amqp.ProtonBasedCommand)1 ProtonBasedCommandContext (org.eclipse.hono.client.command.amqp.ProtonBasedCommandContext)1 ResourceIdentifier (org.eclipse.hono.util.ResourceIdentifier)1