Browse code

[perf] BM-14925 BM-14970 Fix: push message infos from lmtp indexing plugin to hazelcast to speed up the mail notifications process

Thomas Cataldo authored on 24/06/2019 15:14:22
Showing 19 changed files
... ...
@@ -61,6 +61,7 @@
61 61
       <plugin id="net.bluemind.calendar.helper"/>
62 62
       <plugin id="net.bluemind.calendar.occurrence"/>
63 63
       <plugin id="net.bluemind.common.freemarker"/>
64
+      <plugin id="net.bluemind.common.io"/>
64 65
       <plugin id="net.bluemind.common.reflect"/>
65 66
       <plugin id="net.bluemind.config"/>
66 67
       <plugin id="net.bluemind.core.commons"/>
... ...
@@ -122,7 +122,9 @@ public class MailIndexService implements IMailIndexService {
122 122
 			bulkOp.add(client.prepareIndex(getIndexAliasName(mdoc.destination.owner), MUTABLE_DOC_TYPE)
123 123
 					.setSource(mutableContent).setId(id).setParent(bodyId));
124 124
 
125
-			logger.info("append {} in {}", mdoc.id, mdoc.destination.name);
125
+			if (logger.isDebugEnabled()) {
126
+				logger.debug("append {} in {}", mdoc.id, mdoc.destination.name);
127
+			}
126 128
 		}
127 129
 
128 130
 		bulkOp.execute().actionGet();
... ...
@@ -8,7 +8,6 @@ Bundle-Vendor: blue-mind.net
8 8
 Require-Bundle: org.eclipse.core.runtime,
9 9
  net.bluemind.slf4j;bundle-version="1.0.0",
10 10
  net.bluemind.hornetq.client;bundle-version="1.0.0",
11
- net.bluemind.core.mq.bridge;bundle-version="1.0.0",
12 11
  net.bluemind.lib.elasticsearch;bundle-version="1.0.0",
13 12
  net.bluemind.lib.vertx;bundle-version="1.0.0",
14 13
  net.bluemind.user.api;bundle-version="1.0.0",
... ...
@@ -18,3 +17,4 @@ Require-Bundle: org.eclipse.core.runtime,
18 17
  net.bluemind.core.container.api;bundle-version="1.0.0"
19 18
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
20 19
 Bundle-ActivationPolicy: lazy
20
+Automatic-Module-Name: net.bluemind.core.mq.newmail
... ...
@@ -2,12 +2,6 @@
2 2
 <?eclipse version="3.4"?>
3 3
 <plugin>
4 4
    <extension
5
-         point="net.bluemind.core.mq.bridge.forwarder">
6
-      <forwarder
7
-            impl="net.bluemind.core.mq.newmail.OnNewMailHandler">
8
-      </forwarder>
9
-   </extension>
10
-   <extension
11 5
          point="net.bluemind.core.rest.eventBusAccessRule">
12 6
       <access-rule
13 7
             class="net.bluemind.core.mq.newmail.SessionMailsNotifRuleAccess">
... ...
@@ -3,6 +3,9 @@ package net.bluemind.core.mq.newmail;
3 3
 import org.osgi.framework.BundleActivator;
4 4
 import org.osgi.framework.BundleContext;
5 5
 
