use of org.eclipse.hono.client.command.amqp.ProtonBasedCommand 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);
}
}
Aggregations