use of org.eclipse.hono.client.ClientErrorException in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testUploadTelemetryMessageFailsForDisabledTenant.
/**
* Verifies that the adapter does not forward a message published by a device
* if the device belongs to a tenant for which the adapter has been disabled.
*
* @param ctx The vert.x test context.
*/
@Test
public void testUploadTelemetryMessageFailsForDisabledTenant(final TestContext ctx) {
// GIVEN an adapter
final MqttServer server = getMqttServer(false);
// which is disabled for tenant "my-tenant"
final TenantObject myTenantConfig = TenantObject.from("my-tenant", true);
myTenantConfig.addAdapterConfiguration(new JsonObject().put(TenantConstants.FIELD_ADAPTERS_TYPE, ADAPTER_TYPE).put(TenantConstants.FIELD_ENABLED, false));
when(tenantClient.get("my-tenant")).thenReturn(Future.succeededFuture(myTenantConfig));
final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server);
forceClientMocksToConnected();
final MessageSender sender = mock(MessageSender.class);
when(messagingClient.getOrCreateTelemetrySender(anyString())).thenReturn(Future.succeededFuture(sender));
// WHEN a device of "my-tenant" publishes a telemetry message
adapter.uploadTelemetryMessage(new MqttContext(mock(MqttPublishMessage.class), mock(MqttEndpoint.class)), "my-tenant", "the-device", Buffer.buffer("test")).setHandler(ctx.asyncAssertFailure(t -> {
// THEN the message has not been sent downstream
verify(sender, never()).send(any(Message.class));
// because the tenant is not enabled
ctx.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, ((ClientErrorException) t).getErrorCode());
}));
}
use of org.eclipse.hono.client.ClientErrorException in project hono by eclipse.
the class EventSenderImpl method sendMessage.
@Override
protected Future<ProtonDelivery> sendMessage(final Message message) {
Objects.requireNonNull(message);
final Future<ProtonDelivery> result = Future.future();
final String messageId = String.format("%s-%d", getClass().getSimpleName(), MESSAGE_COUNTER.getAndIncrement());
message.setMessageId(messageId);
sender.send(message, deliveryUpdated -> {
if (deliveryUpdated.remotelySettled()) {
if (Accepted.class.isInstance(deliveryUpdated.getRemoteState())) {
LOG.trace("event [message ID: {}] accepted by peer", messageId);
result.complete(deliveryUpdated);
} else if (Rejected.class.isInstance(deliveryUpdated.getRemoteState())) {
Rejected rejected = (Rejected) deliveryUpdated.getRemoteState();
if (rejected.getError() == null) {
LOG.debug("event [message ID: {}] rejected by peer", messageId);
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
} else {
LOG.debug("event [message ID: {}] rejected by peer: {}, {}", messageId, rejected.getError().getCondition(), rejected.getError().getDescription());
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, rejected.getError().getDescription()));
}
} else {
LOG.debug("event [message ID: {}] not accepted by peer: {}", messageId, deliveryUpdated.getRemoteState());
result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
}
} else {
LOG.warn("peer did not settle event, failing delivery [new remote state: {}]", deliveryUpdated.getRemoteState());
result.fail(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR));
}
});
LOG.trace("sent event [ID: {}], remaining credit: {}, queued messages: {}", messageId, sender.getCredit(), sender.getQueued());
return result;
}
use of org.eclipse.hono.client.ClientErrorException in project hono by eclipse.
the class AbstractVertxBasedHttpProtocolAdapterTest method testUploadEventFailsForRejectedOutcome.
/**
* Verifies that the adapter fails the upload of an event with a 400
* result if it is rejected by the downstream peer.
*/
@Test
public void testUploadEventFailsForRejectedOutcome() {
// GIVEN an adapter with a downstream event consumer attached
final Future<ProtonDelivery> outcome = Future.future();
givenAnEventSenderForOutcome(outcome);
HttpServer server = getHttpServer(false);
AbstractVertxBasedHttpProtocolAdapter<HttpProtocolAdapterProperties> adapter = getAdapter(server, null);
// WHEN a device publishes an event that is not accepted by the peer
final Buffer payload = Buffer.buffer("some payload");
final RoutingContext ctx = newRoutingContext(payload);
adapter.uploadEventMessage(ctx, "tenant", "device", payload, "application/text");
outcome.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "malformed message"));
// THEN the device gets a 400
verify(ctx).fail(HttpURLConnection.HTTP_BAD_REQUEST);
}
use of org.eclipse.hono.client.ClientErrorException in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapter method handleEndpointConnectionWithAuthentication.
private void handleEndpointConnectionWithAuthentication(final MqttEndpoint endpoint) {
if (endpoint.auth() == null) {
LOG.debug("connection request from device [clientId: {}] rejected: {}", endpoint.clientIdentifier(), "device did not provide credentials in CONNECT packet");
endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD);
} else {
final DeviceCredentials credentials = getCredentials(endpoint.auth());
if (credentials == null) {
LOG.debug("connection request from device [clientId: {}] rejected: {}", endpoint.clientIdentifier(), "device provided malformed credentials in CONNECT packet");
endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD);
} else {
getTenantConfiguration(credentials.getTenantId()).compose(tenantConfig -> {
if (tenantConfig.isAdapterEnabled(getTypeName())) {
LOG.debug("protocol adapter [{}] is enabled for tenant [{}]", getTypeName(), credentials.getTenantId());
return Future.succeededFuture(tenantConfig);
} else {
LOG.debug("protocol adapter [{}] is disabled for tenant [{}]", getTypeName(), credentials.getTenantId());
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN, "adapter disabled for tenant"));
}
}).compose(tenantConfig -> {
final Future<Device> result = Future.future();
getCredentialsAuthProvider().authenticate(credentials, result.completer());
return result;
}).map(authenticatedDevice -> {
LOG.debug("successfully authenticated device [tenant-id: {}, auth-id: {}, device-id: {}]", authenticatedDevice.getTenantId(), credentials.getAuthId(), authenticatedDevice.getDeviceId());
onAuthenticationSuccess(endpoint, authenticatedDevice);
return null;
}).otherwise(t -> {
LOG.debug("cannot authenticate device [tenant-id: {}, auth-id: {}]", credentials.getTenantId(), credentials.getAuthId(), t);
if (ServerErrorException.class.isInstance(t)) {
// one of the services we depend on might not be available (yet)
endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE);
} else {
// validation of credentials has failed
endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED);
}
return null;
});
}
}
}
use of org.eclipse.hono.client.ClientErrorException in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testUploadTelemetryMessageFailsForUnknownDevice.
/**
* Verifies that the adapter does not forward a message published by a device
* if the device's registration status cannot be asserted.
*
* @param ctx The vert.x test context.
*/
@Test
public void testUploadTelemetryMessageFailsForUnknownDevice(final TestContext ctx) {
// GIVEN an adapter
final MqttServer server = getMqttServer(false);
final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server);
givenATelemetrySenderForOutcome(Future.succeededFuture(mock(ProtonDelivery.class)));
// WHEN an unknown device publishes a telemetry message
when(regClient.assertRegistration(eq("unknown"), any())).thenReturn(Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND)));
final MessageSender sender = mock(MessageSender.class);
when(messagingClient.getOrCreateTelemetrySender(anyString())).thenReturn(Future.succeededFuture(sender));
adapter.uploadTelemetryMessage(new MqttContext(mock(MqttPublishMessage.class), mock(MqttEndpoint.class)), "my-tenant", "unknown", Buffer.buffer("test")).setHandler(ctx.asyncAssertFailure(t -> {
// THEN the message has not been sent downstream
verify(sender, never()).send(any(Message.class));
// because the device's registration status could not be asserted
ctx.assertEquals(HttpURLConnection.HTTP_NOT_FOUND, ((ClientErrorException) t).getErrorCode());
}));
}
Aggregations