This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git

commit 905b30e4fd2efdc78c3dfa1e310f453e0839cc3d
Author: Robert Lazarski <[email protected]>
AuthorDate: Mon Apr 13 07:53:33 2026 -1000

    AXIS2-5788 Add non-touching overload of getServiceGroupContext
    
    ConfigurationContext.getServiceGroupContext(id) always calls
    ServiceGroupContext.touch() on a hit, which resets lastTouchedTime.
    That is an "observer effect": any caller that wants to inspect a
    context (e.g. a session-cleanup sweep evaluating staleness against
    lastTouchedTime) mutates the very field it is trying to read and
    ends up keeping the context alive forever.
    
    Add an overload that takes an explicit touchServiceGroupContext flag:
    
        ServiceGroupContext getServiceGroupContext(String id,
                                                   boolean 
touchServiceGroupContext)
    
    The existing single-arg method is preserved and delegates with
    touch=true, so legacy callers see no behaviour change. Callers that
    want a read-only peek pass touch=false.
    
    Also fix the stale Javadoc on getServiceGroupContextIDs() noted in
    the same ticket (it claimed to return a hashmap; it returns a
    String[]).
    
    No functional change to the lookup itself beyond collapsing the
    duplicated touch() call at the two hit sites into a single branch.
---
 .../apache/axis2/context/ConfigurationContext.java | 49 +++++++++++++++++-----
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git 
a/modules/kernel/src/org/apache/axis2/context/ConfigurationContext.java 
b/modules/kernel/src/org/apache/axis2/context/ConfigurationContext.java
index 69ebc4eb8a..1365a582f0 100644
--- a/modules/kernel/src/org/apache/axis2/context/ConfigurationContext.java
+++ b/modules/kernel/src/org/apache/axis2/context/ConfigurationContext.java
@@ -500,12 +500,36 @@ public class ConfigurationContext extends AbstractContext 
{
 
     /**
      * Returns a ServiceGroupContext object associated with the specified ID 
from the internal
-     * table.
+     * table. The returned context's {@code lastTouchedTime} is updated as a 
side effect of the
+     * lookup; use {@link #getServiceGroupContext(String, boolean)} with 
{@code touch=false}
+     * if the caller needs to inspect the context (for example to evaluate 
staleness against
+     * {@code lastTouchedTime}) without mutating it. See AXIS2-5788.
      *
      * @param serviceGroupCtxId The ID string associated with the 
ServiceGroupContext object
      * @return The ServiceGroupContext object, or null if not found
      */
     public ServiceGroupContext getServiceGroupContext(String 
serviceGroupCtxId) {
+        return getServiceGroupContext(serviceGroupCtxId, true);
+    }
+
+    /**
+     * Returns a ServiceGroupContext object associated with the specified ID 
from the internal
+     * table, optionally updating its {@code lastTouchedTime}.
+     * <p>
+     * Passing {@code touchServiceGroupContext=false} lets external code read 
the context
+     * without the "observer effect" described in
+     * <a 
href="https://issues.apache.org/jira/browse/AXIS2-5788";>AXIS2-5788</a>:
+     * for example, session-cleanup code that wants to evaluate staleness 
against
+     * {@code lastTouchedTime} would otherwise reset the clock by the very act 
of looking.
+     *
+     * @param serviceGroupCtxId         The ID string associated with the 
ServiceGroupContext object.
+     * @param touchServiceGroupContext  {@code true} to update {@code 
lastTouchedTime} on a hit
+     *                                  (legacy behaviour preserved for 
back-compat), {@code false}
+     *                                  to leave it unchanged.
+     * @return The ServiceGroupContext object, or null if not found.
+     */
+    public ServiceGroupContext getServiceGroupContext(String serviceGroupCtxId,
+                                                      boolean 
touchServiceGroupContext) {
 
         if (serviceGroupCtxId == null) {
             // Hashtables require non-null key-value pairs
@@ -515,15 +539,13 @@ public class ConfigurationContext extends AbstractContext 
{
         ServiceGroupContext serviceGroupContext = null;
 
         if (serviceGroupContextMap != null) {
-            serviceGroupContext =serviceGroupContextMap.get(serviceGroupCtxId);
-            if (serviceGroupContext != null) {
-                serviceGroupContext.touch();
-            } else {
-                serviceGroupContext =applicationSessionServiceGroupContexts
+            serviceGroupContext = 
serviceGroupContextMap.get(serviceGroupCtxId);
+            if (serviceGroupContext == null) {
+                serviceGroupContext = applicationSessionServiceGroupContexts
                                 .get(serviceGroupCtxId);
-                if (serviceGroupContext != null) {
-                    serviceGroupContext.touch();
-                }
+            }
+            if (serviceGroupContext != null && touchServiceGroupContext) {
+                serviceGroupContext.touch();
             }
         }
 
@@ -532,9 +554,14 @@ public class ConfigurationContext extends AbstractContext {
     }
 
     /**
-     * Gets all service groups in the system.
+     * Returns the IDs of all service groups currently held by this
+     * {@code ConfigurationContext} (both SOAP-session and application-session 
scoped).
+     * <p>
+     * Fixes the stale Javadoc noted in
+     * <a 
href="https://issues.apache.org/jira/browse/AXIS2-5788";>AXIS2-5788</a>: the 
return
+     * type is a {@code String[]}, not a hashmap of {@code 
ServiceGroupContext} instances.
      *
-     * @return Returns hashmap of ServiceGroupContexts.
+     * @return an array of service group context IDs; never {@code null}, but 
may be empty.
      */
     public String[] getServiceGroupContextIDs() {
         String[] ids = new String[serviceGroupContextMap.size() +

Reply via email to