You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2018/10/08 13:56:19 UTC

syncope git commit: [SYNCOPE-1379] provide the possibility to configure check connection timeouts (console side) + properties to customize resource connection checks thread pool

Repository: syncope
Updated Branches:
  refs/heads/2_0_X 8c1a4f315 -> 11e88868b


[SYNCOPE-1379] provide the possibility to configure check connection timeouts (console side) + properties to customize resource connection checks thread pool


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/11e88868
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/11e88868
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/11e88868

Branch: refs/heads/2_0_X
Commit: 11e88868b1bf88d3b3ab0d6cb25261d7686d9a8e
Parents: 8c1a4f3
Author: fmartelli <fa...@gmail.com>
Authored: Mon Oct 8 15:55:42 2018 +0200
Committer: fmartelli <fa...@gmail.com>
Committed: Mon Oct 8 15:55:42 2018 +0200

----------------------------------------------------------------------
 .../console/SyncopeConsoleApplication.java      |  23 ++
 .../client/console/SyncopeConsoleSession.java   |   6 +-
 .../topology/TopologyWebSocketBehavior.java     | 209 +++++++++++++++----
 .../src/main/resources/console.properties       |   4 +
 .../src/main/resources/console.properties       |   4 +
 .../src/test/resources/console.properties       |   5 +
 6 files changed, 211 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/11e88868/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
index eeaf602..e160f1f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleApplication.java
@@ -111,6 +111,12 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
 
     private Integer maxWaitTime;
 
+    private Integer corePoolSize;
+
+    private Integer maxPoolSize;
+
+    private Integer queueCapacity;
+
     private List<String> domains;
 
     private Map<String, Class<? extends BasePage>> pageClasses;
@@ -166,6 +172,11 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
 
         maxWaitTime = Integer.valueOf(props.getProperty("maxWaitTimeOnApplyChanges", "30"));
 
+        // Resource connections check thread pool size
+        corePoolSize = Integer.valueOf(props.getProperty("topology.corePoolSize", "5"));
+        maxPoolSize = Integer.valueOf(props.getProperty("topology.maxPoolSize", "10"));
+        queueCapacity = Integer.valueOf(props.getProperty("topology.queueCapacity", "50"));
+
         String csrf = props.getProperty("csrf");
 
         // process page properties
@@ -322,6 +333,18 @@ public class SyncopeConsoleApplication extends AuthenticatedWebApplication {
         return maxWaitTime;
     }
 
