PHOENIX-4941 Handle TableExistsException when wrapped under RemoteException for SYSTEM.MUTEX table
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/ec91f62a Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/ec91f62a Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/ec91f62a Branch: refs/heads/4.x-cdh5.15 Commit: ec91f62ac4aea6d82f9c315fbf0e7b6e3e6b513b Parents: 3ace797 Author: Ankit Singhal <ankitsingha...@gmail.com> Authored: Tue Oct 2 20:12:07 2018 +0100 Committer: Pedro Boado <pbo...@apache.org> Committed: Wed Oct 17 22:49:38 2018 +0100 ---------------------------------------------------------------------- .../query/ConnectionQueryServicesImpl.java | 47 +++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/ec91f62a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java index 9ee33a5..39ad967 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java @@ -71,6 +71,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -2567,22 +2568,12 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement boolean foundAccessDeniedException = false; // when running spark/map reduce jobs the ADE might be wrapped // in a RemoteException - for (Throwable t : Throwables.getCausalChain(e)) { - if (t instanceof AccessDeniedException - || (t instanceof RemoteException - && ((RemoteException) t).getClassName() - .equals(AccessDeniedException.class - .getName()))) { - foundAccessDeniedException = true; - break; - } - } - if (foundAccessDeniedException) { + if (inspectIfAnyExceptionInChain(e, Collections.singletonList(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 if (!Iterables.isEmpty(Iterables.filter(Throwables.getCausalChain(e), NamespaceNotFoundException.class))) { + } else if (inspectIfAnyExceptionInChain(e, Collections.singletonList(NamespaceNotFoundException.class))) { // This exception is only possible if SYSTEM namespace mapping is enabled and SYSTEM namespace is missing // It implies that SYSTEM tables are not created and hence we shouldn't provide a connection AccessDeniedException ade = new AccessDeniedException("Insufficient permissions to create SYSTEM namespace and SYSTEM Tables"); @@ -2677,15 +2668,39 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement columnDesc.setTimeToLive(TTL_FOR_MUTEX); // Let mutex expire after some time tableDesc.addFamily(columnDesc); admin.createTable(tableDesc); - } catch (IOException e) { - if(!Iterables.isEmpty(Iterables.filter(Throwables.getCausalChain(e), AccessDeniedException.class)) || - !Iterables.isEmpty(Iterables.filter(Throwables.getCausalChain(e), org.apache.hadoop.hbase.TableNotFoundException.class))) { - // Ignore + } + catch (IOException e) { + if (inspectIfAnyExceptionInChain(e, Arrays.<Class<? extends IOException>> asList( + AccessDeniedException.class, org.apache.hadoop.hbase.TableExistsException.class))) { + // Ignore TableExistsException as another client might beat us during upgrade. + // Ignore AccessDeniedException, as it may be possible underpriviliged user trying to use the connection + // which doesn't required upgrade. + logger.debug("Ignoring exception while creating mutex table during connection initialization: " + + Throwables.getStackTraceAsString(e)); } else { throw e; } } } + + private boolean inspectIfAnyExceptionInChain(Throwable io, List<Class<? extends IOException>> ioList) { + boolean exceptionToIgnore = false; + for (Throwable t : Throwables.getCausalChain(io)) { + for (Class<? extends IOException> exception : ioList) { + exceptionToIgnore |= isExceptionInstanceOf(t, exception); + } + if (exceptionToIgnore) { + break; + } + + } + return exceptionToIgnore; + } + + private boolean isExceptionInstanceOf(Throwable io, Class<? extends IOException> exception) { + return exception.isInstance(io) || (io instanceof RemoteException + && (((RemoteException)io).getClassName().equals(exception.getName()))); + } List<TableName> getSystemTableNamesInDefaultNamespace(HBaseAdmin admin) throws IOException { return Lists.newArrayList(admin.listTableNames(QueryConstants.SYSTEM_SCHEMA_NAME + "\\..*"));