use of com.zimbra.soap.admin.message.AdminWaitSetResponse in project zm-mailbox by Zimbra.
the class AdminWaitSetRequest method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
com.zimbra.soap.admin.message.AdminWaitSetRequest req = zsc.elementToJaxb(request);
AdminWaitSetResponse resp = new AdminWaitSetResponse();
WaitSetRequest.staticHandle(req, context, resp, true);
return zsc.jaxbToElement(resp);
}
use of com.zimbra.soap.admin.message.AdminWaitSetResponse in project zm-mailbox by Zimbra.
the class TestWaitSetRequest method testFolderInterestSyncAdminWaitSetRequest.
@Test
public void testFolderInterestSyncAdminWaitSetRequest() throws Exception {
String user1Name = "testFISyncAdminWaitSetRequest_user1";
String user2Name = "testFISyncAdminWaitSetRequest_user2";
acc1 = TestUtil.createAccount(user1Name);
acc2 = TestUtil.createAccount(user2Name);
ZMailbox zMbox1 = TestUtil.getZMailbox(user1Name);
ZMailbox zMbox2 = TestUtil.getZMailbox(user2Name);
Mailbox mbox1 = TestUtil.getMailbox(user1Name);
Mailbox mbox2 = TestUtil.getMailbox(user2Name);
Set<String> accountIds = new HashSet<String>();
String acct1Id = zMbox1.getAccountId();
String acct2Id = zMbox2.getAccountId();
accountIds.add(acct1Id);
String adminAuthToken = TestUtil.getAdminSoapTransport().getAuthToken().getValue();
ZFolder user1FunFolder = TestUtil.createFolder(zMbox1, "funFolder");
ZFolder user2FunFolder = TestUtil.createFolder(zMbox2, "funFolder");
ZFolder user2FunFolder2 = TestUtil.createFolder(zMbox2, "funFolder2");
Set<Integer> folderInterest = Sets.newHashSet();
folderInterest.add(user1FunFolder.getFolderIdInOwnerMailbox());
// initially only interested in user1::funFolder
AdminCreateWaitSetResponse resp = createAdminWaitSet(accountIds, adminAuthToken, false);
assertNotNull(resp);
waitSetId = resp.getWaitSetId();
int seq = resp.getSequence();
AdminWaitSetRequest waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.addUpdateAccount(createWaitSetAddSpec(acct1Id, folderInterest));
AdminWaitSetResponse wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals(0, seq);
String subject = NAME_PREFIX + " test wait set request 1";
TestUtil.addMessageLmtp(subject, user1Name, "user999@example.com");
TestUtil.waitForMessages(zMbox1, String.format("in:inbox is:unread \"%s\"", subject), 1, 1000);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
assertEquals("Number of signalled accounts", 0, wsResp.getSignalledAccounts().size());
seq = Integer.parseInt(wsResp.getSeqNo());
// now interested in user1::funFolder AND user1::inbox
folderInterest.add(Integer.valueOf(Mailbox.ID_FOLDER_INBOX));
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.addUpdateAccount(createWaitSetAddSpec(acct1Id, folderInterest));
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
// nothing happened, so should not trigger any accounts
assertEquals("Number of signalled accounts (test 1)", 0, wsResp.getSignalledAccounts().size());
seq = Integer.parseInt(wsResp.getSeqNo());
subject = NAME_PREFIX + " test wait set request 2";
TestUtil.addMessageLmtp(subject, user1Name, "user999@example.com");
TestUtil.waitForMessages(zMbox1, String.format("in:inbox is:unread \"%s\"", subject), 1, 1000);
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of signalled accounts (test 2)", 1, wsResp.getSignalledAccounts().size());
AccountWithModifications acctInfo = wsResp.getSignalledAccounts().get(0);
assertEquals("Signaled account id (should signal user1)", acct1Id, acctInfo.getId());
Collection<PendingFolderModifications> mods = acctInfo.getPendingFolderModifications();
assertNotNull("'mod' field should not be null", mods);
assertEquals("Should have 1 folder object with modifications", 1, mods.size());
Integer foldInt = mods.iterator().next().getFolderId();
assertEquals(String.format("Folder ID should be %d (Inbox). Getting %d instead", Mailbox.ID_FOLDER_INBOX, foldInt), foldInt.intValue(), Mailbox.ID_FOLDER_INBOX);
// Add message to user2 (should not trigger this waitset, because this waitset is not subscribed to user2 yet)
subject = NAME_PREFIX + " test wait set request 3";
TestUtil.addMessageLmtp(subject, user2Name, "user999@example.com");
TestUtil.waitForMessages(zMbox2, String.format("in:inbox is:unread \"%s\"", subject), 1, 1000);
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of signalled accounts (test 3)", 0, wsResp.getSignalledAccounts().size());
// subscribe to user2::funFolder2
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
folderInterest = Sets.newHashSet();
folderInterest.add(user2FunFolder2.getFolderIdInOwnerMailbox());
waitSet.addAddAccount(createWaitSetAddSpec(acct2Id, folderInterest));
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of signalled accounts (test 4)", 0, wsResp.getSignalledAccounts().size());
// Add message to user2 (should NOT trigger this waitset yet, because WaitSet is subscribed to user2:funFolder2, user1:funFolder and user1:INBOX
subject = NAME_PREFIX + " test wait set request 4";
TestUtil.addMessageLmtp(subject, user2Name, "user999@example.com");
TestUtil.waitForMessages(zMbox2, String.format("in:inbox is:unread \"%s\"", subject), 1, 1000);
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of signalled accounts (test 5)", 0, wsResp.getSignalledAccounts().size());
// add interest in user2:INBOX
folderInterest = Sets.newHashSet();
folderInterest.add(user2FunFolder2.getFolderIdInOwnerMailbox());
folderInterest.add(Integer.valueOf(Mailbox.ID_FOLDER_INBOX));
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.addUpdateAccount(createWaitSetAddSpec(acct2Id, folderInterest));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
// nothing happened, so should not trigger any accounts
assertEquals("Number of signalled accounts (test 6)", 0, wsResp.getSignalledAccounts().size());
// Add message to user2:INBOX (should trigger this WatSet now)
subject = NAME_PREFIX + " test wait set request 5";
TestUtil.addMessageLmtp(subject, user2Name, "user999@example.com");
TestUtil.waitForMessages(zMbox2, String.format("in:inbox is:unread \"%s\"", subject), 1, 1000);
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
// now user2 should be triggered
assertEquals("Number of signalled accounts (test 7)", 1, wsResp.getSignalledAccounts().size());
acctInfo = wsResp.getSignalledAccounts().get(0);
assertEquals("Signaled account id (should signal user2)", acct2Id, acctInfo.getId());
mods = acctInfo.getPendingFolderModifications();
assertNotNull("'mod' field should not be null", mods);
assertEquals("Should have 1 folder object with modifications", 1, mods.size());
foldInt = mods.iterator().next().getFolderId();
assertEquals(String.format("Folder ID should be %d (Inbox). Getting %d instead", Mailbox.ID_FOLDER_INBOX, foldInt), foldInt.intValue(), Mailbox.ID_FOLDER_INBOX);
// Add message to user1:funFolder (should trigger this WatSet)
subject = NAME_PREFIX + " test wait set request 6";
TestUtil.addMessage(mbox1, user1FunFolder.getFolderIdInOwnerMailbox(), subject, System.currentTimeMillis());
TestUtil.waitForMessages(zMbox1, String.format("in:%s is:unread \"%s\"", user1FunFolder.getName(), subject), 1, 1000);
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of signalled accounts (test 8)", 1, wsResp.getSignalledAccounts().size());
acctInfo = wsResp.getSignalledAccounts().get(0);
assertEquals("Signaled account id (should signal user1)", acct1Id, acctInfo.getId());
mods = acctInfo.getPendingFolderModifications();
assertNotNull("'mod' field should not be null", mods);
assertEquals("Should have 1 folder object with modifications", 1, mods.size());
foldInt = mods.iterator().next().getFolderId();
assertEquals(String.format("Folder ID should be %d (%s). Getting %d instead", user1FunFolder.getFolderIdInOwnerMailbox(), user1FunFolder.getName(), foldInt), foldInt.intValue(), user1FunFolder.getFolderIdInOwnerMailbox());
// Add message to user2:funFolder (should NOT trigger this WatSet, because it is subscribed to INBOX and funFolder2 on user2)
subject = NAME_PREFIX + " test wait set request 7";
TestUtil.addMessage(mbox2, user2FunFolder.getFolderIdInOwnerMailbox(), subject, System.currentTimeMillis());
TestUtil.waitForMessages(zMbox2, String.format("in:%s is:unread \"%s\"", user2FunFolder.getName(), subject), 1, 1000);
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of signalled accounts (test 9)", 0, wsResp.getSignalledAccounts().size());
// Add message to user2:funFolder2 (should trigger this WatSet)
subject = NAME_PREFIX + " test wait set request 8";
TestUtil.addMessage(mbox2, user2FunFolder2.getFolderIdInOwnerMailbox(), subject, System.currentTimeMillis());
TestUtil.waitForMessages(zMbox2, String.format("in:%s is:unread \"%s\"", user2FunFolder2.getName(), subject), 1, 1000);
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of signalled accounts (test 10)", 1, wsResp.getSignalledAccounts().size());
acctInfo = wsResp.getSignalledAccounts().get(0);
assertEquals("Signaled account id (should signal user2)", acct2Id, acctInfo.getId());
mods = acctInfo.getPendingFolderModifications();
assertNotNull("'mod' field should not be null", mods);
assertEquals("Should have 1 folder object with modifications", 1, mods.size());
foldInt = mods.iterator().next().getFolderId();
assertEquals(String.format("Folder ID should be %d (%s). Getting %d instead", user2FunFolder2.getFolderIdInOwnerMailbox(), user2FunFolder2.getName(), foldInt), user2FunFolder2.getFolderIdInOwnerMailbox(), foldInt.intValue());
// Add message to user2:funFolder2 and user1:INBOX (should trigger this WatSet)
subject = NAME_PREFIX + " test wait set request 9";
TestUtil.addMessage(mbox2, user2FunFolder2.getFolderIdInOwnerMailbox(), subject, System.currentTimeMillis());
TestUtil.waitForMessages(zMbox2, String.format("in:%s is:unread \"%s\"", user2FunFolder2.getName(), subject), 1, 1000);
subject = NAME_PREFIX + " test wait set request 10";
TestUtil.addMessageLmtp(subject, user1Name, "user999@example.com");
TestUtil.waitForMessages(zMbox1, String.format("in:inbox is:unread \"%s\"", subject), 1, 1000);
waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
waitSet.setExpand(true);
wsResp = (AdminWaitSetResponse) sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of signalled accounts (test 11)", 2, wsResp.getSignalledAccounts().size());
boolean user1Triggered = false;
boolean user2Triggered = false;
List<AccountWithModifications> accnts = wsResp.getSignalledAccounts();
for (AccountWithModifications info : accnts) {
if (info.getId().equalsIgnoreCase(acct1Id)) {
user1Triggered = true;
mods = info.getPendingFolderModifications();
PendingFolderModifications fm = ((ArrayList<PendingFolderModifications>) mods).get(0);
foldInt = fm.getFolderId();
assertNotNull("'mods' field should not be null", mods);
assertEquals("Should have 1 folder object with modifications for user1", 1, mods.size());
assertEquals(String.format("Folder ID should be %d (INBOX). Getting %d instead. Account %s", Mailbox.ID_FOLDER_INBOX, foldInt, acct1Id), Mailbox.ID_FOLDER_INBOX, foldInt.intValue());
}
if (info.getId().equalsIgnoreCase(acct2Id)) {
user2Triggered = true;
mods = info.getPendingFolderModifications();
assertNotNull("'mods' field should not be null", mods);
assertEquals("Should have 1 folder object with modifications for user2", 1, mods.size());
PendingFolderModifications fm = ((ArrayList<PendingFolderModifications>) mods).get(0);
foldInt = fm.getFolderId();
assertEquals(String.format("Folder ID should be %d (%s). Getting %d instead. Account %s", user2FunFolder2.getFolderIdInOwnerMailbox(), user2FunFolder2.getName(), foldInt, acct2Id), user2FunFolder2.getFolderIdInOwnerMailbox(), foldInt.intValue());
}
}
assertTrue("Should have signalled user2", user2Triggered);
assertTrue("Should have signalled user1", user1Triggered);
}
use of com.zimbra.soap.admin.message.AdminWaitSetResponse in project zm-mailbox by Zimbra.
the class ImapServerListener method restoreWaitSet.
private synchronized void restoreWaitSet() throws ServiceException {
ZimbraLog.imap.debug("Attempting to restore admin waitset for all registered listeners.");
if (wsID != null) {
ZimbraLog.imap.debug("Another thread has already restored waitset.");
// another thread has already restored waitset
return;
}
cancelPendingRequest();
AdminCreateWaitSetRequest req = new AdminCreateWaitSetRequest("all", false);
checkAuth();
AdminCreateWaitSetResponse resp;
resp = soapProv.invokeJaxbAsAdminWithRetry(req, server);
if (resp == null) {
throw ServiceException.FAILURE("Received null response from AdminCreateWaitSetRequest", null);
}
wsID = resp.getWaitSetId();
setWaitSetIdOnMailboxes();
lastSequence.set(resp.getSequence());
ZimbraLog.imap.debug("Created new waitset to replace lost or cancelled one. WaitSet ID: %s", wsID);
// send non-blocking synchronous WaitSetRequest. This way the caller has certainty that listeners were added on remote server
AdminWaitSetRequest waitSetReq = new AdminWaitSetRequest(wsID, lastSequence.toString());
waitSetReq.setBlock(false);
waitSetReq.setExpand(true);
Enumeration<String> accountIds = this.sessionMap.keys();
while (accountIds.hasMoreElements()) {
String accountId = accountIds.nextElement();
WaitSetAddSpec updateOrAdd = new WaitSetAddSpec();
updateOrAdd.setId(accountId);
Enumeration<Integer> folderIDs = this.sessionMap.get(accountId).keys();
while (folderIDs.hasMoreElements()) {
updateOrAdd.addFolderInterest(folderIDs.nextElement());
ZimbraLog.imap.debug("Adding account %s to waitset %s", accountId, wsID);
waitSetReq.addAddAccount(updateOrAdd);
}
}
ZimbraLog.imap.debug("Sending initial AdminWaitSetRequest. WaitSet ID: %s", wsID);
AdminWaitSetResponse wsResp = soapProv.invokeJaxbAsAdminWithRetry(waitSetReq, server);
try {
processAdminWaitSetResponse(wsResp);
} catch (Exception e) {
throw ServiceException.FAILURE("Failed to process initial AdminWaitSetResponse", e);
}
}
use of com.zimbra.soap.admin.message.AdminWaitSetResponse in project zm-mailbox by Zimbra.
the class ImapServerListener method initWaitSet.
private synchronized void initWaitSet(String accountId, boolean alreadyListening) throws ServiceException {
if (wsID == null && this.sessionMap.containsKey(accountId)) {
AdminCreateWaitSetRequest req = new AdminCreateWaitSetRequest("all", false);
checkAuth();
AdminCreateWaitSetResponse resp;
resp = soapProv.invokeJaxbAsAdminWithRetry(req, server);
if (resp == null) {
throw ServiceException.FAILURE("Received null response from AdminCreateWaitSetRequest", null);
}
wsID = resp.getWaitSetId();
setWaitSetIdOnMailboxes();
lastSequence.set(resp.getSequence());
} else {
cancelPendingRequest();
}
ZimbraLog.imap.debug("Current waitset ID is %s", wsID);
// send non-blocking synchronous WaitSetRequest. This way the caller has certainty that listener was added on remote server
AdminWaitSetRequest waitSetReq = new AdminWaitSetRequest(wsID, lastSequence.toString());
waitSetReq.setBlock(false);
waitSetReq.setExpand(true);
if (!this.sessionMap.containsKey(accountId) || this.sessionMap.get(accountId).isEmpty()) {
ZimbraLog.imap.debug("Removing accout %s from waitset %s", accountId, wsID);
waitSetReq.addRemoveAccount(new Id(accountId));
} else {
WaitSetAddSpec updateOrAdd = new WaitSetAddSpec();
updateOrAdd.setId(accountId);
Enumeration<Integer> folderIDs = this.sessionMap.get(accountId).keys();
while (folderIDs.hasMoreElements()) {
updateOrAdd.addFolderInterest(folderIDs.nextElement());
}
if (alreadyListening) {
ZimbraLog.imap.debug("Updating folder interests for account %s in waitset %s", accountId, wsID);
waitSetReq.addUpdateAccount(updateOrAdd);
} else {
ZimbraLog.imap.debug("Adding account %s to waitset %s", accountId, wsID);
waitSetReq.addAddAccount(updateOrAdd);
}
}
try {
ZimbraLog.imap.debug("Sending initial AdminWaitSetRequest. WaitSet ID: %s", wsID);
AdminWaitSetResponse wsResp = soapProv.invokeJaxbAsAdminWithRetry(waitSetReq, server);
processAdminWaitSetResponse(wsResp);
} catch (SoapFaultException e) {
if (AdminServiceException.NO_SUCH_WAITSET.equalsIgnoreCase(e.getCode())) {
// waitset is gone. Create a new one
ZimbraLog.imap.warn("AdminWaitSet %s does not exist anymore", wsID);
wsID = null;
unsetWaitSetIdOnMailboxes();
lastSequence.set(0);
restoreWaitSet();
} else {
throw ServiceException.FAILURE("Failed to process initial AdminWaitSetResponse", e);
}
} catch (Exception e) {
throw ServiceException.FAILURE("Failed to process initial AdminWaitSetResponse", e);
}
}
use of com.zimbra.soap.admin.message.AdminWaitSetResponse in project zm-mailbox by Zimbra.
the class TestWaitSetRequest method adminWSfolderInterestChanges.
/**
* Test that can change the info on which folders we're interested in several times.
* Introduced for ZCS-2220 although discovered that shouldn't need ADMIN SOAP sessions
* for IMAP AdminWaitSet code, so counting them is a bit redundant. Kept test
* as some assurance that lots of folder interest changes works OK.
*/
@Test
public void adminWSfolderInterestChanges() throws Exception {
int numFolders = LC.zimbra_session_limit_admin.intValue() + 15;
String user1Name = testInfo.getMethodName().toLowerCase() + "user1";
acc1 = TestUtil.createAccount(user1Name);
ZMailbox zMbox1 = TestUtil.getZMailbox(user1Name);
Set<String> accountIds = new HashSet<String>();
String acct1Id = zMbox1.getAccountId();
accountIds.add(acct1Id);
String adminAuthToken = TestUtil.getAdminSoapTransport().getAuthToken().getValue();
List<ZFolder> folders = new ArrayList<>(numFolders);
for (int fnum = 1; fnum <= numFolders; fnum++) {
folders.add(TestUtil.createFolder(zMbox1, String.format("FOLDER_%s", fnum)));
}
int numSess = countActiveSessionsForAdmin();
SessionCache.getAllSessions(acct1Id);
AdminCreateWaitSetResponse resp = createAdminWaitSet(accountIds, adminAuthToken, false);
assertNotNull(resp);
waitSetId = resp.getWaitSetId();
int seq = resp.getSequence();
for (int fnum = 0; fnum < numFolders; fnum++) {
AdminWaitSetRequest waitSet = new AdminWaitSetRequest(waitSetId, Integer.toString(seq));
Set<Integer> folderInterest = Sets.newHashSet();
folderInterest.add(folders.get(fnum).getFolderIdInOwnerMailbox());
waitSet.addUpdateAccount(createWaitSetAddSpec(acct1Id, folderInterest));
AdminWaitSetResponse wsResp = sendReq(envelope(adminAuthToken, jaxbToString(waitSet), "urn:zimbra"), TestUtil.getAdminSoapUrl() + "AdminWaitSetRequest");
seq = Integer.parseInt(wsResp.getSeqNo());
assertEquals("Number of ADMIN sessions (should not have increased)", numSess, countActiveSessionsForAdmin());
}
}
Aggregations