Skip to content

Commit

Permalink
[#780] Implement TenantClientFactoryImpl.
Browse files Browse the repository at this point in the history
The methods for creating TenantClient instances have been moved from
HonoConnectionImpl to TenantClientFactoryImpl.

Signed-off-by: Kai Hudalla <[email protected]>
  • Loading branch information
Kai Hudalla committed Apr 15, 2019
1 parent cf56777 commit e8722f2
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@
public interface HonoConnection extends ConnectionLifecycle,
ApplicationClientFactory,
CredentialsClientFactory,
RegistrationClientFactory,
TenantClientFactory {
RegistrationClientFactory {

/**
* Creates a new connection using the default implementation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

package org.eclipse.hono.client;

import org.eclipse.hono.cache.CacheProvider;
import org.eclipse.hono.client.impl.TenantClientFactoryImpl;

import io.vertx.core.Future;

/**
Expand All @@ -22,6 +25,30 @@
*/
public interface TenantClientFactory extends ConnectionLifecycle {

/**
* Creates a new factory for an existing connection.
*
* @param connection The connection to use.
* @return The factory.
* @throws NullPointerException if connection is {@code null}
*/
static TenantClientFactory create(final HonoConnection connection) {
return new TenantClientFactoryImpl(connection, null);
}

/**
* Creates a new factory for an existing connection.
*
* @param connection The connection to use.
* @param cacheProvider The provider to use for creating caches for tenant objects
* or {@code null} if tenant objects should not be cached.
* @return The factory.
* @throws NullPointerException if connection is {@code null}
*/
static TenantClientFactory create(final HonoConnection connection, final CacheProvider cacheProvider) {
return new TenantClientFactoryImpl(connection, cacheProvider);
}

/**
* Gets a client for interacting with Hono's <em>Tenant</em> API.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ abstract class AbstractHonoClientFactory implements ConnectionLifecycle {

/**
* @param connection The connection to use.
* @throws NullPointerException if connection is {@code null}.
*/
AbstractHonoClientFactory(final HonoConnection connection) {
this.connection = Objects.requireNonNull(connection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import org.eclipse.hono.client.ServerErrorException;
import org.eclipse.hono.client.ServiceInvocationException;
import org.eclipse.hono.client.StatusCodeMapper;
import org.eclipse.hono.client.TenantClient;
import org.eclipse.hono.config.ClientConfigProperties;
import org.eclipse.hono.connection.ConnectionFactory;
import org.eclipse.hono.util.CommandConstants;
Expand Down Expand Up @@ -940,60 +939,6 @@ protected final void removeRegistrationClient(final String tenantId) {
removeActiveRequestResponseClient(targetAddress);
}

/**
* {@inheritDoc}
*/
@Override
public Future<TenantClient> getOrCreateTenantClient() {

return getOrCreateRequestResponseClient(
TenantClientImpl.getTargetAddress(),
() -> newTenantClient()).map(c -> (TenantClient) c);
}

/**
* Creates a new instance of {@link TenantClient}.
* <p>
* Custom implementation of {@link TenantClient} can be instantiated by overriding this method.
* Custom extension of {@link HonoConnectionImpl} must invoke
* {@link #removeTenantClient()} to cleanup when finished with the client.
*
* @return a future containing an instance of {@link TenantClient}
* @see TenantClient
*/
protected Future<RequestResponseClient> newTenantClient() {

return checkConnected().compose(connected -> {

return TenantClientImpl.create(
cacheProvider,
this,
this::removeTenantClient,
this::removeTenantClient)
.map(client -> (RequestResponseClient) client);
});
}

private void removeTenantClient(final String tenantId) {
// the tenantId is not relevant for this client, so ignore it
removeTenantClient();
}

/**
*
* Removes a tenant client from the list of active clients.
* <p>
* Once a client has been removed, the next invocation
* of the corresponding <em>getOrCreateTenantClient</em>
* method will result in a new client being created
* (and added to the list of active clients).
*
*/
protected void removeTenantClient() {
final String targetAddress = TenantClientImpl.getTargetAddress();
removeActiveRequestResponseClient(targetAddress);
}

/**
* {@inheritDoc}
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright (c) 2019 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/


package org.eclipse.hono.client.impl;

import org.eclipse.hono.cache.CacheProvider;
import org.eclipse.hono.client.HonoConnection;
import org.eclipse.hono.client.TenantClient;
import org.eclipse.hono.client.TenantClientFactory;

import io.vertx.core.Future;


/**
* A factory for creating clients for Hono's Tenant service.
*
*/
public class TenantClientFactoryImpl extends AbstractHonoClientFactory implements TenantClientFactory {

private final CachingClientFactory<TenantClient> tenantClientFactory;
private final CacheProvider cacheProvider;

/**
* Creates a new factory for an existing connection.
*
* @param connection The connection to use.
* @param cacheProvider The cache provider to use for creating caches for tenant objects
* or {@code null} if tenant objects should not be cached.
* @throws NullPointerException if connection is {@code null}
*/
public TenantClientFactoryImpl(final HonoConnection connection, final CacheProvider cacheProvider) {
super(connection);
this.tenantClientFactory = new CachingClientFactory<>(c -> c.isOpen());
this.cacheProvider = cacheProvider;
}

/**
* {@inheritDoc}
*/
@Override
protected void onDisconnect() {
tenantClientFactory.clearState();
}

/**
* {@inheritDoc}
*/
@Override
public Future<TenantClient> getOrCreateTenantClient() {

return connection.executeOrRunOnContext(result -> {
tenantClientFactory.getOrCreateClient(
TenantClientImpl.getTargetAddress(),
() -> TenantClientImpl.create(
cacheProvider,
connection,
this::removeTenantClient,
this::removeTenantClient),
result);
});
}

private void removeTenantClient(final String tenantId) {
// the tenantId is not relevant for this client, so ignore it
tenantClientFactory.removeClient(TenantClientImpl.getTargetAddress());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -267,14 +267,9 @@ protected void customizeTenantClientFactoryConfig(final RequestResponseClientCon
@Scope("prototype")
public TenantClientFactory tenantClientFactory() {

final HonoConnectionImpl result = new HonoConnectionImpl(vertx(), tenantServiceClientConfig());

final CacheProvider cacheProvider = tenantCacheProvider();
if (cacheProvider != null) {
result.setCacheProvider(cacheProvider);
}

return result;
return TenantClientFactory.create(
HonoConnection.newConnection(vertx(), tenantServiceClientConfig()),
tenantCacheProvider());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private static ClientConfigProperties getClientConfig(final String username, fin
*/
protected static TenantClientFactory prepareTenantClientFactory(final Vertx vertx, final String username, final String password) {

return HonoConnection.newConnection(vertx, getClientConfig(username, password));
return TenantClientFactory.create(HonoConnection.newConnection(vertx, getClientConfig(username, password)));
}

/**
Expand Down

0 comments on commit e8722f2

Please sign in to comment.