+    public Integer getCorePoolSize() {
+        return corePoolSize;
+    }
+
+    public Integer getMaxPoolSize() {
+        return maxPoolSize;
+    }
+
+    public Integer getQueueCapacity() {
+        return queueCapacity;
+    }
+
     public SyncopeClientFactoryBean newClientFactory() {
         return new SyncopeClientFactoryBean().
                 setAddress(scheme + "://" + host + ":" + port + "/" + rootPath).

http://git-wip-us.apache.org/repos/asf/syncope/blob/11e88868/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
index bda14db..f312ca5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java
@@ -103,9 +103,9 @@ public class SyncopeConsoleSession extends AuthenticatedWebSession {
 
         executor = new ThreadPoolTaskExecutor();
         executor.setWaitForTasksToCompleteOnShutdown(false);
-        executor.setCorePoolSize(5);
-        executor.setMaxPoolSize(10);
-        executor.setQueueCapacity(50);
+        executor.setCorePoolSize(SyncopeConsoleApplication.get().getCorePoolSize());
+        executor.setMaxPoolSize(SyncopeConsoleApplication.get().getMaxPoolSize());
+        executor.setQueueCapacity(SyncopeConsoleApplication.get().getQueueCapacity());
         executor.initialize();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/11e88868/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java
index 1134a00..9f15018 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java
@@ -27,9 +27,15 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.rest.ConfRestClient;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
 import org.apache.syncope.client.console.rest.ResourceRestClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.wicket.Application;
@@ -40,6 +46,7 @@ import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
 import org.apache.wicket.protocol.ws.api.message.TextMessage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
 
 public class TopologyWebSocketBehavior extends WebSocketBehavior {
 
@@ -49,13 +56,21 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
 
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
 
-    private final Map<String, String> resources =
-            Collections.<String, String>synchronizedMap(new HashMap<String, String>());
+    private static final String CONNECTOR_TEST_TIMEOUT_PARAMETER = "connector.test.timeout";
+
+    private Integer connectorTestTimeout = null;
+
+    private static final String RESOURCE_TEST_TIMEOUT_PARAMETER = "resource.test.timeout";
+
+    private Integer resourceTestTimeout = null;
+
+    private final Map<String, String> resources
+            = Collections.<String, String>synchronizedMap(new HashMap<String, String>());
 
     private final Set<String> runningResCheck = Collections.synchronizedSet(new HashSet<String>());
 
-    private final Map<String, String> connectors =
-            Collections.<String, String>synchronizedMap(new HashMap<String, String>());
+    private final Map<String, String> connectors
+            = Collections.<String, String>synchronizedMap(new HashMap<String, String>());
 
     private final Set<String> runningConnCheck = Collections.synchronizedSet(new HashSet<String>());
 
@@ -63,6 +78,28 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
 
     private final ResourceRestClient resourceRestClient = new ResourceRestClient();
 
+    public TopologyWebSocketBehavior() {
+        // Handling with timeout as per SYNCOPE-1379
+        try {
+            // Loop just to avoid NotFound exception raising on the Core side
+            for (AttrTO param : new ConfRestClient().list()) {
+                if (!CollectionUtils.isEmpty(param.getValues())) {
+                    try {
+                        if (CONNECTOR_TEST_TIMEOUT_PARAMETER.equalsIgnoreCase(param.getSchema())) {
+                            connectorTestTimeout = Integer.parseInt(param.getValues().get(0));
+                        } else if (RESOURCE_TEST_TIMEOUT_PARAMETER.equalsIgnoreCase(param.getSchema())) {
+                            resourceTestTimeout = Integer.parseInt(param.getValues().get(0));
+                        }
+                    } catch (NumberFormatException e) {
+                        LOG.warn("Invalid timeout {}", param);
+                    }
+                }
+            }
+        } catch (SyncopeClientException e) {
+            // ignore exception
+        }
+    }
+
     @Override
     protected void onMessage(final WebSocketRequestHandler handler, final TextMessage message) {
         try {
@@ -85,7 +122,11 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
                         runningConnCheck.add(ckey);
                     }
 
-                    SyncopeConsoleSession.get().execute(new ConnCheck(ckey));
+                    try {
+                        SyncopeConsoleSession.get().execute(new ConnCheck(ckey));
+                    } catch (Exception e) {
+                        LOG.error("Unexpected error", e);
+                    }
 
                     break;
                 case CHECK_RESOURCE:
@@ -104,7 +145,11 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
                         runningResCheck.add(rkey);
                     }
 
-                    SyncopeConsoleSession.get().execute(new ResCheck(rkey));
+                    try {
+                        SyncopeConsoleSession.get().execute(new ResCheck(rkey));
+                    } catch (Exception e) {
+                        LOG.error("Unexpected error", e);
+                    }
 
                     break;
                 case ADD_ENDPOINT:
@@ -128,6 +173,37 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
         return this.resources.keySet().containsAll(resources);
     }
 
+    private void timeoutHandlingConnectionChecker(
+            final Checker checker,
+            final Integer timeout,
+            final Map<String, String> responses,
+            final Set<String> running) {
+        String res = null;
+        try {
+            if (timeout == null) {
+                LOG.debug("No timeouts for resource connection checking ... ");
+                res = SyncopeConsoleSession.get().execute(checker).get();
+            } else if (timeout > 0) {
+                LOG.debug("Timeouts provided for resource connection checking ... ");
+                res = SyncopeConsoleSession.get().execute(checker).get(timeout, TimeUnit.SECONDS);
+            }
+        } catch (InterruptedException | TimeoutException e) {
+            LOG.warn("Connection with {} timed out", checker.getKey());
+            res = String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
+                    TopologyNode.Status.UNREACHABLE, checker.getKey());
+        } catch (Exception e) {
+            LOG.error("Unexpected exception conneting to {}", checker.getKey(), e);
+            res = String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
+                    TopologyNode.Status.FAILURE, checker.getKey());
+        }
+
+        if (res != null) {
+            responses.put(checker.getKey(), res);
+        }
+
+        running.remove(checker.getKey());
+    }
+
     class ConnCheck implements Runnable {
 
         private final String key;
@@ -144,23 +220,15 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
 
         @Override
         public void run() {
-            try {
-                ThreadContext.setApplication(application);
-                ThreadContext.setSession(session);
-
-                String res;
-                try {
-                    final ConnInstanceTO connector = connectorRestClient.read(key);
-                    res = String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
-                            connectorRestClient.check(connector).getLeft()
-                            ? TopologyNode.Status.REACHABLE : TopologyNode.Status.UNREACHABLE, key);
-                } catch (Exception e) {
-                    LOG.warn("Error checking connection for {}", key, e);
-                    res = String.format("{ \"status\": \"%s\", \"target\": \"%s\"}", TopologyNode.Status.FAILURE, key);
-                }
+            ThreadContext.setApplication(application);
+            ThreadContext.setSession(session);
 
-                connectors.put(key, res);
-                runningConnCheck.remove(key);
+            try {
+                timeoutHandlingConnectionChecker(
+                        new ConnectorChecker(key, this.application),
+                        connectorTestTimeout,
+                        connectors,
+                        runningConnCheck);
             } finally {
                 ThreadContext.detach();
             }
@@ -183,23 +251,90 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
 
         @Override
         public void run() {
+            ThreadContext.setApplication(application);
+            ThreadContext.setSession(session);
+
             try {
-                ThreadContext.setApplication(application);
-                ThreadContext.setSession(session);
-
-                String res;
-                try {
-                    final ResourceTO resource = resourceRestClient.read(key);
-                    res = String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
-                            resourceRestClient.check(resource).getLeft()
-                            ? TopologyNode.Status.REACHABLE : TopologyNode.Status.UNREACHABLE, key);
-                } catch (Exception e) {
-                    LOG.warn("Error checking connection for {}", key, e);
-                    res = String.format("{ \"status\": \"%s\", \"target\": \"%s\"}", TopologyNode.Status.FAILURE, key);
-                }
+                timeoutHandlingConnectionChecker(
+                        new ResourceChecker(key, this.application),
+                        resourceTestTimeout,
+                        resources,
+                        runningResCheck);
+            } finally {
+                ThreadContext.detach();
+            }
+        }
+    }
 
