agingade commented on a change in pull request #6835:
URL: https://github.com/apache/geode/pull/6835#discussion_r702155489



##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java
##########
@@ -1763,6 +1767,19 @@ private void processMessages() {
     }
   }
 
+  private void handleAuthenticate(Message clientMessage) {
+    // if client is in multi-user mode, the CacheClientUpdator (at this point)
+    // can't differentiate which user this message is intended to. so throw 
exception for now
+    // one possible solution is re-authenticate all users in this client
+    if (qManager.getPool().getMultiuserAuthentication()) {
+      throw new UnsupportedOperationException(
+          "Multi-user mode doesn't support re-authentication. This client will 
be closed.");
+    }
+    Long userId = AuthenticateUserOp
+        .executeOn(location, qManager.getPool(), 
this.system.getSecurityProperties());

Review comment:
       CacheClientUpdater threads are meant to process client side events; it 
never sends any message back to the server....
   I don't see strong reason unless tests are added to verify it; it will be 
good to use a separate thread to send messages back to the server....
   If not separate thread then there should be tests with possible failure 
conditions from multiple servers scenarios to verify the impact of such with 
cache-client-updater thread.

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java
##########
@@ -1763,6 +1767,19 @@ private void processMessages() {
     }
   }
 
+  private void handleAuthenticate(Message clientMessage) {
+    // if client is in multi-user mode, the CacheClientUpdator (at this point)
+    // can't differentiate which user this message is intended to. so throw 
exception for now
+    // one possible solution is re-authenticate all users in this client
+    if (qManager.getPool().getMultiuserAuthentication()) {
+      throw new UnsupportedOperationException(

Review comment:
       Throwing this only closes/stops the CacheClientUpdater thread. Is this 
the expectation here? If the server-to-client connection needs to be closed, it 
should disconnect all the connections from that server...
   

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageDispatcher.java
##########
@@ -362,31 +385,63 @@ protected void runDispatcher() {
           }
           waitForResumption();
         }
-        try {
-          clientMessage = (ClientMessage) _messageQueue.peek();
-        } catch (RegionDestroyedException skipped) {
-          break;
+
+        if (clientMessage == null) {
+          try {
+            clientMessage = (ClientMessage) _messageQueue.peek();
+          } catch (RegionDestroyedException skipped) {
+            break;
+          }
         }
+
         getStatistics().setQueueSize(_messageQueue.size());
         if (isStopped()) {
           break;
         }
-        if (clientMessage != null) {
-          // Process the message
-          long start = getStatistics().startTime();
-          //// BUGFIX for BUG#38206 and BUG#37791
-          boolean isDispatched = dispatchMessage(clientMessage);
-          getStatistics().endMessage(start);
-          if (isDispatched) {
+
+        if (clientMessage == null) {
+          _messageQueue.remove();
+          break;

Review comment:
       The code differs from what it used to be previously; it used to be only 
removed. 
   Can this check be moved to right after the peek is done? and continue the 
loop if its null...

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageDispatcher.java
##########
@@ -362,31 +385,63 @@ protected void runDispatcher() {
           }
           waitForResumption();
         }
-        try {
-          clientMessage = (ClientMessage) _messageQueue.peek();
-        } catch (RegionDestroyedException skipped) {
-          break;
+
+        if (clientMessage == null) {
+          try {
+            clientMessage = (ClientMessage) _messageQueue.peek();
+          } catch (RegionDestroyedException skipped) {
+            break;
+          }
         }
+
         getStatistics().setQueueSize(_messageQueue.size());
         if (isStopped()) {
           break;
         }
-        if (clientMessage != null) {
-          // Process the message
-          long start = getStatistics().startTime();
-          //// BUGFIX for BUG#38206 and BUG#37791
-          boolean isDispatched = dispatchMessage(clientMessage);
-          getStatistics().endMessage(start);
-          if (isDispatched) {
+
+        if (clientMessage == null) {
+          _messageQueue.remove();
+          break;
+        }
+
+        // Process the message
+        long start = getStatistics().startTime();
+        try {
+          if (dispatchMessage(clientMessage)) {
+            getStatistics().endMessage(start);
             _messageQueue.remove();
             if (clientMessage instanceof ClientMarkerMessageImpl) {
               getProxy().setMarkerEnqueued(false);
             }
           }
-        } else {
+          clientMessage = null;
+          wait_for_re_auth_start_time = -1;
+        } catch (NotAuthorizedException notAuthorized) {
+          // behave as if the message is dispatched, remove from the queue
+          logger.info("skip delivering message: " + clientMessage, 
notAuthorized);

Review comment:
       Info level may cause log to be filled with this message incase of user 
auth changes...

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageDispatcher.java
##########
@@ -362,31 +385,63 @@ protected void runDispatcher() {
           }
           waitForResumption();
         }
-        try {
-          clientMessage = (ClientMessage) _messageQueue.peek();
-        } catch (RegionDestroyedException skipped) {
-          break;
+
+        if (clientMessage == null) {
+          try {
+            clientMessage = (ClientMessage) _messageQueue.peek();
+          } catch (RegionDestroyedException skipped) {
+            break;
+          }
         }
+
         getStatistics().setQueueSize(_messageQueue.size());
         if (isStopped()) {
           break;
         }
-        if (clientMessage != null) {
-          // Process the message
-          long start = getStatistics().startTime();
-          //// BUGFIX for BUG#38206 and BUG#37791
-          boolean isDispatched = dispatchMessage(clientMessage);
-          getStatistics().endMessage(start);
-          if (isDispatched) {
+
+        if (clientMessage == null) {
+          _messageQueue.remove();
+          break;
+        }
+
+        // Process the message
+        long start = getStatistics().startTime();
+        try {
+          if (dispatchMessage(clientMessage)) {
+            getStatistics().endMessage(start);
             _messageQueue.remove();
             if (clientMessage instanceof ClientMarkerMessageImpl) {
               getProxy().setMarkerEnqueued(false);
             }
           }
-        } else {
+          clientMessage = null;
+          wait_for_re_auth_start_time = -1;
+        } catch (NotAuthorizedException notAuthorized) {

Review comment:
       The auth exception handling logic be moved to separate block. E.g. 
handleAuthExceptions(){}

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageDispatcher.java
##########
@@ -362,31 +385,63 @@ protected void runDispatcher() {
           }
           waitForResumption();
         }
-        try {
-          clientMessage = (ClientMessage) _messageQueue.peek();
-        } catch (RegionDestroyedException skipped) {
-          break;
+
+        if (clientMessage == null) {
+          try {
+            clientMessage = (ClientMessage) _messageQueue.peek();
+          } catch (RegionDestroyedException skipped) {
+            break;
+          }
         }
+
         getStatistics().setQueueSize(_messageQueue.size());
         if (isStopped()) {
           break;
         }
-        if (clientMessage != null) {
-          // Process the message
-          long start = getStatistics().startTime();
-          //// BUGFIX for BUG#38206 and BUG#37791
-          boolean isDispatched = dispatchMessage(clientMessage);
-          getStatistics().endMessage(start);
-          if (isDispatched) {
+
+        if (clientMessage == null) {
+          _messageQueue.remove();
+          break;
+        }
+
+        // Process the message
+        long start = getStatistics().startTime();
+        try {
+          if (dispatchMessage(clientMessage)) {
+            getStatistics().endMessage(start);
             _messageQueue.remove();
             if (clientMessage instanceof ClientMarkerMessageImpl) {
               getProxy().setMarkerEnqueued(false);
             }
           }
-        } else {
+          clientMessage = null;
+          wait_for_re_auth_start_time = -1;
+        } catch (NotAuthorizedException notAuthorized) {
+          // behave as if the message is dispatched, remove from the queue
+          logger.info("skip delivering message: " + clientMessage, 
notAuthorized);
           _messageQueue.remove();
+          clientMessage = null;
+        } catch (AuthenticationExpiredException expired) {
+          if (wait_for_re_auth_start_time == -1) {
+            wait_for_re_auth_start_time = System.currentTimeMillis();
+            // only send the message to clients who can handle the message
+            if 
(getProxy().getVersion().isNewerThanOrEqualTo(RE_AUTHENTICATION_START_VERSION)) 
{
+              EventID eventId = new EventID(getCache().getDistributedSystem());
+              sendMessageDirectly(new ClientReAuthenticateMessage(eventId));

Review comment:
       There could be IOException during send that needs to be handled as done 
in IOException catch block.

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientProxy.java
##########
@@ -371,8 +370,11 @@ public void setPostAuthzCallback(AccessControl 
authzCallback) {
     }
   }
 
+  public boolean isMultiUserMode() {
+    return subject == null;

Review comment:
       Is "subject" set/created only in multiuser mode; feels like there should 
be better/other way to do this... 

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageDispatcher.java
##########
@@ -362,31 +385,63 @@ protected void runDispatcher() {
           }
           waitForResumption();
         }
-        try {
-          clientMessage = (ClientMessage) _messageQueue.peek();
-        } catch (RegionDestroyedException skipped) {
-          break;
+
+        if (clientMessage == null) {

Review comment:
       Can we add comment saying client-message from previous peek is not yet 
dispatched and waiting for re-auth; to make it clear why it may not be null...

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageDispatcher.java
##########
@@ -362,31 +385,63 @@ protected void runDispatcher() {
           }
           waitForResumption();
         }
-        try {
-          clientMessage = (ClientMessage) _messageQueue.peek();
-        } catch (RegionDestroyedException skipped) {
-          break;
+
+        if (clientMessage == null) {
+          try {
+            clientMessage = (ClientMessage) _messageQueue.peek();
+          } catch (RegionDestroyedException skipped) {
+            break;
+          }
         }
+
         getStatistics().setQueueSize(_messageQueue.size());
         if (isStopped()) {
           break;
         }
-        if (clientMessage != null) {
-          // Process the message
-          long start = getStatistics().startTime();
-          //// BUGFIX for BUG#38206 and BUG#37791
-          boolean isDispatched = dispatchMessage(clientMessage);
-          getStatistics().endMessage(start);
-          if (isDispatched) {
+
+        if (clientMessage == null) {
+          _messageQueue.remove();
+          break;
+        }
+
+        // Process the message
+        long start = getStatistics().startTime();
+        try {
+          if (dispatchMessage(clientMessage)) {
+            getStatistics().endMessage(start);
             _messageQueue.remove();
             if (clientMessage instanceof ClientMarkerMessageImpl) {
               getProxy().setMarkerEnqueued(false);
             }
           }
-        } else {
+          clientMessage = null;
+          wait_for_re_auth_start_time = -1;
+        } catch (NotAuthorizedException notAuthorized) {
+          // behave as if the message is dispatched, remove from the queue
+          logger.info("skip delivering message: " + clientMessage, 
notAuthorized);
           _messageQueue.remove();
+          clientMessage = null;
+        } catch (AuthenticationExpiredException expired) {
+          if (wait_for_re_auth_start_time == -1) {
+            wait_for_re_auth_start_time = System.currentTimeMillis();
+            // only send the message to clients who can handle the message
+            if 
(getProxy().getVersion().isNewerThanOrEqualTo(RE_AUTHENTICATION_START_VERSION)) 
{
+              EventID eventId = new EventID(getCache().getDistributedSystem());
+              sendMessageDirectly(new ClientReAuthenticateMessage(eventId));
+            }
+            // for older client, we still wait, just in case client will 
perform some operations to
+            // trigger credential refresh on its own.
+            Thread.sleep(500);

Review comment:
       500 may be a large number?
   Is there way to do wait/notify...timely waiting in re-auth?

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/MessageDispatcher.java
##########
@@ -362,31 +385,63 @@ protected void runDispatcher() {
           }
           waitForResumption();
         }
-        try {
-          clientMessage = (ClientMessage) _messageQueue.peek();
-        } catch (RegionDestroyedException skipped) {
-          break;
+
+        if (clientMessage == null) {
+          try {
+            clientMessage = (ClientMessage) _messageQueue.peek();
+          } catch (RegionDestroyedException skipped) {
+            break;
+          }
         }
+
         getStatistics().setQueueSize(_messageQueue.size());
         if (isStopped()) {
           break;
         }
-        if (clientMessage != null) {
-          // Process the message
-          long start = getStatistics().startTime();
-          //// BUGFIX for BUG#38206 and BUG#37791
-          boolean isDispatched = dispatchMessage(clientMessage);
-          getStatistics().endMessage(start);
-          if (isDispatched) {
+
+        if (clientMessage == null) {
+          _messageQueue.remove();
+          break;
+        }
+
+        // Process the message
+        long start = getStatistics().startTime();
+        try {
+          if (dispatchMessage(clientMessage)) {
+            getStatistics().endMessage(start);
             _messageQueue.remove();
             if (clientMessage instanceof ClientMarkerMessageImpl) {
               getProxy().setMarkerEnqueued(false);
             }
           }
-        } else {
+          clientMessage = null;
+          wait_for_re_auth_start_time = -1;
+        } catch (NotAuthorizedException notAuthorized) {
+          // behave as if the message is dispatched, remove from the queue
+          logger.info("skip delivering message: " + clientMessage, 
notAuthorized);
           _messageQueue.remove();
+          clientMessage = null;
+        } catch (AuthenticationExpiredException expired) {
+          if (wait_for_re_auth_start_time == -1) {
+            wait_for_re_auth_start_time = System.currentTimeMillis();
+            // only send the message to clients who can handle the message
+            if 
(getProxy().getVersion().isNewerThanOrEqualTo(RE_AUTHENTICATION_START_VERSION)) 
{
+              EventID eventId = new EventID(getCache().getDistributedSystem());
+              sendMessageDirectly(new ClientReAuthenticateMessage(eventId));
+            }
+            // for older client, we still wait, just in case client will 
perform some operations to
+            // trigger credential refresh on its own.
+            Thread.sleep(500);
+          } else {
+            long elapsedTime = System.currentTimeMillis() - 
wait_for_re_auth_start_time;
+            if (elapsedTime > reAuthenticateWaitTime) {
+              pauseOrUnregisterProxy(expired);

Review comment:
       adding warn/debug level log here may help here...




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to