Browse code

[eas] Feat: add ActiveSync integration test to ensure we don't release with a broken sync server.

Thomas Cataldo authored on 12/04/2019 08:19:46
Showing 19 changed files
... ...
@@ -29,6 +29,7 @@ import java.util.Map;
29 29
 import java.util.concurrent.CompletableFuture;
30 30
 import java.util.concurrent.ConcurrentHashMap;
31 31
 import java.util.concurrent.ExecutionException;
32
+import java.util.concurrent.TimeUnit;
32 33
 import java.util.regex.Matcher;
33 34
 import java.util.regex.Pattern;
34 35
 
... ...
@@ -270,7 +271,7 @@ public class ClientProxyGenerator<S, T> {
270 271
 					}
271 272
 				});
272 273
 				try {
273
-					return f.get();
274
+					return f.get(50, TimeUnit.SECONDS);
274 275
 				} catch (ExecutionException e) {
275 276
 					Throwable t = e.getCause();
276 277
 					if (t instanceof ServerFault) {
277 278
new file mode 100644
... ...
@@ -0,0 +1,11 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<classpath>
3
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
4
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
5
+	<classpathentry kind="src" path="src">
6
+		<attributes>
7
+			<attribute name="test" value="true"/>
8
+		</attributes>
9
+	</classpathentry>
10
+	<classpathentry kind="output" path="bin"/>
11
+</classpath>
0 12
new file mode 100644
... ...
@@ -0,0 +1,28 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<projectDescription>
3
+	<name>net.bluemind.eas.integration.tests</name>
4
+	<comment></comment>
5
+	<projects>
6
+	</projects>
7
+	<buildSpec>
8
+		<buildCommand>
9
+			<name>org.eclipse.jdt.core.javabuilder</name>
10
+			<arguments>
11
+			</arguments>
12
+		</buildCommand>
13
+		<buildCommand>
14
+			<name>org.eclipse.pde.ManifestBuilder</name>
15
+			<arguments>
16
+			</arguments>
17
+		</buildCommand>
18
+		<buildCommand>
19
+			<name>org.eclipse.pde.SchemaBuilder</name>
20
+			<arguments>
21
+			</arguments>
22
+		</buildCommand>
23
+	</buildSpec>
24
+	<natures>
25
+		<nature>org.eclipse.pde.PluginNature</nature>
26
+		<nature>org.eclipse.jdt.core.javanature</nature>
27
+	</natures>
28
+</projectDescription>
0 29
new file mode 100644
... ...
@@ -0,0 +1,44 @@
1
+Manifest-Version: 1.0
2
+Bundle-ManifestVersion: 2
3
+Bundle-Name: net.bluemind.eas.integration.tests
4
+Bundle-SymbolicName: net.bluemind.eas.integration.tests
5
+Bundle-Version: 4.1.0.qualifier
6
+Bundle-Vendor: bluemind.net
7
+Require-Bundle: org.eclipse.core.runtime,
8
+ net.bluemind.core.jdbc.testshelper;bundle-version="4.1.0",
9
+ net.bluemind.tests.defaultdata;bundle-version="4.1.0",
10
+ net.bluemind.core.elasticsearch.testshelper;bundle-version="4.1.0",
11
+ net.bluemind.backend.cyrus.replication.testhelper;bundle-version="4.1.0",
12
+ net.bluemind.vertx.testhelper,
13
+ com.google.guava,
14
+ net.bluemind.backend.cyrus,
15
+ net.bluemind.lib.vertx,
16
+ net.bluemind.hornetq.client,
17
+ net.bluemind.network.topology,
18
+ net.bluemind.pool,
19
+ org.junit,
20
+ net.bluemind.eas.client,
21
+ net.bluemind.eas.config.global,
22
+ net.bluemind.eas.backend.bm;bundle-version="4.1.0",
23
+ net.bluemind.eas.busmods;bundle-version="4.1.0",
24
+ net.bluemind.eas.http;bundle-version="4.1.0",
25
+ net.bluemind.eas.partnership;bundle-version="4.1.0",
26
+ net.bluemind.eas.validation;bundle-version="4.1.0",
27
+ net.bluemind.eas.verticle;bundle-version="4.1.0",
28
+ net.bluemind.core.rest.http.vertx;bundle-version="4.1.0",
29
+ net.bluemind.system.state,
30
+ net.bluemind.eas.storage.jdbc;bundle-version="4.1.0",
31
+ net.bluemind.role.api,
32
+ net.bluemind.eas.service;bundle-version="4.1.0",
33
+ net.bluemind.core.rest,
34
+ net.bluemind.device.api,
35
+ net.bluemind.device.userdevice;bundle-version="4.1.0",
36
+ net.bluemind.backend.cyrus.replication.server;bundle-version="4.1.0",
37
+ net.bluemind.backend.cyrus.replication.storage.core;bundle-version="4.1.0",
38
+ net.bluemind.network.topology.producer;bundle-version="4.1.0",
39
+ net.bluemind.authentication.service;bundle-version="4.1.0",
40
+ net.bluemind.backend.mail.replica.service;bundle-version="4.1.0",
41
+ net.bluemind.device.service;bundle-version="4.1.0"
42
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
43
+Automatic-Module-Name: net.bluemind.eas.integration.tests
44
+Export-Package: net.bluemind.eas.integration.tests
0 45
new file mode 100644
... ...
@@ -0,0 +1,4 @@
1
+source.. = src/
2
+output.. = bin/
3
+bin.includes = META-INF/,\
4
+               .
0 5
new file mode 100644
... ...
@@ -0,0 +1,35 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4
+	<modelVersion>4.0.0</modelVersion>
5
+
6
+	<parent>
7
+		<groupId>net.bluemind</groupId>
8
+		<artifactId>net.bluemind.eas.plugins</artifactId>
9
+		<version>4.1.0-SNAPSHOT</version>
10
+	</parent>
11
+
12
+	<artifactId>net.bluemind.eas.integration.tests</artifactId>
13
+
14
+	<packaging>eclipse-test-plugin</packaging>
15
+
16
+	<build>
17
+		<plugins>
18
+			<plugin>
19
+				<groupId>org.eclipse.tycho</groupId>
20
+				<artifactId>target-platform-configuration</artifactId>
21
+				<configuration>
22
+					<dependency-resolution>
23
+						<extraRequirements>
24
+							<requirement>
25
+								<type>eclipse-feature</type>
26
+								<id>net.bluemind.tests.feature</id>
27
+								<versionRange>0.0.0</versionRange>
28
+							</requirement>
29
+						</extraRequirements>
30
+					</dependency-resolution>
31
+				</configuration>
32
+			</plugin>
33
+		</plugins>
34
+	</build>
35
+</project>
0 36
new file mode 100644
... ...
@@ -0,0 +1,13 @@
1
+[
2
+	{
3
+		"name": "bluemind/postgres-tests"
4
+	},
5
+
6
+	{
7
+		"name": "bluemind/elasticsearch-tests"
8
+	},
9
+
10
+	{
11
+		"name": "bluemind/imap-role"
12
+	}
13
+]
0 14
\ No newline at end of file
1 15
new file mode 100644
... ...
@@ -0,0 +1,81 @@
1
+/* BEGIN LICENSE
2
+  * Copyright © Blue Mind SAS, 2012-2019
3
+  *
4
+  * This file is part of BlueMind. BlueMind is a messaging and collaborative
5
+  * solution.
6
+  *
7
+  * This program is free software; you can redistribute it and/or modify
8
+  * it under the terms of either the GNU Affero General Public License as
9
+  * published by the Free Software Foundation (version 3 of the License).
10
+  *
11
+  * This program is distributed in the hope that it will be useful,
12
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+  *
15
+  * See LICENSE.txt
16
+  * END LICENSE
17
+  */
18
+package net.bluemind.eas.integration.tests;
19
+
20
+import static org.junit.Assert.assertFalse;
21
+import static org.junit.Assert.assertNotNull;
22
+
23
+import java.lang.management.ManagementFactory;
24
+import java.lang.management.ThreadInfo;
25
+import java.lang.management.ThreadMXBean;
26
+
27
+import org.junit.After;
28
+import org.junit.Before;
29
+import org.junit.BeforeClass;
30
+import org.junit.Test;
31
+
32
+import net.bluemind.eas.client.FolderSyncResponse;
33
+import net.bluemind.eas.client.OPClient;
34
+import net.bluemind.eas.config.global.GlobalConfig;
35
+
36
+public class EasIntegrationTests {
37
+
38
+	private EasServerSetup setup;
39
+	private OPClient client;
40
+
41
+	@BeforeClass
42
+	public static void oneShotBefore() {
43
+		System.setProperty("es.mailspool.count", "1");
44
+	}
45
+
46
+	@Before
47
+	public void before() throws Exception {
48
+		this.setup = EasServerSetup.get();
49
+		setup.beforeTest();
50
+		this.client = new OPClient(setup.loginAtDomain(), setup.password(), setup.device().identifier, "junit",
51
+				"junit-agent", "http://127.0.0.1:" + GlobalConfig.EAS_PORT + "/Microsoft-Server-ActiveSync");
52
+
53
+	}
54
+
55
+	@After
56
+	public void after() throws Exception {
57
+		client.destroy();
58
+		setup.afterTest();
59
+	}
60
+
61
+	@Test
62
+	public void testEasIsWorking() throws Exception {
63
+		try {
64
+			client.options();
65
+			FolderSyncResponse fSync = client.folderSync("0");
66
+			assertNotNull(fSync);
67
+			assertFalse(fSync.getFolders().isEmpty());
68
+		} catch (Exception e) {
69
+			dumpThreadDump();
70
+			throw e;
71
+		}
72
+	}
73
+
74
+	public void dumpThreadDump() {
75
+		ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
76
+		for (ThreadInfo ti : threadMxBean.dumpAllThreads(true, true)) {
77
+			System.err.print(ti.toString());
78
+		}
79
+	}
80
+
81
+}
0 82
new file mode 100644
... ...
@@ -0,0 +1,168 @@
1
+/* BEGIN LICENSE
2
+  * Copyright © Blue Mind SAS, 2012-2019
3
+  *
4
+  * This file is part of BlueMind. BlueMind is a messaging and collaborative
5
+  * solution.
6
+  *
7
+  * This program is free software; you can redistribute it and/or modify
8
+  * it under the terms of either the GNU Affero General Public License as
9
+  * published by the Free Software Foundation (version 3 of the License).
10
+  *
11
+  * This program is distributed in the hope that it will be useful,
12
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+  *
15
+  * See LICENSE.txt
16
+  * END LICENSE
17
+  */
18
+package net.bluemind.eas.integration.tests;
19
+
20
+import java.util.Set;
21
+import java.util.concurrent.CountDownLatch;
22
+import java.util.concurrent.TimeUnit;
23
+import java.util.concurrent.TimeoutException;
24
+
25
+import com.google.common.collect.Lists;
26
+
27
+import net.bluemind.backend.cyrus.CyrusService;
28
+import net.bluemind.backend.cyrus.replication.testhelper.CyrusReplicationHelper;
29
+import net.bluemind.core.container.model.ItemValue;
30
+import net.bluemind.core.context.SecurityContext;
31
+import net.bluemind.core.elasticsearch.ElasticsearchTestHelper;
32
+import net.bluemind.core.jdbc.JdbcActivator;
33
+import net.bluemind.core.jdbc.JdbcTestHelper;
34
+import net.bluemind.core.rest.ServerSideServiceProvider;
35
+import net.bluemind.device.api.Device;
36
+import net.bluemind.device.api.IDevice;
37
+import net.bluemind.hornetq.client.MQ;
38
+import net.bluemind.lib.vertx.VertxPlatform;
39
+import net.bluemind.mailbox.api.Mailbox.Routing;
40
+import net.bluemind.network.topology.Topology;
41
+import net.bluemind.pool.impl.BmConfIni;
42
+import net.bluemind.role.api.BasicRoles;
43
+import net.bluemind.server.api.Server;
44
+import net.bluemind.system.state.StateContext;
45
+import net.bluemind.tests.defaultdata.PopulateHelper;
46
+import net.bluemind.vertx.testhelper.Deploy;
47
+
48
+public class EasServerSetup {
49
+
50
+	private static final EasServerSetup INST = new EasServerSetup();
51
+
52
+	public static EasServerSetup get() {
53
+		return INST;
54
+	}
55
+
56
+	private String cyrusIp;
57
+	private String domainUid;
58
+	private String userUid;
59
+	private CyrusReplicationHelper cyrusReplication;
60
+	private Set<String> locatorVerticles;
61
+	private Device device;
62
+
63
+	private EasServerSetup() {
64
+
65
+	}
66
+
67
+	public Device device() {
68
+		return device;
69
+	}
70
+
71
+	public String loginAtDomain() {
72
+		return userUid + "@" + domainUid;
73
+	}
74
+
75
+	public String password() {
76
+		return userUid;
77
+	}
78
+
79
+	public void beforeTest() throws Exception {
80
+		JdbcTestHelper.getInstance().beforeTest();
81
+		JdbcTestHelper.getInstance().getDbSchemaService().initialize();
82
+		this.locatorVerticles = Deploy.verticles(false, "net.bluemind.locator.LocatorVerticle").get(5,
83
+				TimeUnit.SECONDS);
84
+
85
+		BmConfIni ini = new BmConfIni();
86
+
87
+		Server esServer = new Server();
88
+		esServer.ip = ElasticsearchTestHelper.getInstance().getHost();
89
+		System.out.println("ES is " + esServer.ip);
90
+		esServer.tags = Lists.newArrayList("bm/es");
91
+
92
+		this.cyrusIp = ini.get("imap-role");
93
+		Server imapServer = new Server();
94
+		imapServer.ip = cyrusIp;
95
+		imapServer.tags = Lists.newArrayList("mail/imap");
96
+
97
+		ItemValue<Server> cyrusServer = ItemValue.create("localhost", imapServer);
98
+		CyrusService cyrusService = new CyrusService(cyrusServer);
99
+		cyrusService.reset();
100
+
101
+		PopulateHelper.initGlobalVirt(esServer, imapServer);
102
+		ElasticsearchTestHelper.getInstance().beforeTest();
103
+		PopulateHelper.addDomainAdmin("admin0", "global.virt", Routing.none);
104
+
105
+		String unique = System.currentTimeMillis() + "";
106
+		this.domainUid = "test" + unique + ".lab";
107
+		this.userUid = "user" + unique;
108
+
109
+		// ensure the partition is created correctly before restarting cyrus
110
+		PopulateHelper.addDomain(domainUid, Routing.none);
111
+
112
+		System.err.println("Setup replication START");
113
+		this.cyrusReplication = new CyrusReplicationHelper(cyrusIp);
114
+		cyrusReplication.installReplication();
115
+		System.err.println("Setup replication END");
116
+
117
+		JdbcActivator.getInstance().addMailboxDataSource(cyrusReplication.server().uid,
118
+				JdbcTestHelper.getInstance().getMailboxDataDataSource());
119
+
120
+		CountDownLatch cdl = new CountDownLatch(1);
121
+		VertxPlatform.spawnVerticles(ar -> {
122
+			cdl.countDown();
123
+		});
124
+		boolean beforeTimeout = cdl.await(30, TimeUnit.SECONDS);
125
+		if (!beforeTimeout) {
126
+			throw new TimeoutException("Vertx spaw was too slow");
127
+		}
128
+
129
+		MQ.init().get(30, TimeUnit.SECONDS);
130
+		Topology.get();
131
+
132
+		cyrusReplication.startReplication().get(5, TimeUnit.SECONDS);
133
+
134
+		System.err.println("Start populate user " + userUid);
135
+		PopulateHelper.addUser(userUid, domainUid, Routing.internal, BasicRoles.ROLE_EAS);
136
+
137
+		ServerSideServiceProvider prov = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM);
138
+		IDevice devApi = prov.instance(IDevice.class, userUid);
139
+		Device dev = new Device();
140
+		dev.hasPartnership = true;
141
+		dev.identifier = "junit-" + userUid;
142
+		dev.type = "junit-phone";
143
+		dev.isWipe = false;
144
+		dev.owner = userUid;
145
+		devApi.create("junit-" + userUid, dev);
146
+
147
+		this.device = devApi.byIdentifier("junit-" + userUid).value;
148
+
149
+		StateContext.setState("core.started");
150
+		Thread.sleep(200);
151
+		StateContext.setState("core.upgrade.start");
152
+		Thread.sleep(200);
153
+		StateContext.setState("core.upgrade.end");
154
+
155
+		Thread.sleep(2000);
156
+
157
+		System.err.println("Test setup is complete, dev: " + device);
158
+	}
159
+
160
+	public void afterTest() throws Exception {
161
+		System.out.println("Waiting for last events (remove this sleep ?)...");
162
+		Thread.sleep(1000);
163
+		cyrusReplication.stopReplication().get(5, TimeUnit.SECONDS);
164
+		Deploy.afterTest(locatorVerticles);
165
+		JdbcTestHelper.getInstance().afterTest();
166
+	}
167
+
168
+}
... ...
@@ -17,6 +17,7 @@
17 17
 		<module>net.bluemind.eas.service</module>
18 18
 		<module>net.bluemind.eas.service.tests</module>
19 19
 		<module>net.bluemind.eas.verticle</module>
20
+		<module>net.bluemind.eas.integration.tests</module>
20 21
 	</modules>
21 22
 
22 23
 </project>
... ...
@@ -51,9 +51,15 @@ public class SyncServerConnection implements Handler<NetSocket> {
51 51
 	public void handle(NetSocket client) {
52 52
 		String remoteIp = client.remoteAddress().getHostString();
53 53
 		logger.info("Connected {}", remoteIp);
54
-		StorageApiLink.create(vertx, http, remoteIp).thenAccept(storage -> {
55
-			ReplicationSession session = new ReplicationSession(vertx, client, storage, observers);
56
-			session.start();
54
+		StorageApiLink.create(vertx, http, remoteIp).whenComplete((storage, ex) -> {
55
+			if (ex == null) {
56
+				logger.info("Start replication session with {}", client);
57
+				ReplicationSession session = new ReplicationSession(vertx, client, storage, observers);
58
+				session.start();
59
+			} else {
60
+				logger.error(ex.getMessage(), ex);
61
+				client.close();
62
+			}
57 63
 		});
58 64
 	}
59 65
 
... ...
@@ -21,6 +21,8 @@ import java.util.List;
21 21
 import java.util.Optional;
22 22
 import java.util.concurrent.CompletableFuture;
23 23
 
24
+import org.slf4j.Logger;
25
+import org.slf4j.LoggerFactory;
24 26
 import org.vertx.java.core.Vertx;
25 27
 
26 28
 import net.bluemind.backend.cyrus.replication.server.utils.ReplicatedBoxes.ReplicatedBox;
... ...
@@ -35,6 +37,8 @@ import net.bluemind.eclipse.common.RunnableExtensionLoader;
35 37
 
36 38
 public interface StorageApiLink {
37 39
 
40
+	public static final Logger logger = LoggerFactory.getLogger(StorageApiLink.class);
41
+
38 42
 	public static class ApiDesc {
39 43
 
40 44
 		IDbReplicatedMailboxesPromise mboxApi;
... ...
@@ -58,11 +62,10 @@ public interface StorageApiLink {
58 62
 		List<StorageLinkFactory> factories = rel.loadExtensionsWithPriority(
59 63
 				"net.bluemind.backend.cyrus.replication.server", "storage", "storage", "factory");
60 64
 		Optional<StorageLinkFactory> factory = factories.stream().filter(link -> link.isAvailable()).findFirst();
61
-		if (factory.isPresent()) {
62
-			return factory.get().newLink(vertx, http, remoteIp);
63
-		} else {
64
-			throw ReplicationException.serverError("No StorageApiLink usable implementation found.");
65
-		}
65
+		return factory.map(f -> {
66
+			logger.info("Selected {}", f);
67
+			return f.newLink(vertx, http, remoteIp);
68
+		}).orElseThrow(() -> ReplicationException.serverError("No StorageApiLink usable implementation found."));
66 69
 	}
67 70
 
68 71
 	public CompletableFuture<IDbMessageBodiesPromise> bodies(String partition);
... ...
@@ -27,7 +27,6 @@ Require-Bundle: org.apache.commons.codec;bundle-version="1.3.0",
27 27
  net.bluemind.core.rest.http,
28 28
  net.bluemind.authentication.api,
29 29
  net.bluemind.config,
30
- net.bluemind.locator.client,
31 30
  net.bluemind.todolist.api,
32 31
  net.bluemind.addressbook.api,
33 32
  net.bluemind.calendar.api,
... ...
@@ -48,7 +47,8 @@ Require-Bundle: org.apache.commons.codec;bundle-version="1.3.0",
48 47
  net.bluemind.backend.cyrus.partitions,
49 48
  net.bluemind.backend.mail.replica.api,
50 49
  net.bluemind.common.io;bundle-version="4.1.0",
51
- net.bluemind.eas.utils
50
+ net.bluemind.eas.utils,
51
+ net.bluemind.network.topology
52 52
 Export-Package: net.bluemind.eas.backend.bm.contacts,
53 53
  net.bluemind.eas.backend.bm.mail,
54 54
  net.bluemind.eas.backend.bm.user
... ...
@@ -44,7 +44,7 @@ import net.bluemind.eas.store.ISyncStorage;
44 44
 import net.bluemind.hornetq.client.Consumer;
45 45
 import net.bluemind.hornetq.client.MQ;
46 46
 import net.bluemind.hornetq.client.Topic;
47
-import net.bluemind.locator.client.LocatorClient;
47
+import net.bluemind.network.topology.Topology;
48 48
 import net.bluemind.vertx.common.http.BasicAuthHandler;
49 49
 
50 50
 public class BMBackend implements IBackend {
... ...
@@ -170,8 +170,7 @@ public class BMBackend implements IBackend {
170 170
 		logger.debug("Set internal state");
171 171
 
172 172
 		InternalState is = new InternalState();
173
-		LocatorClient lc = new LocatorClient();
174
-		is.coreUrl = "http://" + lc.locateHost("bm/core", bs.getLoginAtDomain()) + ":8090";
173
+		is.coreUrl = "http://" + Topology.get().core().value.address() + ":8090";
175 174
 		is.sid = bs.getSid();
176 175
 
177 176
 		bs.setInternalState(is);
... ...
@@ -44,9 +44,9 @@ import net.bluemind.domain.api.IDomains;
44 44
 import net.bluemind.eas.dto.device.DeviceValidationRequest;
45 45
 import net.bluemind.eas.dto.device.DeviceValidationResponse;
46 46
 import net.bluemind.eas.partnership.IDevicePartnershipProvider;
47
-import net.bluemind.locator.client.LocatorClient;
48 47
 import net.bluemind.metrics.registry.IdFactory;
49 48
 import net.bluemind.metrics.registry.MetricsRegistry;
49
+import net.bluemind.network.topology.Topology;
50 50
 import net.bluemind.system.api.ISystemConfiguration;
51 51
 import net.bluemind.system.api.SystemConf;
52 52
 import net.bluemind.user.api.IUser;
... ...
@@ -161,11 +161,7 @@ public class PartnershipProvider implements IDevicePartnershipProvider {
161 161
 
162 162
 	private String locateCore() {
163 163
 		if (coreUrl == null) {
164
-			LocatorClient lc = new LocatorClient();
165
-			String l = lc.locateHost("bm/core", "admin0@global.virt");
166
-			if (l != null) {
167
-				coreUrl = "http://" + l + ":8090";
168
-			}
164
+			coreUrl = "http://" + Topology.get().core().value.address() + ":8090";
169 165
 		}
170 166
 		return coreUrl;
171 167
 	}
... ...
@@ -39,8 +39,8 @@ import net.bluemind.eas.backend.BackendSession;
39 39
 import net.bluemind.eas.backend.bm.impl.CoreConnect;
40 40
 import net.bluemind.eas.dto.user.MSUser;
41 41
 import net.bluemind.eas.exception.ActiveSyncException;
42
-import net.bluemind.locator.client.LocatorClient;
43 42
 import net.bluemind.mailbox.api.Mailbox.Routing;
43
+import net.bluemind.network.topology.Topology;
44 44
 import net.bluemind.user.api.IUser;
45 45
 import net.bluemind.user.api.IUserSettings;
46 46
 import net.bluemind.user.api.User;
... ...
@@ -71,8 +71,7 @@ public class UserBackend extends CoreConnect {
71 71
 		String login = latd.next();
72 72
 		String domain = latd.next();
73 73
 		try {
74
-			LocatorClient lc = new LocatorClient();
75
-			String core = "http://" + lc.locateHost("bm/core", loginAtDomain) + ":8090";
74
+			String core = "http://" + Topology.get().core().value.address() + ":8090";
76 75
 
77 76
 			// BM-8155
78 77
 			IDomains domainsService = getService(core, Token.admin0(), IDomains.class);
... ...
@@ -87,7 +87,7 @@ public class OPClient {
87 87
 
88 88
 	private AsyncHttpClient createHttpClient() {
89 89
 		AsyncHttpClientConfig config = new AsyncHttpClientConfig.Builder().setFollowRedirect(false).setMaxRedirects(0)
90
-				.setMaxRequestRetry(0).setRequestTimeout(60000).setAllowPoolingConnections(false).build();
90
+				.setMaxRequestRetry(0).setRequestTimeout(180000).setAllowPoolingConnections(false).build();
91 91
 		return new AsyncHttpClient(config);
92 92
 	}
93 93
 
... ...
@@ -220,7 +220,7 @@ public class OPClient {
220 220
 		byte[] data = WBXMLTools.toWbxml(namespace, doc);
221 221
 		String url = ai.getUrl() + "?User=" + ai.getLogin() + "&DeviceId=" + ai.getDevId() + "&DeviceType="
222 222
 				+ ai.getDevType() + "&Cmd=" + cmd;
223
-
223
+		logger.info("Posting to {}", url);
224 224
 		BoundRequestBuilder pm = ahc.preparePost(url);
225 225
 
226 226
 		pm.setBody(data);
... ...
@@ -70,14 +70,11 @@ public class FolderSyncProtocol implements IEasProtocol<FolderSyncRequest, Folde
70 70
 
71 71
 	@Override
72 72
 	public void execute(BackendSession bs, FolderSyncRequest query, Handler<FolderSyncResponse> responseHandler) {
73
-		if (logger.isDebugEnabled()) {
74
-			logger.debug("******** Executing *******");
75
-		}
76
-
77 73
 		if (query == null) {
78 74
 			responseHandler.handle(null);
79 75
 			return;
80 76
 		}
77
+		logger.info("FolderSync from {}", query.syncKey);
81 78
 
82 79
 		FolderSyncResponse response = new FolderSyncResponse();
83 80
 
... ...
@@ -18,6 +18,10 @@
18 18
  */
19 19
 package net.bluemind.eas.protocol;
20 20
 
21
+import java.util.concurrent.CompletableFuture;
22
+import java.util.concurrent.ExecutorService;
23
+import java.util.concurrent.Executors;
24
+
21 25
 import org.slf4j.Logger;
22 26
 import org.slf4j.LoggerFactory;
23 27
 import org.slf4j.MDC;
... ...
@@ -35,6 +39,7 @@ import net.bluemind.eas.http.AuthorizedDeviceQuery;
35 39
 import net.bluemind.eas.impl.vertx.compat.SessionWrapper;
36 40
 import net.bluemind.eas.impl.vertx.compat.VertxResponder;
37 41
 import net.bluemind.eas.protocol.impl.ExecutionPayload;
42
+import net.bluemind.lib.vertx.BlockingCode;
38 43
 import net.bluemind.lib.vertx.VertxPlatform;
39 44
 import net.bluemind.vertx.common.LocalJsonObject;
40 45
 
... ...
@@ -43,20 +48,34 @@ public final class ProtocolExecutor {
43 48
 	private static final Logger logger = LoggerFactory.getLogger(ProtocolExecutor.class);
44 49
 	private static final EventBus eb = VertxPlatform.eventBus();
45 50
 
51
+	private static final ExecutorService backendInit = Executors.newFixedThreadPool(4);
52
+
46 53
 	public static <Q, R> void run(AuthorizedDeviceQuery query, Document document, final IEasProtocol<Q, R> protocol) {
47 54
 		if (logger.isDebugEnabled()) {
48 55
 			logger.debug("[{}] Running protocol {}", query.loginAtDomain(), protocol);
49 56
 		}
50 57
 		query.request().pause();
51
-		BackendSession bs = SessionWrapper.wrap(query);
52
-		RequestDTOHandler<Q, R> requestHandler = new RequestDTOHandler<Q, R>(bs, query, protocol);
53
-		try {
54
-			protocol.parse(query.optionalParams(), document, bs, requestHandler);
55
-		} catch (Exception e) {
56
-			logger.error(e.getMessage(), e);
57
-			HttpServerResponse resp = query.request().response();
58
-			resp.setStatusCode(500).setStatusMessage(String.format("Throwable: %s", e.getMessage())).end();
59
-		}
58
+		CompletableFuture<BackendSession> futureSession = BlockingCode.forVertx(query.vertx()).withExecutor(backendInit)
59
+				.run(() -> SessionWrapper.wrap(query));
60
+		futureSession.whenComplete((bs, e) -> {
61
+			if (e != null) {
62
+				errorOut(query, e);
63
+			} else {
64
+				RequestDTOHandler<Q, R> requestHandler = new RequestDTOHandler<Q, R>(bs, query, protocol);
65
+				try {
66
+					protocol.parse(query.optionalParams(), document, bs, requestHandler);
67
+				} catch (Exception ex) {
68
+					errorOut(query, ex);
69
+				}
70
+			}
71
+		});
72
+	}
73
+
74
+	private static void errorOut(AuthorizedDeviceQuery query, Throwable e) {
75
+		logger.error(e.getMessage(), e);
76
+		query.request().resume();
77
+		HttpServerResponse resp = query.request().response();
78
+		resp.setStatusCode(500).setStatusMessage(String.format("Throwable: %s", e.getMessage())).end();
60 79
 	}
61 80
 
62 81
 	private static class RequestDTOHandler<Q, R> implements Handler<Q> {