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 + 
"\\..*"));

Reply via email to