use of org.apache.phoenix.exception.PhoenixIOException in project phoenix by apache.
the class ConnectionQueryServicesImpl method init.
@Override
public void init(final String url, final Properties props) throws SQLException {
try {
PhoenixContextExecutor.call(new Callable<Void>() {
@Override
public Void call() throws Exception {
if (initialized) {
if (initializationException != null) {
// Throw previous initialization exception, as we won't resuse this instance
throw initializationException;
}
return null;
}
synchronized (ConnectionQueryServicesImpl.this) {
if (initialized) {
if (initializationException != null) {
// Throw previous initialization exception, as we won't resuse this instance
throw initializationException;
}
return null;
}
checkClosed();
boolean hConnectionEstablished = false;
boolean success = false;
try {
GLOBAL_QUERY_SERVICES_COUNTER.increment();
logger.info("An instance of ConnectionQueryServices was created.");
openConnection();
hConnectionEstablished = true;
boolean isDoNotUpgradePropSet = UpgradeUtil.isNoUpgradeSet(props);
try (HBaseAdmin admin = getAdmin()) {
boolean mappedSystemCatalogExists = admin.tableExists(SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, true));
if (SchemaUtil.isNamespaceMappingEnabled(PTableType.SYSTEM, ConnectionQueryServicesImpl.this.getProps())) {
if (admin.tableExists(SYSTEM_CATALOG_NAME_BYTES)) {
//check if the server is already updated and have namespace config properly set.
checkClientServerCompatibility(SYSTEM_CATALOG_NAME_BYTES);
}
ensureSystemTablesUpgraded(ConnectionQueryServicesImpl.this.getProps());
} else if (mappedSystemCatalogExists) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.INCONSISTENET_NAMESPACE_MAPPING_PROPERTIES).setMessage("Cannot initiate connection as " + SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, true) + " is found but client does not have " + IS_NAMESPACE_MAPPING_ENABLED + " enabled").build().buildException();
}
createSysMutexTable(admin);
}
Properties scnProps = PropertiesUtil.deepCopy(props);
scnProps.setProperty(PhoenixRuntime.CURRENT_SCN_ATTRIB, Long.toString(MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP));
scnProps.remove(PhoenixRuntime.TENANT_ID_ATTRIB);
String globalUrl = JDBCUtil.removeProperty(url, PhoenixRuntime.TENANT_ID_ATTRIB);
try (PhoenixConnection metaConnection = new PhoenixConnection(ConnectionQueryServicesImpl.this, globalUrl, scnProps, newEmptyMetaData())) {
try {
metaConnection.createStatement().executeUpdate(QueryConstants.CREATE_TABLE_METADATA);
} catch (NewerTableAlreadyExistsException ignore) {
// Ignore, as this will happen if the SYSTEM.CATALOG already exists at this fixed
// timestamp. A TableAlreadyExistsException is not thrown, since the table only exists
// *after* this fixed timestamp.
} catch (TableAlreadyExistsException e) {
long currentServerSideTableTimeStamp = e.getTable().getTimeStamp();
if (currentServerSideTableTimeStamp < MIN_SYSTEM_TABLE_TIMESTAMP) {
ConnectionQueryServicesImpl.this.upgradeRequired.set(true);
}
} catch (PhoenixIOException e) {
if (!Iterables.isEmpty(Iterables.filter(Throwables.getCausalChain(e), AccessDeniedException.class))) {
// Pass
logger.warn("Could not check for Phoenix SYSTEM tables, assuming they exist and are properly configured");
checkClientServerCompatibility(SchemaUtil.getPhysicalName(SYSTEM_CATALOG_NAME_BYTES, getProps()).getName());
success = true;
} else {
initializationException = e;
}
return null;
}
if (!ConnectionQueryServicesImpl.this.upgradeRequired.get()) {
createOtherSystemTables(metaConnection);
} else if (isAutoUpgradeEnabled && !isDoNotUpgradePropSet) {
upgradeSystemTables(url, props);
}
}
scheduleRenewLeaseTasks();
success = true;
} catch (RetriableUpgradeException e) {
// to retry establishing connection.
throw e;
} catch (Exception e) {
if (e instanceof SQLException) {
initializationException = (SQLException) e;
} else {
// wrap every other exception into a SQLException
initializationException = new SQLException(e);
}
} finally {
try {
if (!success && hConnectionEstablished) {
connection.close();
}
} catch (IOException e) {
SQLException ex = new SQLException(e);
if (initializationException != null) {
initializationException.setNextException(ex);
} else {
initializationException = ex;
}
} finally {
try {
if (initializationException != null) {
throw initializationException;
}
} finally {
initialized = true;
}
}
}
}
return null;
}
});
} catch (Exception e) {
Throwables.propagateIfInstanceOf(e, SQLException.class);
Throwables.propagate(e);
}
}
use of org.apache.phoenix.exception.PhoenixIOException in project phoenix by apache.
the class ConnectionQueryServicesImplTest method testExceptionHandlingOnSystemNamespaceCreation.
@SuppressWarnings("unchecked")
@Test
public void testExceptionHandlingOnSystemNamespaceCreation() throws Exception {
ConnectionQueryServicesImpl cqs = mock(ConnectionQueryServicesImpl.class);
// Invoke the real methods for these two calls
when(cqs.createSchema(any(List.class), anyString())).thenCallRealMethod();
doCallRealMethod().when(cqs).ensureSystemTablesUpgraded(any(ReadOnlyProps.class));
// Spoof out this call so that ensureSystemTablesUpgrade() will return-fast.
when(cqs.getSystemTableNames(any(HBaseAdmin.class))).thenReturn(Collections.<TableName>emptyList());
// Throw a special exception to check on later
doThrow(PHOENIX_IO_EXCEPTION).when(cqs).ensureNamespaceCreated(anyString());
// Make sure that ensureSystemTablesUpgraded will try to migrate the system tables.
Map<String, String> props = new HashMap<>();
props.put(QueryServices.IS_NAMESPACE_MAPPING_ENABLED, "true");
cqs.ensureSystemTablesUpgraded(new ReadOnlyProps(props));
// Should be called after upgradeSystemTables()
// Proves that execution proceeded
verify(cqs).getSystemTableNames(any(HBaseAdmin.class));
try {
// Verifies that the exception is propagated back to the caller
cqs.createSchema(Collections.<Mutation>emptyList(), "");
} catch (PhoenixIOException e) {
assertEquals(PHOENIX_IO_EXCEPTION, e);
}
}
use of org.apache.phoenix.exception.PhoenixIOException in project phoenix by apache.
the class ConnectionQueryServicesImpl method ensureSystemTablesUpgraded.
void ensureSystemTablesUpgraded(ReadOnlyProps props) throws SQLException, IOException, IllegalArgumentException, InterruptedException {
if (!SchemaUtil.isNamespaceMappingEnabled(PTableType.SYSTEM, props)) {
return;
}
HTableInterface metatable = null;
try (HBaseAdmin admin = getAdmin()) {
// Namespace-mapping is enabled at this point.
try {
ensureNamespaceCreated(QueryConstants.SYSTEM_SCHEMA_NAME);
} catch (PhoenixIOException e) {
// We could either:
// 1) Not access the NS descriptor. The NS may or may not exist at this point.
// 2) We could not create the NS
// Regardless of the case 1 or 2, if the NS does not exist, we will error expectedly
// below. If the NS does exist and is mapped, the below check will exit gracefully.
}
List<TableName> tableNames = getSystemTableNames(admin);
// No tables exist matching "SYSTEM\..*", they are all already in "SYSTEM:.*"
if (tableNames.size() == 0) {
return;
}
// Try to move any remaining tables matching "SYSTEM\..*" into "SYSTEM:"
if (tableNames.size() > 5) {
logger.warn("Expected 5 system tables but found " + tableNames.size() + ":" + tableNames);
}
byte[] mappedSystemTable = SchemaUtil.getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, props).getName();
metatable = getTable(mappedSystemTable);
if (tableNames.contains(PhoenixDatabaseMetaData.SYSTEM_CATALOG_HBASE_TABLE_NAME)) {
if (!admin.tableExists(mappedSystemTable)) {
UpgradeUtil.mapTableToNamespace(admin, metatable, PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME, props, null, PTableType.SYSTEM, null);
ConnectionQueryServicesImpl.this.removeTable(null, PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME, null, MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_1_0);
}
tableNames.remove(PhoenixDatabaseMetaData.SYSTEM_CATALOG_HBASE_TABLE_NAME);
}
tableNames.remove(PhoenixDatabaseMetaData.SYSTEM_MUTEX_HBASE_TABLE_NAME);
for (TableName table : tableNames) {
UpgradeUtil.mapTableToNamespace(admin, metatable, table.getNameAsString(), props, null, PTableType.SYSTEM, null);
ConnectionQueryServicesImpl.this.removeTable(null, table.getNameAsString(), null, MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_1_0);
}
if (!tableNames.isEmpty()) {
clearCache();
}
} finally {
if (metatable != null) {
metatable.close();
}
}
}
Aggregations