-                resources.put(key, res);
-                runningResCheck.remove(key);
+    abstract class Checker implements Callable<String> {
+
+        protected final String key;
+
+        protected final Application application;
+
+        protected final Session session;
+
+        Checker(final String key, final Application application) {
+            this.key = key;
+            this.application = application;
+            this.session = Session.exists() ? Session.get() : null;
+        }
+
+        public String getKey() {
+            return key;
+        }
+
+        @Override
+        public abstract String call() throws Exception;
+    }
+
+    class ConnectorChecker extends Checker {
+
+        ConnectorChecker(final String key, final Application application) {
+            super(key, application);
+        }
+
+        @Override
+        public String call() throws Exception {
+            ThreadContext.setApplication(application);
+            ThreadContext.setSession(session);
+
+            try {
+                final ConnInstanceTO connector = connectorRestClient.read(key);
+                return String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
+                        connectorRestClient.check(connector).getLeft()
+                        ? TopologyNode.Status.REACHABLE : TopologyNode.Status.UNREACHABLE, key);
+            } catch (Exception e) {
+                LOG.warn("Error checking connection for {}", key, e);
+                return String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
+                        TopologyNode.Status.FAILURE, key);
+            } finally {
+                ThreadContext.detach();
+            }
+        }
+    }
+
+    class ResourceChecker extends Checker {
+
+        ResourceChecker(final String key, final Application application) {
+            super(key, application);
+        }
+
+        @Override
+        public String call() throws Exception {
+            ThreadContext.setApplication(application);
+            ThreadContext.setSession(session);
+
+            try {
+                final ResourceTO resource = resourceRestClient.read(key);
+                return String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
+                        resourceRestClient.check(resource).getLeft()
+                        ? TopologyNode.Status.REACHABLE : TopologyNode.Status.UNREACHABLE, key);
+            } catch (Exception e) {
+                LOG.warn("Error checking connection for {}", key, e);
+                return String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
+                        TopologyNode.Status.FAILURE,
+                        key);
             } finally {
                 ThreadContext.detach();
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/11e88868/client/console/src/main/resources/console.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/console.properties b/client/console/src/main/resources/console.properties
index 0bb8171..3611052 100644
--- a/client/console/src/main/resources/console.properties
+++ b/client/console/src/main/resources/console.properties
@@ -51,3 +51,7 @@ page.types=org.apache.syncope.client.console.pages.Types
 page.policies=org.apache.syncope.client.console.pages.Policies
 page.notifications=org.apache.syncope.client.console.pages.Notifications
 page.parameters=org.apache.syncope.client.console.pages.Parameters
+
+topology.corePoolSize=10
+topology.maxPoolSize=20
+topology.queueCapacity=50

http://git-wip-us.apache.org/repos/asf/syncope/blob/11e88868/fit/console-reference/src/main/resources/console.properties
----------------------------------------------------------------------
diff --git a/fit/console-reference/src/main/resources/console.properties b/fit/console-reference/src/main/resources/console.properties
index 6bd549c..366d0de 100644
--- a/fit/console-reference/src/main/resources/console.properties
+++ b/fit/console-reference/src/main/resources/console.properties
@@ -51,3 +51,7 @@ page.types=org.apache.syncope.client.console.pages.Types
 page.policies=org.apache.syncope.client.console.pages.Policies
 page.notifications=org.apache.syncope.client.console.pages.Notifications
 page.parameters=org.apache.syncope.client.console.pages.Parameters
+
+topology.corePoolSize=50
+topology.maxPoolSize=100
+topology.queueCapacity=10

http://git-wip-us.apache.org/repos/asf/syncope/blob/11e88868/fit/core-reference/src/test/resources/console.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/console.properties b/fit/core-reference/src/test/resources/console.properties
index fa46422..908acfb 100644
--- a/fit/core-reference/src/test/resources/console.properties
+++ b/fit/core-reference/src/test/resources/console.properties
@@ -51,3 +51,8 @@ page.types=org.apache.syncope.client.console.pages.Types
 page.policies=org.apache.syncope.client.console.pages.Policies
 page.notifications=org.apache.syncope.client.console.pages.Notifications
 page.parameters=org.apache.syncope.client.console.pages.Parameters
+
+topology.corePoolSize=50
+topology.maxPoolSize=100
+topology.queueCapacity=10
+