use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.
the class RegistrationMessageFilterTest method testVerifyDetectsMissingAction.
/**
* Verifies that a request that does not contain a subject
* does not pass the filter.
*/
@Test
public void testVerifyDetectsMissingAction() {
// GIVEN a registration message lacking a valid subject
final Message msg = givenAMessageHavingProperties(MY_DEVICE, null);
// WHEN receiving the message via a link
final ResourceIdentifier linkTarget = getResourceIdentifier(MY_TENANT);
// THEN message validation fails
assertFalse(RegistrationMessageFilter.verify(linkTarget, msg));
}
use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.
the class VertxBasedAmqpProtocolAdapter method doUploadCommandResponseMessage.
private Future<Void> doUploadCommandResponseMessage(final AmqpContext context, final ResourceIdentifier resource, final Span currentSpan) {
final Future<CommandResponse> responseTracker = Optional.ofNullable(getCommandResponse(context.getMessage())).map(Future::succeededFuture).orElseGet(() -> {
TracingHelper.logError(currentSpan, String.format("invalid message (correlationId: %s, address: %s, status: %s)", context.getMessage().getCorrelationId(), context.getMessage().getAddress(), MessageHelper.getStatus(context.getMessage())));
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "malformed command response message"));
});
final Future<TenantObject> tenantTracker = getTenantConfiguration(resource.getTenantId(), currentSpan.context());
return CompositeFuture.all(tenantTracker, responseTracker).compose(ok -> {
final CommandResponse commandResponse = responseTracker.result();
log.trace("sending command response [device-id: {}, status: {}, correlation-id: {}, reply-to: {}]", resource.getResourceId(), commandResponse.getStatus(), commandResponse.getCorrelationId(), commandResponse.getReplyToId());
final Map<String, Object> items = new HashMap<>(3);
items.put(Fields.EVENT, "sending command response");
items.put(TracingHelper.TAG_CORRELATION_ID.getKey(), commandResponse.getCorrelationId());
items.put(MessageHelper.APP_PROPERTY_STATUS, commandResponse.getStatus());
currentSpan.log(items);
final Future<RegistrationAssertion> tokenFuture = getRegistrationAssertion(resource.getTenantId(), resource.getResourceId(), context.getAuthenticatedDevice(), currentSpan.context());
final Future<TenantObject> tenantValidationTracker = CompositeFuture.all(isAdapterEnabled(tenantTracker.result()), checkMessageLimit(tenantTracker.result(), context.getPayloadSize(), currentSpan.context())).map(success -> tenantTracker.result());
return CompositeFuture.all(tenantValidationTracker, tokenFuture).compose(success -> sendCommandResponse(tenantTracker.result(), tokenFuture.result(), commandResponse, currentSpan.context()));
}).map(delivery -> {
log.trace("forwarded command response from device [tenant: {}, device-id: {}]", resource.getTenantId(), resource.getResourceId());
metrics.reportCommand(Direction.RESPONSE, resource.getTenantId(), tenantTracker.result(), ProcessingOutcome.FORWARDED, context.getPayloadSize(), context.getTimer());
return delivery;
}).recover(t -> {
log.debug("cannot process command response from device [tenant: {}, device-id: {}]", resource.getTenantId(), resource.getResourceId(), t);
metrics.reportCommand(Direction.RESPONSE, resource.getTenantId(), tenantTracker.result(), ProcessingOutcome.from(t), context.getPayloadSize(), context.getTimer());
return Future.failedFuture(t);
});
}
use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.
the class AbstractHonoResource method getPutRequestDeviceAndAuth.
/**
* Gets a device identity for a CoAP PUT request which contains a tenant and device id in its URI.
*
* @param exchange The CoAP exchange with URI and/or peer's principal.
* @return A future indicating the outcome of the operation.
* The future will be succeeded if the device can be determined from the CoAP exchange,
* otherwise the future will be failed with a {@link ClientErrorException}.
*/
public Future<RequestDeviceAndAuth> getPutRequestDeviceAndAuth(final CoapExchange exchange) {
final List<String> pathList = exchange.getRequestOptions().getUriPath();
if (pathList.isEmpty()) {
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "missing request URI"));
} else if (pathList.size() == 1) {
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "missing tenant and device ID in URI"));
} else if (pathList.size() == 2) {
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "missing device ID in URI"));
}
try {
final String[] path = pathList.toArray(new String[pathList.size()]);
final ResourceIdentifier identifier = ResourceIdentifier.fromPath(path);
final Device device = new Device(identifier.getTenantId(), identifier.getResourceId());
final Principal peer = exchange.advanced().getRequest().getSourceContext().getPeerIdentity();
if (peer == null) {
// unauthenticated device request
return Future.succeededFuture(new RequestDeviceAndAuth(device, null, null));
} else {
return TracingSupportingHonoResource.getAuthenticatedDevice(exchange).map(authenticatedDevice -> new RequestDeviceAndAuth(device, TracingSupportingHonoResource.getAuthId(exchange), authenticatedDevice));
}
} catch (final IllegalArgumentException cause) {
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "invalid request URI"));
}
}
use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.
the class VertxBasedAmqpProtocolAdapterTest method testAdapterAcceptsAnonymousRelayReceiverOnly.
/**
* Verifies that the AMQP Adapter rejects (closes) AMQP links that contains a target address.
*/
@Test
public void testAdapterAcceptsAnonymousRelayReceiverOnly() {
// GIVEN an AMQP adapter with a configured server.
givenAnAdapter(properties);
// WHEN the adapter receives a link that contains a target address
final ResourceIdentifier targetAddress = ResourceIdentifier.from(TelemetryConstants.TELEMETRY_ENDPOINT, TEST_TENANT_ID, TEST_DEVICE);
final ProtonReceiver link = getReceiver(ProtonQoS.AT_LEAST_ONCE, getTarget(targetAddress));
adapter.handleRemoteReceiverOpen(getConnection(null), link);
// THEN the adapter closes the link.
verify(link).close();
}
use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.
the class AbstractProtocolAdapterBaseTest method testValidateAddressUsesDeviceIdentityForAddressWithoutTenantAndDevice.
/**
* Verifies that the adapter uses an authenticated device's identity when validating an
* address without a tenant ID and device ID.
*
* @param ctx The vert.x test context.
*/
@Test
public void testValidateAddressUsesDeviceIdentityForAddressWithoutTenantAndDevice(final VertxTestContext ctx) {
// WHEN an authenticated device publishes a message to an address that does not contain a tenant ID
final Device authenticatedDevice = new Device("my-tenant", "4711");
final ResourceIdentifier address = ResourceIdentifier.fromString(TelemetryConstants.TELEMETRY_ENDPOINT);
adapter.validateAddress(address, authenticatedDevice).onComplete(ctx.succeeding(r -> ctx.verify(() -> {
// THEN the validated address contains the authenticated device's tenant and device ID
assertEquals("my-tenant", r.getTenantId());
assertEquals("4711", r.getResourceId());
ctx.completeNow();
})));
}
Aggregations