use of org.eclipse.hono.service.management.tenant.Tenant in project hono by eclipse.
the class ManagementStore method delete.
/**
* Delete the tenant.
*
* @param tenantId The tenant to delete.
* @param resourceVersion The version of the resource to delete.
* @param spanContext The span to contribute to.
* @return The future, tracking the outcome of the operation.
*/
public Future<UpdateResult> delete(final String tenantId, final Optional<String> resourceVersion, final SpanContext spanContext) {
final Span span = TracingHelper.buildChildSpan(this.tracer, spanContext, "delete tenant", getClass().getSimpleName()).withTag(TracingHelper.TAG_TENANT_ID, tenantId).start();
resourceVersion.ifPresent(version -> span.setTag("version", version));
final Statement statement;
if (resourceVersion.isPresent()) {
statement = this.deleteVersionedStatement;
} else {
statement = this.deleteStatement;
}
final var expanded = statement.expand(map -> {
map.put("tenant_id", tenantId);
resourceVersion.ifPresent(version -> map.put("expected_version", version));
});
log.debug("delete - statement: {}", expanded);
final var result = expanded.trace(this.tracer, span.context()).update(this.client);
return checkOptimisticLock(result, span, resourceVersion, checkSpan -> readTenantEntryById(this.client, tenantId, checkSpan.context())).onComplete(x -> span.finish());
}
use of org.eclipse.hono.service.management.tenant.Tenant in project hono by eclipse.
the class ManagementStore method update.
/**
* Create a new tenant.
* <p>
* The operation may fail with a {@link org.eclipse.hono.service.base.jdbc.store.EntityNotFoundException} if the
* specified tenant does not exist.
* <p>
* The operation may fail with a {@link org.eclipse.hono.service.base.jdbc.store.DuplicateKeyException} if a
* tenant with the ID or trust anchor already exists.
* <p>
* The operation may fail with an {@link org.eclipse.hono.service.base.jdbc.store.OptimisticLockingException} if
* an expected resource version was provided, but the current version did not match.
*
* @param tenantId The ID of the new tenant.
* @param tenant The tenant information.
* @param resourceVersion An optional resource version.
* @param spanContext The span to contribute to.
* @return A future, tracking the outcome of the operation.
*/
public Future<Versioned<Void>> update(final String tenantId, final Tenant tenant, final Optional<String> resourceVersion, final SpanContext spanContext) {
final var json = tenantToJson(tenant);
final Span span = TracingHelper.buildChildSpan(this.tracer, spanContext, "update tenant", getClass().getSimpleName()).withTag(TracingHelper.TAG_TENANT_ID, tenantId).start();
final var nextVersion = UUID.randomUUID().toString();
resourceVersion.ifPresent(version -> span.setTag("version", version));
final Statement statement = resourceVersion.isPresent() ? this.updateVersionedStatement : this.updateStatement;
return SQL.runTransactionally(this.client, this.tracer, span.context(), (connection, context) -> updateJsonField(connection, tenantId, statement, json, resourceVersion, nextVersion, span).flatMap(r -> {
if (r.getUpdated() <= 0) {
return Future.failedFuture(new EntityNotFoundException());
} else {
return Future.succeededFuture();
}
}).flatMap(x -> deleteAllTrustAnchors(connection, tenantId, span)).flatMap(r -> insertAllTrustAnchors(connection, tenantId, tenant, span))).map(new Versioned<Void>(nextVersion, null)).onComplete(x -> span.finish());
}
use of org.eclipse.hono.service.management.tenant.Tenant in project hono by eclipse.
the class DeviceAndGatewayAutoProvisionerTest method testProvisionFailsWhenEventNotificationFails.
@SuppressWarnings("unchecked")
private void testProvisionFailsWhenEventNotificationFails(final VertxTestContext ctx, final boolean isGateway, final String expectedDeviceId) throws CertificateEncodingException {
configureTenant(isGateway, null);
final JsonObject clientContext = new JsonObject().put(CredentialsConstants.FIELD_CLIENT_CERT, cert.getEncoded());
when(deviceManagementService.createDevice(eq(tenantId), any(), any(), any())).thenReturn(Future.succeededFuture(OperationResult.ok(HttpURLConnection.HTTP_CREATED, Id.of(deviceId), Optional.empty(), Optional.empty())));
when(deviceManagementService.updateDevice(eq(tenantId), eq(expectedDeviceId), any(), any(), any())).thenReturn(Future.succeededFuture(OperationResult.empty(HttpURLConnection.HTTP_NO_CONTENT)));
when(credentialsManagementService.updateCredentials(eq(tenantId), eq(expectedDeviceId), any(), any(), any())).thenReturn(Future.succeededFuture(OperationResult.empty(HttpURLConnection.HTTP_NO_CONTENT)));
// WHEN sending an auto-provisioning event fails
when(sender.sendEvent(any(TenantObject.class), any(RegistrationAssertion.class), anyString(), any(), any(Map.class), any())).thenReturn(Future.failedFuture(ServiceInvocationException.create(HttpURLConnection.HTTP_INTERNAL_ERROR, "error sending event")));
// WHEN provisioning a device/gateway from a certificate
deviceAndGatewayAutoProvisioner.provisionIfEnabled(tenantId, tenant, subjectDn, clientContext, NoopSpan.INSTANCE).onComplete(ctx.succeeding(result -> {
// VERIFY that the status code corresponds to an error.
assertThat(result.isError()).isTrue();
assertThat(result.getStatus()).isEqualTo(HttpURLConnection.HTTP_INTERNAL_ERROR);
ctx.completeNow();
}));
}
use of org.eclipse.hono.service.management.tenant.Tenant in project hono by eclipse.
the class AmqpConnectionIT method testConnectFailsForDisabledAdapter.
/**
* Verifies that the adapter rejects connection attempts from devices belonging
* to a tenant for which the AMQP adapter has been disabled.
*
* @param ctx The test context
*/
@Test
public void testConnectFailsForDisabledAdapter(final VertxTestContext ctx) {
final String tenantId = helper.getRandomTenantId();
final String deviceId = helper.getRandomDeviceId(tenantId);
final String password = "secret";
// GIVEN a tenant for which the AMQP adapter is disabled
final Tenant tenant = new Tenant();
tenant.addAdapterConfig(new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_HTTP).setEnabled(true));
tenant.addAdapterConfig(new Adapter(Constants.PROTOCOL_ADAPTER_TYPE_AMQP).setEnabled(false));
helper.registry.addDeviceForTenant(tenantId, tenant, deviceId, password).compose(ok -> connectToAdapter(IntegrationTestSupport.getUsername(deviceId, tenantId), password)).onComplete(ctx.failing(t -> {
// THEN the connection is refused
ctx.verify(() -> assertThat(((ClientErrorException) t).getErrorCode()).isEqualTo(HttpURLConnection.HTTP_FORBIDDEN));
ctx.completeNow();
}));
}
use of org.eclipse.hono.service.management.tenant.Tenant in project hono by eclipse.
the class AmqpConnectionIT method testConnectFailsForNonMatchingTrustAnchor.
/**
* Verifies that the adapter fails to authenticate a device if the device's client certificate's signature cannot be
* validated using the trust anchor that is registered for the tenant that the device belongs to.
*
* @param ctx The test context.
* @throws GeneralSecurityException if the tenant's trust anchor cannot be generated
*/
@Test
public void testConnectFailsForNonMatchingTrustAnchor(final VertxTestContext ctx) throws GeneralSecurityException {
final String tenantId = helper.getRandomTenantId();
final String deviceId = helper.getRandomDeviceId(tenantId);
final KeyPair keyPair = helper.newEcKeyPair();
final SelfSignedCertificate deviceCert = SelfSignedCertificate.create(UUID.randomUUID().toString());
// GIVEN a tenant configured with a trust anchor
helper.getCertificate(deviceCert.certificatePath()).compose(cert -> {
final Tenant tenant = Tenants.createTenantForTrustAnchor(cert.getSubjectX500Principal(), keyPair.getPublic());
return helper.registry.addDeviceForTenant(tenantId, tenant, deviceId, cert);
}).compose(ok -> {
// using the trust anchor registered for the device's tenant
return connectToAdapter(deviceCert);
}).onComplete(ctx.failing(t -> {
// THEN the connection is not established
ctx.verify(() -> assertThat(t).isInstanceOf(SaslException.class));
ctx.completeNow();
}));
}
Aggregations