org.accidia.echo.services.impl.TenantService Maven / Gradle / Ivy
package org.accidia.echo.services.impl;
import com.google.common.base.Strings;
import com.google.inject.Inject;
import com.google.protobuf.Descriptors;
import org.accidia.echo.EchoContext;
import org.accidia.echo.dao.IProtobufDao;
import org.accidia.echo.mysql.keyvalue.MySqlKeyValueProtobufDao;
import org.accidia.echo.mysql.relational.MySqlProtobufDao;
import org.accidia.echo.redis.RedisProtobufDao;
import org.accidia.echo.services.IObjectsService;
import org.accidia.echo.services.ITenantService;
import org.accidia.echo.protos.Protos.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
public class TenantService implements ITenantService {
private static final Logger logger = LoggerFactory.getLogger(TenantService.class);
private final DataSourceService dataSourceService;
private final Map tenantNameToTenantMap = new ConcurrentHashMap<>();
private final Map tenantNameToProtobufDao = new ConcurrentHashMap<>();
private final Map tenantToObjectsServicesMap = new ConcurrentHashMap<>();
private List allTenants = new ArrayList<>();
@Inject
public TenantService(final DataSourceService dataSourceService) {
this.dataSourceService = dataSourceService;
}
/**
* Validate the given tenant name; check that the name is not empty or whitespaces,
* and that the tenant name is already registered.
*
* @param tenant the tenant name
* @throws java.lang.IllegalArgumentException if the tenant name is not valid or not registered
*/
@Override
public void validateTenant(final String tenant) throws IllegalArgumentException {
checkArgument(!Strings.isNullOrEmpty(tenant.trim()), "null/empty tenant name");
}
/**
* Given an instance of Tenant, register services for the tenant.
*
* @param tenant the tenant to register
*/
@Override
public void registerTenant(final Tenant tenant)
throws IOException, ReflectiveOperationException, Descriptors.DescriptorValidationException {
logger.debug("registerTenant(tenantMeta)");
checkArgument(tenant != null, "null tenant");
checkArgument(!Strings.isNullOrEmpty(tenant.getName()), "null/empty tenant name");
doRegisterTenant(tenant);
}
/**
* Get the protobuf type meta object associated to the given tenant
*
* @param tenant
*/
@Override
public Tenant getTenant(final String tenant) {
logger.debug("getTenant(tenant)");
validateTenant(tenant);
return checkNotNull(this.tenantNameToTenantMap.get(tenant),
"tenant is not registered: " + tenant);
}
/**
* Get the DAO instance for tenant, or return null if tenant is not registered.
*
* @param tenant the tenant name
* @return protobuf DAO for the tenant, or null if not registered
*/
@Override
public IProtobufDao getDaoForTenant(final String tenant) {
logger.debug("getDaoForTenant(tenant)");
validateTenant(tenant);
return this.tenantNameToProtobufDao.get(tenant);
}
@Override
public IObjectsService getObjectsServicesForTenant(final String tenant) {
logger.debug("getObjectsServicesForTenant(tenant)");
validateTenant(tenant);
return this.tenantToObjectsServicesMap.get(tenant);
}
@Override
public List getAllTenants() {
logger.debug("getAllTenants()");
return this.allTenants;
}
protected void doRegisterTenant(final Tenant tenant)
throws Descriptors.DescriptorValidationException, ReflectiveOperationException, IOException {
// find the datasource for tenant
final DataSource dataSource = this.dataSourceService.getDataSource(tenant.getDatasourceName());
checkArgument(dataSource != null, "invalid datasource");
this.tenantNameToTenantMap.put(tenant.getName(), tenant);
this.allTenants.add(tenant);
final IProtobufDao protobufDao;
switch (dataSource.getStorageType()) {
case MYSQL:
protobufDao = MySqlProtobufDao.newInstance(tenant, dataSource);
break;
case MYSQL_KEYVALUE:
protobufDao = MySqlKeyValueProtobufDao.newInstance(tenant, dataSource);
break;
case REDIS:
protobufDao = RedisProtobufDao.newInstance(tenant, dataSource);
break;
default:
throw new AssertionError();
}
final IObjectsService objectsServices = new ObjectsService(EchoContext.INSTANCE.getExecutorService(),
protobufDao);
this.tenantToObjectsServicesMap.put(tenant.getName(), objectsServices);
this.tenantNameToProtobufDao.put(tenant.getName(), protobufDao);
}
@Override
public boolean isRegistered(final String tenant) {
// TODO
return false;
}
}