use of org.eclipse.hono.util.MessagingType in project hono by eclipse.
the class AssumeMessagingSystemCondition method evaluateExecutionCondition.
@Override
public ConditionEvaluationResult evaluateExecutionCondition(final ExtensionContext context) {
final Optional<AssumeMessagingSystem> annotation = AnnotationUtils.findAnnotation(context.getElement(), AssumeMessagingSystem.class);
if (annotation.isPresent()) {
final MessagingType assumedMessagingType = annotation.get().type();
final MessagingType messagingType = IntegrationTestSupport.getConfiguredMessagingType();
if (messagingType != assumedMessagingType) {
return ConditionEvaluationResult.disabled(String.format("Test assumes to run on %s, but current test profile is %s. Skipping test!", assumedMessagingType, messagingType));
} else {
return ConditionEvaluationResult.enabled(String.format("Test assumes to run on %s, which matches current test profile is %s. Running test!", assumedMessagingType, messagingType));
}
}
return ConditionEvaluationResult.enabled("Test makes no assumptions of messaging systems. Running test.");
}
use of org.eclipse.hono.util.MessagingType in project hono by eclipse.
the class AbstractMappingAndDelegatingCommandHandler method mapAndDelegateIncomingCommand.
/**
* 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 commandContext The context of the command to send.
* @param timer The timer indicating the amount of time used for processing the command message.
* @return A future indicating the outcome of the operation.
* @throws NullPointerException if any of the parameters are {@code null}.
*/
protected final Future<Void> mapAndDelegateIncomingCommand(final CommandContext commandContext, final Timer.Sample timer) {
Objects.requireNonNull(commandContext);
Objects.requireNonNull(timer);
final Command command = commandContext.getCommand();
// determine last used gateway device id
if (log.isTraceEnabled()) {
log.trace("determine command target gateway/adapter for [{}]", command);
}
final Future<TenantObject> tenantObjectFuture = tenantClient.get(command.getTenant(), commandContext.getTracingContext());
return tenantObjectFuture.compose(tenantObject -> {
TenantTraceSamplingHelper.applyTraceSamplingPriority(tenantObject, null, commandContext.getTracingSpan());
commandContext.put(CommandContext.KEY_TENANT_CONFIG, tenantObject);
// check whether the handler messaging type is equal to the messaging type of the tenant (if set)
final MessagingType tenantMessagingType = Optional.ofNullable(tenantObject.getProperty(TenantConstants.FIELD_EXT, JsonObject.class)).map(ext -> ext.getString(TenantConstants.FIELD_EXT_MESSAGING_TYPE)).map(MessagingType::valueOf).orElse(null);
if (tenantMessagingType != null && getMessagingType() != tenantMessagingType) {
log.info("command received via {} but tenant is configured to use {} [{}]", getMessagingType(), tenantMessagingType, commandContext.getCommand());
commandContext.getTracingSpan().log(String.format("command received via %s but tenant is configured to use %s", getMessagingType(), tenantMessagingType));
}
return commandTargetMapper.getTargetGatewayAndAdapterInstance(command.getTenant(), command.getDeviceId(), commandContext.getTracingContext());
}).recover(cause -> {
final Throwable error;
if (tenantObjectFuture.failed() && ServiceInvocationException.extractStatusCode(cause) == HttpURLConnection.HTTP_NOT_FOUND) {
error = new TenantDisabledOrNotRegisteredException(command.getTenant(), HttpURLConnection.HTTP_NOT_FOUND);
} else if (cause instanceof DeviceDisabledOrNotRegisteredException) {
error = cause;
} else if (ServiceInvocationException.extractStatusCode(cause) == HttpURLConnection.HTTP_NOT_FOUND) {
log.debug("no target adapter instance found for command with device id " + command.getDeviceId(), cause);
error = new NoConsumerException("no target adapter instance found");
} else {
log.debug("error getting target gateway and adapter instance for command with device id " + command.getDeviceId(), cause);
error = new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "error getting target gateway and adapter instance", cause);
}
if (error instanceof ClientErrorException) {
commandContext.reject(error);
} else {
commandContext.release(error);
}
reportCommandProcessingError(command, tenantObjectFuture.result(), error, timer);
return Future.failedFuture(cause);
}).compose(result -> {
final String targetAdapterInstanceId = result.getString(DeviceConnectionConstants.FIELD_ADAPTER_INSTANCE_ID);
final String targetDeviceId = result.getString(DeviceConnectionConstants.FIELD_PAYLOAD_DEVICE_ID);
final String targetGatewayId = targetDeviceId.equals(command.getDeviceId()) ? null : targetDeviceId;
if (Objects.isNull(targetGatewayId)) {
log.trace("determined target adapter instance [{}] for [{}] (command not mapped to gateway)", targetAdapterInstanceId, command);
} else {
command.setGatewayId(targetGatewayId);
log.trace("determined target gateway [{}] and adapter instance [{}] for [{}]", targetGatewayId, targetAdapterInstanceId, command);
commandContext.getTracingSpan().log("determined target gateway [" + targetGatewayId + "]");
}
return sendCommand(commandContext, targetAdapterInstanceId, tenantObjectFuture.result(), timer);
});
}
use of org.eclipse.hono.util.MessagingType in project hono by eclipse.
the class Commands method decodeRequestIdParameters.
/**
* Decodes the given request identifier.
*
* @param requestId The request id to extract the values from.
* @param deviceId The device identifier.
* @return The object containing the parameters decoded from the request identifier.
* @throws NullPointerException if any of the parameters is {@code null}.
* @throws IllegalArgumentException if the given requestId is invalid.
* @see #encodeRequestIdParameters(String, String, String, MessagingType) getRequestId() as the reverse operation.
*/
public static CommandRequestIdParameters decodeRequestIdParameters(final String requestId, final String deviceId) {
Objects.requireNonNull(requestId);
Objects.requireNonNull(deviceId);
try {
final String replyToOptionsBitFlag = requestId.substring(0, 1);
final boolean addDeviceIdToReply = Commands.isReplyToContainedDeviceIdOptionSet(replyToOptionsBitFlag);
final int lengthStringOne = Integer.parseInt(requestId.substring(1, 3), 16);
final String replyIdWithoutDevice = requestId.substring(3 + lengthStringOne);
final String correlationId = requestId.substring(3, 3 + lengthStringOne);
final String replyToId = addDeviceIdToReply ? deviceId + "/" + replyIdWithoutDevice : replyIdWithoutDevice;
final MessagingType messagingType = getMessagingTypeFromBitFlag(replyToOptionsBitFlag);
return new CommandRequestIdParameters(correlationId, replyToId, messagingType);
} catch (final IndexOutOfBoundsException e) {
throw new IllegalArgumentException("invalid requestId", e);
}
}
use of org.eclipse.hono.util.MessagingType in project hono by eclipse.
the class Commands method getOriginalReplyToIdAndMessagingType.
/**
* Gets the reply-to-id that was set in the original command message.
* <p>
* The input is the id returned by {@link #getDeviceFacingReplyToId(String, String, MessagingType)}, which is
* used in the command message forwarded to the device.
*
* @param deviceFacingReplyToId The reply-to-id as returned by {@link #getDeviceFacingReplyToId(String, String, MessagingType)}.
* @param deviceId The device id.
* @return The pair of reply-to-id and messaging type.
* @throws NullPointerException if deviceFacingReplyToId or deviceId is {@code null}.
* @throws IllegalArgumentException if the given deviceFacingReplyToId is invalid.
* @see #getDeviceFacingReplyToId(String, String, MessagingType) getDeviceFacingReplyToId() as the reverse operation.
*/
public static Pair<String, MessagingType> getOriginalReplyToIdAndMessagingType(final String deviceFacingReplyToId, final String deviceId) {
Objects.requireNonNull(deviceFacingReplyToId);
Objects.requireNonNull(deviceId);
try {
// deviceFacingReplyToId starts with deviceId/[bit flag]
final String replyToOptionsBitFlag = deviceFacingReplyToId.substring(deviceId.length() + 1, deviceId.length() + 2);
final boolean replyToContainedDeviceId = isReplyToContainedDeviceIdOptionSet(replyToOptionsBitFlag);
final MessagingType messagingType = getMessagingTypeFromBitFlag(replyToOptionsBitFlag);
final String originalReplyToId = deviceFacingReplyToId.replaceFirst(deviceId + "/" + replyToOptionsBitFlag, replyToContainedDeviceId ? deviceId + "/" : "");
return Pair.of(originalReplyToId, messagingType);
} catch (final IndexOutOfBoundsException e) {
throw new IllegalArgumentException("invalid deviceFacingReplyToId", e);
}
}
use of org.eclipse.hono.util.MessagingType in project hono by eclipse.
the class CommandResponse method fromAddressAndCorrelationId.
/**
* Creates a response for a given response message address and correlation ID.
*
* @param address The address of the response message. It has to contain a tenant segment followed by the segments
* returned by {@link Commands#getDeviceFacingReplyToId(String, String, MessagingType)}.
* @param correlationId The correlation ID of the command that this is the response for.
* @param payload The payload of the response or {@code null} if the response has no payload.
* @param contentType The contentType of the response or {@code null} if the response has no payload.
* @param status The HTTP status code indicating the outcome of the command.
* @return The response or {@code null} if correlation ID is {@code null}, the address cannot be parsed,
* the status is {@code null} or if the status code is < 200 or >= 600.
*/
public static CommandResponse fromAddressAndCorrelationId(final String address, final String correlationId, final Buffer payload, final String contentType, final Integer status) {
if (correlationId == null || !ResourceIdentifier.isValid(address) || status == null) {
LOG.debug("cannot create CommandResponse: invalid message (correlationId: {}, address: {}, status: {})", correlationId, address, status);
return null;
} else if (INVALID_STATUS_CODE.test(status)) {
LOG.debug("cannot create CommandResponse: status is invalid: {}", status);
return null;
}
final ResourceIdentifier resource = ResourceIdentifier.fromString(address);
final String tenantId = resource.getTenantId();
final String deviceId = resource.getResourceId();
if (tenantId == null || deviceId == null) {
LOG.debug("cannot create CommandResponse: invalid address, missing tenant and/or device identifier");
return null;
}
try {
// resource.getPathWithoutBase() represents the result of Commands.getDeviceFacingReplyToId()
final Pair<String, MessagingType> replyToIdMessagingTypePair = Commands.getOriginalReplyToIdAndMessagingType(resource.getPathWithoutBase(), deviceId);
return new CommandResponse(tenantId, deviceId, payload, contentType, status, correlationId, replyToIdMessagingTypePair.one(), replyToIdMessagingTypePair.two());
} catch (final IllegalArgumentException e) {
LOG.debug("error creating CommandResponse: invalid address, invalid last path component", e);
return null;
}
}
Aggregations