From 6a8cbe6991332405a32da1fccefcae6472f6b9fd Mon Sep 17 00:00:00 2001
From: brinn <brinn>
Date: Wed, 10 Oct 2012 15:07:24 +0000
Subject: [PATCH] BIS-215 Logout hangs when a DSS is not up.

SVN: 27134
---
 .../generic/server/SessionFactory.java        | 20 +-------
 .../business/DataStoreServiceFactory.java     | 48 ++++++++++++++++++-
 .../business/IDataStoreServiceFactory.java    |  6 +++
 3 files changed, 55 insertions(+), 19 deletions(-)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java
index 5dff8668a9d..f09df44ecd8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java
@@ -16,13 +16,10 @@
 
 package ch.systemsx.cisd.openbis.generic.server;
 
-import java.net.ConnectException;
-
 import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.authentication.ISessionFactory;
 import ch.systemsx.cisd.authentication.Principal;
-import ch.systemsx.cisd.common.exception.ExceptionUtils;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.shared.basic.string.StringUtils;
@@ -82,21 +79,8 @@ public final class SessionFactory implements ISessionFactory<Session>
                             final String remoteUrl = datastore.getRemoteUrl();
                             if (StringUtils.isBlank(remoteUrl) == false)
                             {
-                                try
-                                {
-                                    dssFactory.create(remoteUrl).cleanupSession(sessionToken);
-                                } catch (RuntimeException ex)
-                                {
-                                    Throwable originalCause = ExceptionUtils.getEndOfChain(ex);
-                                    if (originalCause instanceof ConnectException == false)
-                                    {
-                                        throw ex;
-                                    } else
-                                    {
-                                        operationLog.warn("Couldn't cleanup session at "
-                                                + remoteUrl + ": " + ex);
-                                    }
-                                }
+                                dssFactory.createMonitored(remoteUrl).cleanupSession(
+                                        sessionToken);
                             } else
                             {
                                 operationLog.warn("datastore remoteUrl of datastore "
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DataStoreServiceFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DataStoreServiceFactory.java
index 70e2c8a8f30..3fb67825393 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DataStoreServiceFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DataStoreServiceFactory.java
@@ -20,9 +20,20 @@ import static ch.systemsx.cisd.openbis.generic.shared.basic.GenericSharedConstan
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
 
 import org.apache.commons.lang.time.DateUtils;
+import org.apache.log4j.Logger;
+import org.springframework.remoting.RemoteAccessException;
 
+import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
+import ch.systemsx.cisd.base.namedthread.NamingThreadPoolExecutor;
+import ch.systemsx.cisd.common.TimingParameters;
+import ch.systemsx.cisd.common.concurrent.MonitoringProxy;
+import ch.systemsx.cisd.common.logging.Log4jSimpleLogger;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.logging.LogLevel;
 import ch.systemsx.cisd.common.spring.HttpInvokerUtils;
 import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService;
 
@@ -33,9 +44,18 @@ import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService;
  */
 public class DataStoreServiceFactory implements IDataStoreServiceFactory
 {
+    private final static int NUMBER_OF_CORE_THREADS = 10;
+
     private final Map<String, IDataStoreService> services =
             new HashMap<String, IDataStoreService>();
 
+    private final static Logger machineLog = LogFactory.getLogger(LogCategory.MACHINE,
+            IDataStoreService.class);
+
+    private final static ExecutorService executorService =
+            new NamingThreadPoolExecutor("Monitoring Proxy").corePoolSize(NUMBER_OF_CORE_THREADS)
+                    .daemonize();
+
     @Override
     public IDataStoreService create(String serverURL)
     {
@@ -43,11 +63,37 @@ public class DataStoreServiceFactory implements IDataStoreServiceFactory
         if (service == null)
         {
             service =
-                    HttpInvokerUtils.createServiceStub(IDataStoreService.class, serverURL + "/"
+                    HttpInvokerUtils.createServiceStub(IDataStoreService.class, serverURL
+                            + "/"
                             + DATA_STORE_SERVER_SERVICE_NAME, 5 * DateUtils.MILLIS_PER_MINUTE);
             services.put(serverURL, service);
         }
         return service;
     }
 
+    @Override
+    public IDataStoreService createMonitored(String serverURL)
+    {
+        try
+        {
+            return MonitoringProxy
+                    .create(IDataStoreService.class, create(serverURL))
+                    .errorLog(new Log4jSimpleLogger(machineLog))
+                    .logLevelForSuccessfulCalls(LogLevel.INFO)
+                    .timing(TimingParameters.create(-1L, 5, DateUtils.MILLIS_PER_MINUTE))
+                    .exceptionClassSuitableForRetrying(RemoteAccessException.class)
+                    .executorService(executorService)
+                    .callAsynchronously(
+                            IDataStoreService.class.getMethod("cleanupSession", new Class<?>[]
+                                { String.class }))
+                    .get();
+        } catch (SecurityException ex)
+        {
+            throw CheckedExceptionTunnel.wrapIfNecessary(ex);
+        } catch (NoSuchMethodException ex)
+        {
+            throw CheckedExceptionTunnel.wrapIfNecessary(ex);
+        }
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/IDataStoreServiceFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/IDataStoreServiceFactory.java
index b0c4bbbfafc..08604f383f5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/IDataStoreServiceFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/IDataStoreServiceFactory.java
@@ -24,4 +24,10 @@ import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService;
 public interface IDataStoreServiceFactory
 {
     public IDataStoreService create(String serverURL);
+
+    /**
+     * Creates a monitored version of the service where
+     * {@link IDataStoreService#cleanupSession(String)} is run asynchronously.
+     */
+    public IDataStoreService createMonitored(String serverURL);
 }
-- 
GitLab