6
+import net.bluemind.hornetq.client.MQ;
7
+import net.bluemind.hornetq.client.Topic;
8
+
6 9
 public class Activator implements BundleActivator {
7 10
 
8 11
 	private static BundleContext context;
... ...
@@ -19,6 +22,7 @@ public class Activator implements BundleActivator {
19 22
 	 */
20 23
 	public void start(BundleContext bundleContext) throws Exception {
21 24
 		Activator.context = bundleContext;
25
+		MQ.init(() -> MQ.registerConsumer(Topic.MAIL_NOTIFICATIONS, new OnNewMailHandler()));
22 26
 	}
23 27
 
24 28
 	/*
... ...
@@ -1,102 +1,36 @@
1 1
 package net.bluemind.core.mq.newmail;
2 2
 
3
-import org.elasticsearch.action.search.SearchResponse;
4
-import org.elasticsearch.client.Client;
5
-import org.elasticsearch.index.query.IdsQueryBuilder;
6
-import org.elasticsearch.index.query.QueryBuilders;
7
-import org.elasticsearch.search.SearchHit;
8
-import org.elasticsearch.search.SearchHits;
9 3
 import org.slf4j.Logger;
10 4
 import org.slf4j.LoggerFactory;
11
-import org.vertx.java.core.eventbus.EventBus;
12 5
 import org.vertx.java.core.json.JsonObject;
13 6
 
14
-import net.bluemind.core.container.model.ItemValue;
15
-import net.bluemind.core.context.SecurityContext;
16
-import net.bluemind.core.mq.bridge.IMQForwarder;
17
-import net.bluemind.core.rest.ServerSideServiceProvider;
18
-import net.bluemind.folder.api.Folder;
19 7
 import net.bluemind.hornetq.client.OOPMessage;
20
-import net.bluemind.hornetq.client.Topic;
21
-import net.bluemind.lib.elasticsearch.ESearchActivator;
22
-import net.bluemind.mailbox.api.IMailboxFolderHierarchy;
23
-import net.bluemind.user.api.User;
8
+import net.bluemind.hornetq.client.OutOfProcessMessageHandler;
9
+import net.bluemind.lib.vertx.VertxPlatform;
24 10
 
25
-public final class OnNewMailHandler implements IMQForwarder {
11
+public final class OnNewMailHandler implements OutOfProcessMessageHandler {
26 12
 
27 13
 	private static final Logger logger = LoggerFactory.getLogger(OnNewMailHandler.class);
28 14
 
29 15
 	@Override
30
-	public String getLoginAtDomain(OOPMessage m) {
31
-		String mbox = m.getStringProperty("mailbox");
32
-		if (mbox.startsWith("+")) {
33
-			return null; // a mailshare
34
-		}
35
-		return mbox;
36
-	}
37
-
38
-	@Override
39
-	public void forward(EventBus eb, ItemValue<User> user, String queue, OOPMessage m) {
16
+	public void handle(OOPMessage m) {
40 17
 		if (!"inbox".equalsIgnoreCase(m.getStringProperty("imapFolder"))) {
41
-			logger.debug("Not for inbox");
42 18
 			return;
43 19
 		}
44
-		try {
45
-			ServerSideServiceProvider p = ServerSideServiceProvider.getProvider(SecurityContext.SYSTEM);
46
-			IMailboxFolderHierarchy folders = p.instance(IMailboxFolderHierarchy.class, user.uid);
47
-
48
-			ItemValue<Folder> folder = folders.byPath(m.getStringProperty("imapFolder"));
49
-			Integer imapUid = m.getIntProperty("imapUid");
50
-			String esId = folder.value.uid + ":" + m.getIntProperty("imapUid");
51
-
52
-			Client cli = ESearchActivator.getClient();
53
-			IdsQueryBuilder idQuery = QueryBuilders.idsQuery("msg").addIds(esId);
54
-			SearchResponse data = cli.prepareSearch("mailspool_alias_" + user.uid).addFields("from", "headers.subject")
55
-					.setFetchSource(false).setQuery(idQuery).execute().actionGet();
56
-			SearchHits hits = data.getHits();
57
-			if (hits.getTotalHits() > 0) {
58
-				SearchHit theHit = hits.getAt(0);
59
-				String from = getFrom(theHit);
60
-				String subject = getSubject(theHit);
61
-				JsonObject jso = new JsonObject();
62
-				jso.putString("title", from);
63
-				jso.putString("body", subject);
64
-				jso.putString("uid", Integer.toString(imapUid));
65
-				eb.send(queue + ".notifications.mails", jso);
66
-				logger.debug("[{}] {} {}", getLoginAtDomain(m), esId, jso.encode());
67
-			} else {
68
-				logger.error("Invalid hit count: " + hits.getTotalHits() + " for {}", esId);
69
-			}
70
-		} catch (Exception e) {
71
-			logger.error("error during forwarding mail event", e);
72
-		}
73
-	}
74
-
75
-	private String getSubject(SearchHit theHit) {
76
-		if (!theHit.getFields().containsKey("headers.subject")) {
77
-			return "";
78
-		}
79
-		String ret = theHit.getFields().get("headers.subject").getValue();
80
-		if (ret == null) {
81
-			ret = "";
82
-		}
83
-		return ret;
84
-	}
85
-
86
-	private String getFrom(SearchHit theHit) {
87
-		if (!theHit.getFields().containsKey("from")) {
88
-			return "";
20
+		if (m.getStringProperty("mailbox").startsWith("+")) {
21
+			return;
89 22
 		}
90
-		String ret = theHit.getFields().get("from").getValue();
91
-		if (ret == null) {
92
-			ret = "";
23
+		String mboxUid = m.getStringProperty("mailboxUid");
24
+		if (mboxUid == null) {
25
+			return;
93 26
 		}
94
-		return ret;
95
-	}
96
-
97
-	@Override
98
-	public String consumedQueue() {
99
-		return Topic.MAIL_NOTIFICATIONS;
27
+		JsonObject jso = new JsonObject();
28
+		jso.putString("title", m.getStringProperty("from"));
29
+		jso.putString("body", m.getStringProperty("subject"));
30
+		Integer imapUid = m.getIntProperty("imapUid");
31
+		jso.putString("uid", Integer.toString(imapUid));
32
+		logger.info("[{}] Publish mail notification for uid {}", mboxUid, imapUid);
33
+		VertxPlatform.eventBus().send(mboxUid + ".notifications.mails", jso);
100 34
 	}
101 35
 
102 36
 }
... ...
@@ -25,7 +25,7 @@ public class SessionMailsNotifRuleAccess implements IEventBusAccessRule {
25 25
 
26 26
 	@Override
27 27
 	public boolean match(String path) {
28
-		if (path.startsWith("client.session.") && path.endsWith(".notifications.mails")) {
28
+		if (path.endsWith(".notifications.mails")) {
29 29
 			return true;
30 30
 		} else {
31 31
 			return false;
... ...
@@ -34,9 +34,7 @@ public class SessionMailsNotifRuleAccess implements IEventBusAccessRule {
34 34
 
35 35
 	@Override
36 36
 	public boolean authorize(BmContext context, String path) {
37
-		String sessesionId = path.substring("client.session.".length(),
38
-				path.length() - ".notifications.mails".length());
39
-		if (context.getSecurityContext().getSessionId().equals(sessesionId)) {
37
+		if (path.equals(context.getSecurityContext().getSubject() + ".notifications.mails")) {
40 38
 			return true;
41 39
 		} else {
42 40
 			return false;
... ...
@@ -9,7 +9,8 @@
9 9
    <extension
10 10
          point="net.bluemind.lmtp.deliverydoneaction">
11 11
       <action
12
-            implementation="net.bluemind.lmtp.filter.fakeindexing.IndexOnDeliveryAction">
12
+            implementation="net.bluemind.lmtp.filter.fakeindexing.IndexOnDeliveryAction"
13
+            priority="0">
13 14
       </action>
14 15
    </extension>
15 16
 
... ...
@@ -42,9 +42,4 @@ public class IndexOnDeliveryAction implements IDeliveryDoneAction {
42 42
 		}
43 43
 	}
44 44
 
45
-	@Override
46
-	public int getPriority() {
47
-		return 0;
48
-	}
49
-
50 45
 }
... ...
@@ -9,7 +9,8 @@
9 9
    <extension
10 10
          point="net.bluemind.lmtp.deliverydoneaction">
11 11
       <action
12
-            implementation="net.bluemind.lmtp.filter.indexing.IndexOnDeliveryAction">
12
+            implementation="net.bluemind.lmtp.filter.indexing.IndexOnDeliveryAction"
13
+            priority="500">
13 14
       </action>
14 15
    </extension>
15 16
 
... ...
@@ -22,6 +22,7 @@ import java.util.ArrayList;
22 22
 import java.util.Date;
23 23
 import java.util.HashSet;
24 24
 import java.util.List;
25
+import java.util.Optional;
25 26
 import java.util.Set;
26 27
 import java.util.concurrent.TimeUnit;
27 28
 
... ...
@@ -91,24 +92,31 @@ public class IndexOnDeliveryAction implements IDeliveryDoneAction {
91 92
 		}
92 93
 
93 94
 		Doc doc = new MailIndexer().prepareDoc(pending.getMessage(), new Date(), pending.getMessageSize());
94
-
95
+		String subject = Optional.ofNullable(pending.getMessage().getSubject()).orElse("(no subject)");
96
+		String from = "Unknown Sender";
97
+		if (doc.getValues().containsKey("from")) {
98
+			from = (String) doc.getValues().get("from");
99
+		}
95 100
 		List<MailDoc> mailDocs = new ArrayList<>(pending.getVersions().size());
96 101
 		for (DeliveredVersion dv : pending.getVersions()) {
97 102
 			try {
98 103
 				String mailbox = boxToUid(dv.getMbox());
104
+				dv.putMetaData("mailboxUid", mailbox);
99 105
 				IMailboxFolderHierarchy fhApi = ClientSideServiceProvider.getProvider(locateCore(), Token.admin0())
100 106
 						.instance(IMailboxFolderHierarchy.class, mailbox);
101 107
 				String imapFolder = UTF7Converter.decode(dv.getImapFolder());
102 108
 				ItemValue<Folder> folder = fhApi.byPath(imapFolder);
103 109
 				MailDoc mailDoc = Activator.getMailIndex().asMailDoc(folder.value, dv.getImapUid(), doc, new Date(),
104 110
 						pending.getMessageSize(), expandFlags(dv.getFlags()));
111
+				dv.putMetaData("subject", subject);
112
+				dv.putMetaData("from", from);
105 113
 				mailDocs.add(mailDoc);
106 114
 			} catch (Exception e) {
107 115
 				logger.error(e.getMessage(), e);
108 116
 			}
109 117
 		}
110 118
 
111
-		MailIndexActivator.getService().append(mailDocs, true);
119
+		MailIndexActivator.getService().append(mailDocs, false);
112 120
 		IndexingFilter.deliveryFinished(env.getId());
113 121
 	}
114 122
 
... ...
@@ -164,11 +172,6 @@ public class IndexOnDeliveryAction implements IDeliveryDoneAction {
164 172
 		return box;
165 173
 	}
166 174
 
167
-	@Override
168
-	public int getPriority() {
169
-		return 0;
170
-	}
171
-
172 175
 	/**
173 176
 	 * @return
174 177
 	 */
... ...
@@ -4,7 +4,8 @@
4 4
    <extension
5 5
          point="net.bluemind.lmtp.deliverydoneaction">
6 6
       <action
7
-            implementation="net.bluemind.lmtp.notification.QueueNotificationOnDelivery">
7
+            implementation="net.bluemind.lmtp.notification.QueueNotificationOnDelivery"
8
+            priority="400">
8 9
       </action>
9 10
    </extension>
10 11
 
... ...
@@ -18,7 +18,7 @@
18 18
  */
19 19
 package net.bluemind.lmtp.notification;
20 20
 
21
-import java.util.concurrent.ConcurrentLinkedDeque;
21
+import java.util.Optional;
22 22
 
23 23
 import org.slf4j.Logger;
24 24
 import org.slf4j.LoggerFactory;
... ...
@@ -29,51 +29,51 @@ import net.bluemind.hornetq.client.Producer;
29 29
 import net.bluemind.hornetq.client.Topic;
30 30
 import net.bluemind.lmtp.backend.DeliveredVersion;
31 31
 import net.bluemind.lmtp.backend.IDeliveryDoneAction;
32
+import net.bluemind.lmtp.backend.LmtpAddress;
32 33
 import net.bluemind.lmtp.backend.LmtpEnvelope;
34
+import net.bluemind.lmtp.backend.LmtpReply;
33 35
 
34 36
 public class QueueNotificationOnDelivery implements IDeliveryDoneAction {
35 37
 
36 38
 	private static final Logger logger = LoggerFactory.getLogger(QueueNotificationOnDelivery.class);
37 39
 
38
-	private final ConcurrentLinkedDeque<OOPMessage> messages;
39
-
40 40
 	public QueueNotificationOnDelivery() {
41
-		messages = new ConcurrentLinkedDeque<>();
42 41
 	}
43 42
 
44 43
 	@Override
45 44
 	public void newMessageDelivered(LmtpEnvelope env, DeliveredVersion dv, String email) {
46
-		Producer producer = MQ.getProducer(Topic.MAIL_NOTIFICATIONS);
47
-		if (producer != null && dv != null) {
48
-			OOPMessage msg = MQ.newMessage();
49
-			msg.putStringProperty("mailbox", email);
50
-			msg.putStringProperty("imapFolder", dv.getImapFolder() != null ? dv.getImapFolder() : "INBOX");
51
-			msg.putIntProperty("imapUid", dv.getImapUid());
52
-			messages.add(msg);
53
-			logger.info("[{}] Queued notification. (this: {})", email, this);
54
-		} else {
55
-			logger.error("failed to create producer. producer: {}, dv: {}. (this: {})", producer, dv, this);
56
-		}
57 45
 	}
58 46
 
59 47
 	@Override
60 48
 	public void deliveryFinished(LmtpEnvelope mEnvelope) {
61
-		OOPMessage qm = messages.poll();
62
-		if (qm == null) {
63
-			logger.warn("Message queue is empty. 0 notification will be sent to queue. (this: {})", this);
64
-		} else {
65
-			int i = 0;
66
-			while (qm != null) {
67
-				MQ.getProducer(Topic.MAIL_NOTIFICATIONS).send(qm);
49
+		Producer producer = MQ.getProducer(Topic.MAIL_NOTIFICATIONS);
50
+		if (producer == null) {
51
+			logger.warn("Producer is missing, not notifying for {}", mEnvelope);
52
+			return;
53
+		}
54
+
55
+		int i = 0;
56
+		for (LmtpAddress recipient : mEnvelope.getRecipients()) {
57
+			LmtpReply reply = recipient.getDeliveryStatus();
58
+			if (reply.success()) {
59
+				DeliveredVersion dv = recipient.getDeliveredVersion();
60
+				OOPMessage msg = MQ.newMessage();
61
+				msg.putStringProperty("mailbox", recipient.getEmailAddress());
62
+				msg.putStringProperty("imapFolder", dv.getImapFolder() != null ? dv.getImapFolder() : "INBOX");
63
+				msg.putIntProperty("imapUid", dv.getImapUid());
64
+				// those props are added by the indexing plugin, which has a bigger priority
65
+				// than this one
66
+				Optional.ofNullable(dv.getMetaData("mailboxUid"))
67
+						.ifPresent(v -> msg.putStringProperty("mailboxUid", v));
68
+				Optional.ofNullable(dv.getMetaData("subject")).ifPresent(v -> msg.putStringProperty("subject", v));
69
+				Optional.ofNullable(dv.getMetaData("from")).ifPresent(v -> msg.putStringProperty("from", v));
70
+
71
+				producer.send(msg);
68 72
 				i++;
69
-				qm = messages.poll();
70 73
 			}
71
-			logger.info("{} notification(s) sent to queue. (this: {})", i, this);
72 74
 		}
73
-	}
75
+		logger.info("{} notification(s) sent to queue.", i);
74 76
 
75
-	@Override
76
-	public int getPriority() {
77
-		return Integer.MAX_VALUE;
78 77
 	}
78
+
79 79
 }
... ...
@@ -59,6 +59,13 @@
59 59
                </appinfo>
60 60
             </annotation>
61 61
          </attribute>
62
+         <attribute name="priority" type="string">
63
+            <annotation>
64
+               <documentation>
65
+                  
66
+               </documentation>
67
+            </annotation>
68
+         </attribute>
62 69
       </complexType>
63 70
    </element>
64 71
 
... ...
@@ -58,8 +58,7 @@ public class Activator extends Plugin {
58 58
 	/*
59 59
 	 * (non-Javadoc)
60 60
 	 * 
61
-	 * @see
62
-	 * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
61
+	 * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
63 62
 	 */
64 63
 	@Override
65 64
 	public void start(BundleContext context) throws Exception {
... ...
@@ -74,16 +73,10 @@ public class Activator extends Plugin {
74 73
 
75 74
 	private List<IDeliveryDoneAction> getDeliveryDoneExtensions() {
76 75
 		RunnableExtensionLoader<IDeliveryDoneAction> rel = new RunnableExtensionLoader<IDeliveryDoneAction>();
77
-		List<IDeliveryDoneAction> theList = rel.loadExtensions(PLUGIN_ID, "deliverydoneaction", "action",
78
-				"implementation");
79
-		Collections.sort(theList, new Comparator<IDeliveryDoneAction>() {
80
-
81
-			@Override
82
-			public int compare(IDeliveryDoneAction o1, IDeliveryDoneAction o2) {
83
-				return new Integer(o1.getPriority()).compareTo(new Integer(o2.getPriority()));
84
-			}
85
-		});
86
-		return theList;
76
+		List<IDeliveryDoneAction> orderedActions = rel.loadExtensionsWithPriority(PLUGIN_ID, "deliverydoneaction",
77
+				"action", "implementation");
78
+		logger.info("Delivery actions: {}", orderedActions);
79
+		return orderedActions;
87 80
 	}
88 81
 
89 82
 	public List<IDeliveryDoneAction> getDeliveryDoneActions() {
... ...
@@ -122,8 +115,7 @@ public class Activator extends Plugin {
122 115
 	/*
123 116
 	 * (non-Javadoc)
124 117
 	 * 
125
-	 * @see
126
-	 * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
118
+	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
127 119
 	 */
128 120
 	@Override
129 121
 	public void stop(BundleContext context) throws Exception {
... ...
@@ -18,8 +18,12 @@
18 18
  */
19 19
 package net.bluemind.lmtp.backend;
20 20
 
21
+import java.util.HashMap;
22
+import java.util.Map;
21 23
 import java.util.Set;
22 24
 
25
+import com.google.common.base.MoreObjects;
26
+
23 27
 /**
24 28
  * Holds informations about were in email was delivered, taking filters into
25 29
  * account.
... ...
@@ -31,12 +35,14 @@ public class DeliveredVersion {
31 35
 	private final String imapFolder;
32 36
 	private final int imapUid;
33 37
 	private final Set<String> flags;
38
+	private final Map<String, String> meta;
34 39
 
35 40
 	public DeliveredVersion(String mbox, String folder, int uid, Set<String> flags) {
36 41
 		this.mbox = mbox;
37 42
 		this.imapFolder = folder != null ? folder.replace('^', '.') : null;
38 43
 		this.imapUid = uid;
39 44
 		this.flags = flags;
45
+		this.meta = new HashMap<>();
40 46
 	}
41 47
 
42 48
 	public String getImapFolder() {
... ...
@@ -55,6 +61,14 @@ public class DeliveredVersion {
55 61
 		return flags;
56 62
 	}
57 63
 
64
+	public void putMetaData(String key, String value) {
65
+		meta.put(key, value);
66
+	}
67
+
68
+	public String getMetaData(String key) {
69
+		return meta.get(key);
70
+	}
71
+
58 72
 	@Override
59 73
 	public int hashCode() {
60 74
 		final int prime = 31;
... ...
@@ -90,4 +104,13 @@ public class DeliveredVersion {
90 104
 		return true;
91 105
 	}
92 106
 
107
+	@Override
108
+	public String toString() {
109
+		return MoreObjects.toStringHelper(DeliveredVersion.class)//
110
+				.add("mbox", mbox)//
111
+				.add("imapFolder", imapFolder).add("uid", imapUid)//
112
+				.add("meta", meta)//
113
+				.toString();
114
+	}
115
+
93 116
 }
... ...
@@ -24,8 +24,6 @@ package net.bluemind.lmtp.backend;
24 24
  */
25 25
 public interface IDeliveryDoneAction {
26 26
 
27
-	int getPriority();
28
-
29 27
 	void newMessageDelivered(LmtpEnvelope env, DeliveredVersion dv, String email);
30 28
 
31 29
 	void deliveryFinished(LmtpEnvelope mEnvelope);
... ...
@@ -120,8 +120,10 @@ public class DeliveryReceipt {
120 120
 		Iterable<String> split = Splitter.on(", ").omitEmptyStrings().split(flags);
121 121
 		dr.setFlags(Lists.newLinkedList(split));
122 122
 
123
-		logger.info("[{}] folder: '{}', flags: '{}', uid: {}, mbox string {}", dr.getMbox(), folder, dr.getFlags(), uid,
124
-				mboxName);
123
+		if (logger.isDebugEnabled()) {
124
+			logger.debug("[{}] folder: '{}', flags: '{}', uid: {}, mbox string {}", dr.getMbox(), folder, dr.getFlags(),
125
+					uid, mboxName);
126
+		}
125 127
 
126 128
 		return dr;
127 129
 	}
... ...
@@ -47,6 +47,7 @@ public class PushSetup {
47 47
 	 */
48 48
 	public static void initConnection(final String queue) {
49 49
 		final String sid = getSidFromPage();
50
+		final String mailboxUid = getUidFromPage();
50 51
 		final String login = getLogin();
51 52
 
52 53
 		OnlineListener cl = new OnlineListener() {
... ...
@@ -55,7 +56,7 @@ public class PushSetup {
55 56
 
56 57
 				register(queue + ".notifications.reminders", new ReminderNotificationHandler());
57 58
 
58
-				register(queue + ".notifications.mails", new MailNotificationHandler());
59
+				register(mailboxUid + ".notifications.mails", new MailNotificationHandler());
59 60
 
60 61
 				// open session
61 62
 				JSONObject message = new JSONObject();
... ...
@@ -116,6 +117,10 @@ public class PushSetup {
116 117
 													return $wnd.bmcSessionInfos['sid'];
117 118
 													}-*/;
118 119
 
120
+	private static native String getUidFromPage() /*-{
121
+													return $wnd.bmcSessionInfos['userId'];
122
+													}-*/;
123
+
119 124
 	private static native String getLogin() /*-{
120 125
 											return $wnd.bmcSessionInfos['defaultEmail'];
121 126
 											}-*/;