diff --git a/WebContent/WEB-INF/applicationContext.xml b/WebContent/WEB-INF/applicationContext.xml
index 57cbc58713..d0e68ab512 100644
--- a/WebContent/WEB-INF/applicationContext.xml
+++ b/WebContent/WEB-INF/applicationContext.xml
@@ -244,4 +244,6 @@
+
+
diff --git a/build.gradle b/build.gradle
index e577577d05..6921d48ecb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -197,5 +197,6 @@ test {
includeTestsMatching "org.scada_lts.dao.IsEventDetectorXidUniqueTest"
includeTestsMatching "com.serotonin.mango.view.export.CsvWriterTest"
includeTestsMatching "com.serotonin.mango.util.EmailValidatorTest"
+ includeTestsMatching "com.serotonin.mango.vo.LoggedUserTestsSuite"
}
}
\ No newline at end of file
diff --git a/src/br/org/scadabr/view/component/AlarmListComponent.java b/src/br/org/scadabr/view/component/AlarmListComponent.java
index 6241cf93af..b60cb78fc8 100644
--- a/src/br/org/scadabr/view/component/AlarmListComponent.java
+++ b/src/br/org/scadabr/view/component/AlarmListComponent.java
@@ -58,7 +58,7 @@ public String generateContent() {
WebContext webContext = WebContextFactory.get();
HttpServletRequest request = webContext.getHttpServletRequest();
List toViewEvents = new EventService().getPendingEventsAlarmLevelMin(Common
- .getUser().getId(), minAlarmLevel, maxListSize, true);
+ .getUser().getId(), minAlarmLevel, maxListSize);
model.put("nome", "marlon");
model.put("events",toViewEvents);
diff --git a/src/br/org/scadabr/web/dwr/UsersProfilesDwr.java b/src/br/org/scadabr/web/dwr/UsersProfilesDwr.java
index f3426259a2..3c918d3f44 100644
--- a/src/br/org/scadabr/web/dwr/UsersProfilesDwr.java
+++ b/src/br/org/scadabr/web/dwr/UsersProfilesDwr.java
@@ -10,6 +10,7 @@
import javax.servlet.http.HttpServletRequest;
+import com.serotonin.mango.vo.User;
import org.directwebremoting.WebContextFactory;
import br.org.scadabr.api.exception.DAOException;
@@ -33,6 +34,7 @@
import org.scada_lts.dao.model.ScadaObjectIdentifier;
import org.scada_lts.mango.service.UsersProfileService;
import org.scada_lts.mango.service.ViewService;
+import org.scada_lts.web.beans.ApplicationBeans;
public class UsersProfilesDwr {
@@ -122,6 +124,7 @@ public DwrResponseI18n saveUserAdmin(int id, String name,
try {
usersProfileService.saveUsersProfile(profile);
+ ApplicationBeans.getLoggedUsersBean().updateUsers(profile);
} catch (DAOException e) {
response.addMessage(new LocalizableMessage(
"userProfiles.validate.nameUnique"));
diff --git a/src/com/serotonin/mango/db/dao/EventDao.java b/src/com/serotonin/mango/db/dao/EventDao.java
deleted file mode 100644
index 9da777843c..0000000000
--- a/src/com/serotonin/mango/db/dao/EventDao.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * (c) 2016 Abil'I.T. http://abilit.eu/
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-package com.serotonin.mango.db.dao;
-
-import java.util.Date;
-import java.util.List;
-import java.util.ResourceBundle;
-
-import org.scada_lts.dao.DAO;
-import org.scada_lts.mango.adapter.MangoEvent;
-import org.scada_lts.mango.service.EventService;
-
-import com.serotonin.mango.rt.event.EventInstance;
-import com.serotonin.mango.rt.event.type.EventType;
-import com.serotonin.mango.vo.UserComment;
-import com.serotonin.mango.vo.event.EventHandlerVO;
-import com.serotonin.mango.vo.event.EventTypeVO;
-
-/**
- * Rewrite (ultimately to remove) and only use EventService
- *
- * @author Grzesiek Bylica Abil'I.T. development team, sdt@abilit.eu
- */
-@Deprecated
-public class EventDao {
-
- private MangoEvent eventService = new EventService();
-
- public void saveEvent(EventInstance event) {
- eventService.saveEvent(event);
- }
-
- public void ackEvent(int eventId, long time, int userId,
- int alternateAckSource, boolean signalAlarmLevelChange) {
- eventService.ackEvent(eventId, time, userId, alternateAckSource);
- }
-
- public void ackEvent(int eventId, long time, int userId,
- int alternateAckSource) {
- eventService.ackEvent(eventId, time, userId, alternateAckSource);
- }
-
- public void insertUserEvents(final int eventId,
- final List userIds, final boolean alarm) {
- eventService.insertUserEvents(eventId, userIds, alarm);
- }
-
- public List getActiveEvents() {
- return eventService.getActiveEvents();
- }
-
- public List getEventsForDataPoint(int dataPointId, int userId) {
- return eventService.getEventsForDataPoint(dataPointId, userId);
- }
-
- public List getPendingEventsForDataPoint(int dataPointId,
- int userId) {
- return eventService.getPendingEventsForDataPoint(dataPointId, userId);
- }
-
- public List getPendingEventsForDataSource(int dataSourceId,
- int userId) {
- return eventService.getPendingEvents(EventType.EventSources.DATA_SOURCE,
- dataSourceId, userId);
- }
-
- public List getPendingEventsForPublisher(int publisherId,
- int userId) {
- return eventService.getPendingEvents(EventType.EventSources.PUBLISHER, publisherId,
- userId);
- }
-
- public List getPendingEvents(int userId) {
- return eventService.getPendingEvents(userId);
- }
-
- public void attachRelationalInfo(List list) {
- eventService.attachRelationalInfo(list);
- }
-
- public EventInstance insertEventComment(int eventId, UserComment comment) {
- return eventService.insertEventComment(eventId, comment);
- }
-
- public int purgeEventsBefore(final long time) {
- return eventService.purgeEventsBefore(time);
- }
-
- public int getEventCount() {
- return eventService.getEventCount();
- }
-
- public List searchOld(int eventId, int eventSourceType,
- String status, int alarmLevel, final String[] keywords,
- final int maxResults, int userId, final ResourceBundle bundle) {
- return eventService.searchOld(eventId, eventSourceType, status, alarmLevel, keywords, maxResults, userId, bundle);
-
- }
-
- public List search(int eventId, int eventSourceType,
- String status, int alarmLevel, final String[] keywords, int userId,
- final ResourceBundle bundle, final int from, final int to,
- final Date date) {
- return eventService.search(eventId, eventSourceType, status, alarmLevel, keywords, userId, bundle, from, to, date);
-
- }
-
- public List search(int eventId, int eventSourceType,
- String status, int alarmLevel, final String[] keywords,
- long dateFrom, long dateTo, int userId,
- final ResourceBundle bundle, final int from, final int to,
- final Date date) {
-
- return eventService.search(eventId, eventSourceType, status, alarmLevel, keywords, dateFrom, dateTo, userId, bundle, from, to, date);
- }
-
- public int getSearchRowCount() {
- return eventService.getSearchRowCount();
- }
-
- public int getStartRow() {
- return eventService.getStartRow();
- }
-
- //
- // /
- // / Event handlers
- // /
- //
- public String generateUniqueXid() {
- return DAO.getInstance().generateUniqueXid(EventHandlerVO.XID_PREFIX, "eventHandlers");
- }
-
- public boolean isXidUnique(String xid, int excludeId) {
- return DAO.getInstance().isXidUnique(xid, excludeId, "eventHandlers");
- }
-
- public EventType getEventHandlerType(int handlerId) {
- return eventService.getEventHandlerType(handlerId);
- }
-
- public List getEventHandlers(EventType type) {
- return eventService.getEventHandlers(type);
- }
-
- public List getEventHandlers(EventTypeVO type) {
- return eventService.getEventHandlers(type);
- }
-
- public List getEventHandlers() {
- return eventService.getEventHandlers();
- }
-
- public EventHandlerVO getEventHandler(int eventHandlerId) {
- return eventService.getEventHandler(eventHandlerId);
- }
-
- public EventHandlerVO getEventHandler(String xid) {
- return eventService.getEventHandler(xid);
- }
-
- public EventHandlerVO saveEventHandler(final EventType type,
- final EventHandlerVO handler) {
- return eventService.saveEventHandler(type, handler);
- }
-
- public EventHandlerVO saveEventHandler(final EventTypeVO type,
- final EventHandlerVO handler) {
- return eventService.saveEventHandler(type, handler);
- }
-
- public void deleteEventHandler(final int handlerId) {
- eventService.deleteEventHandler(handlerId);
- }
-
- public boolean toggleSilence(int eventId, int userId) {
- return eventService.toggleSilence(eventId, userId);
- }
-
- @Deprecated
- public int getHighestUnsilencedAlarmLevel(int userId) {
- return eventService.getHighestUnsilencedAlarmLevel(userId);
- }
-
- public static List getFromCache(int userId) {
- return EventService.getFromCache(userId);
- }
-
- public static void addToCache(int userId, List list) {
- EventService.addToCache(userId, list);
- }
-
- public static void updateCache(EventInstance event) {
- EventService.updateCache(event);
- }
-
- public static void removeUserIdFromCache(int userId) {
- EventService.removeUserIdFromCache(userId);
- }
-
- public static void clearCache() {
- EventService.clearCache();
- }
-
-
-}
diff --git a/src/com/serotonin/mango/rt/event/type/AlarmLevelType.java b/src/com/serotonin/mango/rt/event/type/AlarmLevelType.java
new file mode 100644
index 0000000000..4f6e9dfb32
--- /dev/null
+++ b/src/com/serotonin/mango/rt/event/type/AlarmLevelType.java
@@ -0,0 +1,32 @@
+package com.serotonin.mango.rt.event.type;
+
+import com.serotonin.mango.rt.event.AlarmLevels;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public enum AlarmLevelType {
+
+ NONE(AlarmLevels.NONE),
+ INFORMATION(AlarmLevels.INFORMATION),
+ URGENT(AlarmLevels.URGENT),
+ CRITICAL(AlarmLevels.CRITICAL),
+ LIFE_SAFETY(AlarmLevels.LIFE_SAFETY);
+ private final int code;
+ AlarmLevelType(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public static List getAlarmLevels() {
+ return Stream.of(AlarmLevelType.values()).collect(Collectors.toList());
+ }
+
+ public static List getAlarmLevelsWithoutNone() {
+ return Stream.of(AlarmLevelType.values()).filter(a -> a != AlarmLevelType.NONE).collect(Collectors.toList());
+ }
+}
diff --git a/src/com/serotonin/mango/vo/User.java b/src/com/serotonin/mango/vo/User.java
index aeccfb4798..b89b766bdd 100644
--- a/src/com/serotonin/mango/vo/User.java
+++ b/src/com/serotonin/mango/vo/User.java
@@ -21,6 +21,7 @@
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
+import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import br.org.scadabr.vo.exporter.ZIPProjectManager;
@@ -51,6 +52,7 @@
import com.serotonin.web.i18n.LocalizableMessage;
import org.scada_lts.dao.UsersProfileDAO;
import org.scada_lts.mango.service.UsersProfileService;
+import org.scada_lts.web.beans.ApplicationBeans;
@JsonRemoteEntity
public class User implements SetPointSource, HttpSessionBindingListener,
@@ -123,18 +125,6 @@ public class User implements SetPointSource, HttpSessionBindingListener,
public User() { }
- @Deprecated
- public User(int id, String username, String email, String phone, boolean admin, boolean disabled, String homeUrl, long lastLogin) {
- this.id = id;
- this.username = username;
- this.email = email;
- this.phone = phone;
- this.admin = admin;
- this.disabled = disabled;
- this.homeUrl = homeUrl;
- this.lastLogin = lastLogin;
- }
-
public User(int id, String username, String firstName, String lastName, String email, String phone, boolean admin, boolean disabled, String homeUrl, long lastLogin) {
this.id = id;
this.username = username;
@@ -231,6 +221,16 @@ public void raiseRecursionFailureEvent() {
throw new ShouldNeverHappenException("");
}
+ @Override
+ public void valueBound(HttpSessionBindingEvent event) {
+ ApplicationBeans.getLoggedUsersBean().addUser(this, event.getSession());
+ }
+
+ @Override
+ public void valueUnbound(HttpSessionBindingEvent event) {
+ ApplicationBeans.getLoggedUsersBean().removeUser(this, event.getSession());
+ }
+
// Convenience method for JSPs
@JsonIgnore
public boolean isDataSourcePermission() {
@@ -674,6 +674,10 @@ public int getUserProfile() {
public void resetUserProfile() {
this.userProfile = Common.NEW_ID;
+ this.dataPointProfilePermissions.clear();
+ this.dataSourceProfilePermissions.clear();
+ this.watchListProfilePermissions.clear();
+ this.viewProfilePermissions.clear();
}
@Override
diff --git a/src/com/serotonin/mango/web/dwr/UsersDwr.java b/src/com/serotonin/mango/web/dwr/UsersDwr.java
index 0e65e0f71e..f670587539 100644
--- a/src/com/serotonin/mango/web/dwr/UsersDwr.java
+++ b/src/com/serotonin/mango/web/dwr/UsersDwr.java
@@ -51,6 +51,7 @@
import org.scada_lts.mango.service.SystemSettingsService;
import org.scada_lts.mango.service.UserService;
import org.scada_lts.mango.service.UsersProfileService;
+import org.scada_lts.web.beans.ApplicationBeans;
import org.scada_lts.web.mvc.api.json.JsonSettingsMisc;
import static com.serotonin.mango.util.LoggingUtils.userInfo;
@@ -215,10 +216,10 @@ else if (dupUser != null && id != dupUser.getId())
// set permission on all watchlists
}
- if (currentUser.getId() == id)
+ /*if (currentUser.getId() == id)
// Update the user object in session too. Why not?
- Common.updateUserInSession(request, user);
-
+ Common.updateUserInSession(request, user);*/
+ ApplicationBeans.getLoggedUsersBean().updateUser(user);
response.addData("userId", user.getId());
}
diff --git a/src/org/scada_lts/dao/PendingEventsDAO.java b/src/org/scada_lts/dao/PendingEventsDAO.java
index a23dfe6fab..14f19b659c 100644
--- a/src/org/scada_lts/dao/PendingEventsDAO.java
+++ b/src/org/scada_lts/dao/PendingEventsDAO.java
@@ -19,9 +19,11 @@
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import com.serotonin.mango.rt.event.type.AlarmLevelType;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.scada_lts.utils.EventTypeUtil;
@@ -85,31 +87,32 @@ public class PendingEventsDAO {
+ "left join userEvents ue on e.id=ue.eventId "
+ "where "
+ "ue.userId=? and "
- + "(e.ackTs is null or e.ackTs = 0) "
+ + "(e.ackTs is null or e.ackTs = 0) and "
+ + "e.alarmLevel >= ? "
+ "order by e.activeTs desc "
- + "LIMIT ? ";
+ + "LIMIT ? OFFSET ?";
// @formatter:on
- public List getPendingEvents(int userId, final Map> comments) {
- return getPendingEvents(userId, comments, 100);
+ public List getPendingEvents(int userId, final Map> comments, AlarmLevelType minAlarmLevel) {
+ return getPendingEvents(userId, comments, minAlarmLevel, 100, 0);
}
- public List getPendingEvents(int userId, final Map> comments, int limit) {
+ public List getPendingEvents(int userId, final Map> comments, AlarmLevelType minAlarmLevel, int limit, int offset) {
if (LOG.isTraceEnabled()) {
LOG.trace("SQL PendingEvents userId:"+userId);
}
try {
@SuppressWarnings({ "unchecked", "rawtypes" })
- List listEvents = DAO.getInstance().getJdbcTemp().query(SQL_EVENTS,new Integer[]{userId, limit},
+ List listEvents = DAO.getInstance().getJdbcTemp().query(SQL_EVENTS,new Integer[]{userId, minAlarmLevel.getCode(), limit, offset},
(rs, rownumber) -> mapToEvent(comments, rs));
return listEvents;
} catch (Exception e) {
LOG.error(e);
}
- return null;
+ return Collections.emptyList();
}
private EventInstance mapToEvent(Map> comments, ResultSet rs) throws SQLException {
diff --git a/src/org/scada_lts/login/ILoggedUsers.java b/src/org/scada_lts/login/ILoggedUsers.java
new file mode 100644
index 0000000000..90b32a2970
--- /dev/null
+++ b/src/org/scada_lts/login/ILoggedUsers.java
@@ -0,0 +1,15 @@
+package org.scada_lts.login;
+
+import br.org.scadabr.vo.usersProfiles.UsersProfileVO;
+import com.serotonin.mango.vo.User;
+
+import javax.servlet.http.HttpSession;
+import java.util.Set;
+
+public interface ILoggedUsers {
+ User addUser(User user, HttpSession session);
+ void updateUser(User user);
+ void updateUsers(UsersProfileVO profile);
+ User removeUser(User user, HttpSession session);
+ Set getUserIds();
+}
diff --git a/src/org/scada_lts/login/LoggedUsers.java b/src/org/scada_lts/login/LoggedUsers.java
new file mode 100644
index 0000000000..18eb58153e
--- /dev/null
+++ b/src/org/scada_lts/login/LoggedUsers.java
@@ -0,0 +1,122 @@
+package org.scada_lts.login;
+
+import br.org.scadabr.vo.usersProfiles.UsersProfileVO;
+import com.serotonin.mango.util.LoggingUtils;
+import com.serotonin.mango.vo.User;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.security.core.GrantedAuthority;
+
+import javax.servlet.http.HttpSession;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import static com.serotonin.mango.Common.SESSION_USER;
+
+public class LoggedUsers implements ILoggedUsers {
+
+ private static final Log LOG = LogFactory.getLog(LoggedUsers.class);
+
+ public LoggedUsers() {}
+
+ private final Map loggedUsers = new ConcurrentHashMap<>();
+ private final Map> loggedSessions = new ConcurrentHashMap<>();
+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+ private final ThreadLocal blocked = new ThreadLocal<>();
+
+ @Override
+ public User addUser(User user, HttpSession session) {
+ lock.writeLock().lock();
+ try {
+ if("setAttribute".equals(blocked.get())) {
+ LOG.warn("blocked addUser: " + LoggingUtils.userInfo(user) + ", thread: " + Thread.currentThread().getName());
+ return null;
+ }
+ loggedSessions.putIfAbsent(user.getId(), new CopyOnWriteArrayList<>());
+ if(!loggedSessions.get(user.getId()).contains(session)) {
+ loggedSessions.get(user.getId()).add(session);
+ return loggedUsers.put(user.getId(), user);
+ }
+ LOG.warn("session exists for: " + LoggingUtils.userInfo(user) + ", thread: " + Thread.currentThread().getName());
+ return null;
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ @Override
+ public void updateUser(User user) {
+ lock.writeLock().lock();
+ try {
+ update(user, loggedUsers, loggedSessions, blocked);
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ @Override
+ public void updateUsers(UsersProfileVO profile) {
+ lock.writeLock().lock();
+ try {
+ for(User user: new ArrayList<>(loggedUsers.values())) {
+ if(user.getUserProfile() == profile.getId()) {
+ profile.apply(user);
+ update(user, loggedUsers, loggedSessions, blocked);
+ }
+ }
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ @Override
+ public User removeUser(User user, HttpSession session) {
+ lock.writeLock().lock();
+ try {
+ if("setAttribute".equals(blocked.get())) {
+ LOG.warn("blocked removeUser: " + LoggingUtils.userInfo(user) + ", thread: " + Thread.currentThread().getName());
+ return null;
+ }
+ if (loggedSessions.get(user.getId()) == null || (loggedSessions.get(user.getId()).remove(session)
+ && loggedSessions.get(user.getId()).isEmpty())) {
+ loggedSessions.remove(user.getId());
+ return loggedUsers.remove(user.getId());
+ }
+ return null;
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ @Override
+ public Set getUserIds() {
+ lock.readLock().lock();
+ try {
+ return loggedUsers.keySet();
+ } finally {
+ lock.readLock().unlock();
+ }
+ }
+
+ private static void update(User user, Map loggedUsers,
+ Map> loggedSessions,
+ ThreadLocal blocked) {
+ User loggedUser = loggedUsers.get(user.getId());
+ if(loggedUser == null) {
+ LOG.warn("not logged user: " + LoggingUtils.userInfo(user) + ", thread: " + Thread.currentThread().getName());
+ return;
+ }
+ List roles = loggedUser.getAttribute("roles");
+ if(roles != null)
+ user.setAttribute("roles", roles);
+ loggedSessions.putIfAbsent(user.getId(), new CopyOnWriteArrayList<>());
+ for(HttpSession session : loggedSessions.get(user.getId())) {
+ blocked.set("setAttribute");
+ session.setAttribute(SESSION_USER, user);
+ blocked.set("");
+ }
+ loggedUsers.put(user.getId(), user);
+ }
+}
diff --git a/src/org/scada_lts/mango/adapter/MangoEvent.java b/src/org/scada_lts/mango/adapter/MangoEvent.java
index 2cf994a07e..cab5948e6e 100644
--- a/src/org/scada_lts/mango/adapter/MangoEvent.java
+++ b/src/org/scada_lts/mango/adapter/MangoEvent.java
@@ -66,16 +66,12 @@ public interface MangoEvent {
List getEventsForDataPoint(int dataPointId, int userId);
List getPendingEventsForDataPoint(int dataPointId, int userId);
-
- List getPendingSimpleEventsForDataSource(int dataSourceId, int userId);
List getPendingEventsForDataSource(int dataSourceId, int userId);
List getPendingEventsForPublisher(int publisherId, int userId);
List getPendingEvents(int typeId, int typeRef1, int userId);
-
- List getPendingSimpleEvents(int typeId, int typeRef1, int userId);
List getPendingEvents(int userId);
@@ -132,6 +128,4 @@ public interface MangoEvent {
boolean isXidUnique(String xid, int excludeId);
List getPendingEventsAlarmLevelMin(int userId, int alarmLevelMin, int limit);
-
- List getPendingEventsAlarmLevelMin(int userId, int alarmLevelMin, int limit, boolean disabledCache);
}
diff --git a/src/org/scada_lts/mango/service/EventService.java b/src/org/scada_lts/mango/service/EventService.java
index 67491f83f5..6509c6a3bc 100644
--- a/src/org/scada_lts/mango/service/EventService.java
+++ b/src/org/scada_lts/mango/service/EventService.java
@@ -185,20 +185,6 @@ public List getPendingEvents(int typeId, int typeRef1, int userId
}
- @Deprecated(since = "2.7.5.4")
- @Override
- public List getPendingSimpleEvents(int typeId, int typeRef1, int userId) {
-
- List lst;
- if (typeRef1 == -1) {
- lst = eventDAO.getPendingEvents(typeId, userId);
- } else {
- lst = eventDAO.getPendingEvents(typeId, typeRef1, userId);
- }
- return lst;
-
- }
-
@Override
public List getEventsForDataPoint(int dataPointId, int userId) {
int limit = systemSettingsService.getMiscSettings().getEventPendingLimit();
@@ -235,13 +221,6 @@ public List getPendingEventsForDataSource(int dataSourceId, int u
return getPendingEvents(EventType.EventSources.DATA_SOURCE, dataSourceId, userId);
}
- @Deprecated
- @Override
- public List getPendingSimpleEventsForDataSource(int dataSourceId, int userId) {
- return getPendingSimpleEvents(EventType.EventSources.DATA_SOURCE, dataSourceId, userId);
- }
-
-
@Override
public List getPendingEventsForPublisher(int publisherId, int userId) {
return getPendingEvents(EventType.EventSources.PUBLISHER, publisherId,
@@ -251,29 +230,24 @@ public List getPendingEventsForPublisher(int publisherId, int use
@Override
public List getPendingEvents(int userId) {
int limit = systemSettingsService.getMiscSettings().getEventPendingLimit();
- return getPendingEventsAlarmLevelMin(userId, -1, limit, false);
+ return getPendingEventsAlarmLevelMin(userId, -1, limit);
}
@Override
public List getPendingEventsAlarmLevelMin(int userId, int alarmLevelMin, int limit) {
- return getPendingEventsAlarmLevelMin(userId, alarmLevelMin, limit, false);
- }
-
- @Override
- public List getPendingEventsAlarmLevelMin(int userId, int alarmLevelMin, int limit, boolean forceDisabledCache) {
List results = null;
try {
boolean cacheEnable = systemSettingsService.getMiscSettings().isEventPendingCacheEnabled();
- if (!forceDisabledCache && cacheEnable) {
+ int fromSystemSettingsLimit = systemSettingsService.getMiscSettings().getEventPendingLimit();
+ int calcLimit = limit > -1 && limit <= fromSystemSettingsLimit ? limit : fromSystemSettingsLimit;
+ if (cacheEnable) {
PendingEventsCache.getInstance().startUpdate();
results = PendingEventsCache.getInstance().getPendingEvents(userId).stream()
- .sorted(Comparator.comparing(EventInstance::getActiveTimestamp))
+ .sorted(Comparator.comparing(EventInstance::getActiveTimestamp).reversed())
.filter(a -> alarmLevelMin < 0 || a.getAlarmLevel() >= alarmLevelMin)
+ .limit(calcLimit)
.collect(Collectors.toList());
} else {
- if(!forceDisabledCache)
- PendingEventsCache.getInstance().stopUpdate();
- int fromSystemSettingsLimit = systemSettingsService.getMiscSettings().getEventPendingLimit();
- int calcLimit = limit > -1 ? limit : fromSystemSettingsLimit;
+ PendingEventsCache.getInstance().stopUpdate();
if(alarmLevelMin > 0) {
results = eventDAO.getPendingEventsLimitAlarmLevelMin(userId, alarmLevelMin, calcLimit);
} else {
diff --git a/src/org/scada_lts/mango/service/PendingEventService.java b/src/org/scada_lts/mango/service/PendingEventService.java
index 97bd1dbef0..ea9557399e 100644
--- a/src/org/scada_lts/mango/service/PendingEventService.java
+++ b/src/org/scada_lts/mango/service/PendingEventService.java
@@ -18,18 +18,23 @@
package org.scada_lts.mango.service;
+import com.serotonin.mango.rt.event.type.AlarmLevelType;
import com.serotonin.mango.rt.event.EventInstance;
+import org.scada_lts.login.ILoggedUsers;
+import com.serotonin.mango.vo.User;
import com.serotonin.mango.vo.UserComment;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.scada_lts.dao.IUserCommentDAO;
-import org.scada_lts.dao.IUserDAO;
import org.scada_lts.dao.PendingEventsDAO;
+import org.scada_lts.service.IHighestAlarmLevelService;
+import org.scada_lts.utils.SystemSettingsUtils;
import org.scada_lts.web.beans.ApplicationBeans;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Collectors;
@Service
public class PendingEventService {
@@ -40,27 +45,47 @@ public class PendingEventService {
private final PendingEventsDAO pendingEventsDAO;
- private final IUserDAO userDAO;
-
private final SystemSettingsService systemSettingsService;
+ private final IHighestAlarmLevelService highestAlarmLevelService;
+ private final ILoggedUsers loggedUsers;
+
public PendingEventService() {
userCommentDAO = ApplicationBeans.getUserCommentDaoBean();
+ highestAlarmLevelService = ApplicationBeans.getHighestAlarmLevelServiceBean();
+ loggedUsers = ApplicationBeans.getLoggedUsersBean();
pendingEventsDAO = new PendingEventsDAO();
- userDAO = ApplicationBeans.getUserDaoBean();
systemSettingsService = new SystemSettingsService();
}
public Map> getPendingEvents() {
- List users = userDAO.getAll();
+ Set users = loggedUsers.getUserIds();
Map> comments = getCacheUserComments(userCommentDAO.getEventComments());
int limit = systemSettingsService.getMiscSettings().getEventPendingLimit();
Map> cacheEvents = new ConcurrentHashMap<>();
for (int userId: users) {
- List events = new CopyOnWriteArrayList<>(pendingEventsDAO.getPendingEvents(userId, comments, limit));
- cacheEvents.put(userId, events);
+ Set events = pendingEventsDAO.getPendingEvents(userId, comments, AlarmLevelType.NONE,
+ SystemSettingsUtils.getEventPendingUpdateLimit(), 0).stream()
+ .map(EventInstanceEqualsById::new)
+ .collect(Collectors.toSet());
+ if(!events.isEmpty()) {
+ int highestAlarmLevelForUser = highestAlarmLevelService.getAlarmLevel(User.onlyId(userId));
+ for (AlarmLevelType alarmLevelType : AlarmLevelType.getAlarmLevelsWithoutNone()) {
+ if(alarmLevelType.getCode() <= highestAlarmLevelForUser) {
+ long count = events.stream()
+ .filter(a -> a.getEventInstance().getAlarmLevel() >= alarmLevelType.getCode())
+ .count();
+ if (count < limit) {
+ events.addAll(pendingEventsDAO.getPendingEvents(userId, comments, alarmLevelType, limit, 0).stream()
+ .map(EventInstanceEqualsById::new)
+ .collect(Collectors.toSet()));
+ }
+ }
+ }
+ }
+ cacheEvents.put(userId, events.stream().map(EventInstanceEqualsById::getEventInstance).collect(Collectors.toList()));
}
return cacheEvents;
}
@@ -82,4 +107,28 @@ private Map> getCacheUserComments(List c
}
return mappedUserCommentForEvent;
}
+
+ static class EventInstanceEqualsById {
+ private final EventInstance eventInstance;
+ public EventInstanceEqualsById(EventInstance eventInstance) {
+ this.eventInstance = eventInstance;
+ }
+
+ public EventInstance getEventInstance() {
+ return eventInstance;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof EventInstanceEqualsById)) return false;
+ EventInstanceEqualsById byId = (EventInstanceEqualsById) o;
+ return eventInstance.getId() == byId.eventInstance.getId();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(eventInstance.getId());
+ }
+ }
}
diff --git a/src/org/scada_lts/utils/SystemSettingsUtils.java b/src/org/scada_lts/utils/SystemSettingsUtils.java
index cc0f80d285..dacf29b319 100644
--- a/src/org/scada_lts/utils/SystemSettingsUtils.java
+++ b/src/org/scada_lts/utils/SystemSettingsUtils.java
@@ -35,6 +35,7 @@ private SystemSettingsUtils() {}
public static final String VIEW_FORCE_FULL_SCREEN_MODE = "view.forceFullScreen";
public static final String VIEW_HIDE_SHORTCUT_DISABLE_FULL_SCREEN = "view.hideShortcutDisableFullScreen";
public static final String EVENT_PENDING_LIMIT = "event.pending.limit";
+ public static final String EVENT_PENDING_UPDATE_LIMIT = "event.pending.update.limit";
public static final String EVENT_PENDING_CACHE_ENABLED = "abilit.cacheEnable";
private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(SystemSettingsUtils.class);
@@ -215,13 +216,23 @@ public static int getEventPendingLimit() {
}
}
+ public static int getEventPendingUpdateLimit() {
+ try {
+ String eventPendingLimit = ScadaConfig.getInstance().getConf().getProperty(EVENT_PENDING_UPDATE_LIMIT, "1000");
+ return Integer.parseInt(eventPendingLimit);
+ } catch (Exception e) {
+ LOG.error(e.getMessage());
+ return 1000;
+ }
+ }
+
public static boolean isEventPendingCacheEnabled() {
try {
- String eventPendingCache = ScadaConfig.getInstance().getConf().getProperty(EVENT_PENDING_CACHE_ENABLED, "false");
+ String eventPendingCache = ScadaConfig.getInstance().getConf().getProperty(EVENT_PENDING_CACHE_ENABLED, "true");
return Boolean.parseBoolean(eventPendingCache);
} catch (Exception e) {
LOG.error(e.getMessage());
- return false;
+ return true;
}
}
}
diff --git a/src/org/scada_lts/web/beans/ApplicationBeans.java b/src/org/scada_lts/web/beans/ApplicationBeans.java
index c9de7e88a2..4507c8e373 100644
--- a/src/org/scada_lts/web/beans/ApplicationBeans.java
+++ b/src/org/scada_lts/web/beans/ApplicationBeans.java
@@ -5,6 +5,8 @@
import br.org.scadabr.vo.usersProfiles.UsersProfileVO;
import com.serotonin.mango.Common;
import com.serotonin.mango.view.View;
+import org.scada_lts.login.ILoggedUsers;
+import org.scada_lts.login.LoggedUsers;
import com.serotonin.mango.vo.User;
import com.serotonin.mango.vo.WatchList;
import com.serotonin.mango.vo.permission.DataPointAccess;
@@ -147,6 +149,10 @@ public static EventsServiceWebSocket getEventsServiceWebSocketBean() {
return getBeanFromContext("eventsServiceWebSocket", EventsServiceWebSocket.class);
}
+ public static ILoggedUsers getLoggedUsersBean() {
+ return getBeanFromContext("loggedUsers", LoggedUsers.class);
+ }
+
@Deprecated
public static class Lazy {
diff --git a/test/com/serotonin/mango/vo/LoggedUserTestsSuite.java b/test/com/serotonin/mango/vo/LoggedUserTestsSuite.java
new file mode 100644
index 0000000000..2d34e47567
--- /dev/null
+++ b/test/com/serotonin/mango/vo/LoggedUserTestsSuite.java
@@ -0,0 +1,17 @@
+package com.serotonin.mango.vo;
+
+import com.serotonin.mango.rt.scripting.ScriptTest;
+import com.serotonin.mango.rt.scripting.ScriptWithObjectContextEnableDisableDataPointTest;
+import com.serotonin.mango.rt.scripting.ScriptWithObjectContextEnableDisableDataSourceTest;
+import com.serotonin.mango.rt.scripting.ScriptWithObjectContextWriteDataPointTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ LoggedUsersTest.class,
+ LoggedUsersMultiThreadTest.class
+})
+public class LoggedUserTestsSuite {
+}
\ No newline at end of file
diff --git a/test/com/serotonin/mango/vo/LoggedUsersMultiThreadTest.java b/test/com/serotonin/mango/vo/LoggedUsersMultiThreadTest.java
new file mode 100644
index 0000000000..e9a5be5047
--- /dev/null
+++ b/test/com/serotonin/mango/vo/LoggedUsersMultiThreadTest.java
@@ -0,0 +1,532 @@
+package com.serotonin.mango.vo;
+
+import br.org.scadabr.db.utils.TestUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.scada_lts.login.ILoggedUsers;
+import org.scada_lts.login.LoggedUsers;
+import org.scada_lts.web.beans.ApplicationBeans;
+import org.springframework.mock.web.MockHttpSession;
+import utils.TestConcurrentUtils;
+
+import javax.servlet.http.HttpSession;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
+import static com.serotonin.mango.Common.SESSION_USER;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ApplicationBeans.class})
+// resources/org/powermock/extensions/configuration.properties is not working
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*",
+ "javax.activation.*", "javax.management.*"})
+public class LoggedUsersMultiThreadTest {
+
+ private final ILoggedUsers loggedUsers = new LoggedUsers();
+
+ @Before
+ public void config() {
+ mockStatic(ApplicationBeans.class);
+ when(ApplicationBeans.getLoggedUsersBean()).thenReturn(loggedUsers);
+ }
+
+ @Test
+ public void when_addUser_for_one_user_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+
+ //when:
+ TestConcurrentUtils.biConsumer(10, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, httpSession1)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_one_removeUser_for_one_user_and_same_session_as_addUser_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ TestConcurrentUtils.biConsumer(10, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_one_removeUser_for_one_user_and_other_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ TestConcurrentUtils.biConsumer(10, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, new MockHttpSession())
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_one_removeUser_for_one_user_and_two_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(10, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_one_user_and_two_session_as_addUser_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_one_user_and_one_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, new MockHttpSession())
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_for_one_user_and_other_session_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1),
+ new TestConcurrentUtils.ConsumerAction<>(loggedUsers::updateUser, user),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_for_one_user_and_other_session_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, httpSession1),
+ new TestConcurrentUtils.ConsumerAction<>(loggedUsers::updateUser, user),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_two_user_and_same_session_as_addUser_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user2, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_addUser_for_two_user_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId(), user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, httpSession1),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user2, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_four_addUser_for_two_user_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(1);
+ User user2 = TestUtils.newUser(2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, new MockHttpSession()),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user2, new MockHttpSession()),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, new MockHttpSession()),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user2, new MockHttpSession())
+ ));
+
+ //then:
+ Assert.assertEquals(2, loggedUsers.getUserIds().size());
+ }
+
+ @Test
+ public void when_six_addUser_for_two_user_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(1);
+ User user2 = TestUtils.newUser(2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, new MockHttpSession()),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user2, new MockHttpSession()),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, new MockHttpSession()),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user2, new MockHttpSession()),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, new MockHttpSession()),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user2, new MockHttpSession())
+ ));
+
+ //then:
+ Assert.assertEquals(2, loggedUsers.getUserIds().size());
+ }
+
+ @Test
+ public void when_two_removeUser_for_two_user_and_other_session_as_addUser_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId(), user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(10, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, new MockHttpSession())
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_two_user_and_two_session_as_addUser_then_logged_one_user() {
+
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(10, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_three_removeUser_for_two_user_and_three_session_as_addUser_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ HttpSession httpSession3 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+ loggedUsers.addUser(user2, httpSession3);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession2),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user2, httpSession3)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_three_removeUser_for_two_user_and_two_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ HttpSession httpSession3 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+ loggedUsers.addUser(user2, httpSession3);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_three_removeUser_for_two_user_and_one_session_as_addUser_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId(), user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ HttpSession httpSession3 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+ loggedUsers.addUser(user2, httpSession3);
+
+ //when:
+ TestConcurrentUtils.biConsumer(10, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_three_removeUser_for_two_user_and_one_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ HttpSession httpSession3 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+ loggedUsers.addUser(user2, httpSession3);
+
+ //when:
+ TestConcurrentUtils.biConsumer(10, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user2, httpSession3)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_two_user_and_one_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user2, new MockHttpSession())
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_for_two_user_and_other_session_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user, httpSession1),
+ new TestConcurrentUtils.ConsumerAction<>(loggedUsers::updateUser, user),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::removeUser, user2, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_for_two_user_and_other_session_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId(), user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user, httpSession1),
+ new TestConcurrentUtils.ConsumerAction<>(loggedUsers::updateUser, user),
+ new TestConcurrentUtils.BiFunctionAction<>(loggedUsers::addUser, user2, httpSession2)
+ ));
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_for_one_user_and_one_session_then_set_user_in_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setFirstName("nonupdated");
+ User updatedUser = TestUtils.newUser(123);
+ updatedUser.setFirstName("updated");
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.ConsumerAction<>(loggedUsers::updateUser, updatedUser)
+ ));
+
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertEquals(updatedUser.isAdmin(), result1.isAdmin());
+ }
+
+ @Test
+ public void when_updateUser_for_one_user_and_two_session_then_set_updated_user_in_two_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setFirstName("nonupdated");
+ User updatedUser = TestUtils.newUser(123);
+ updatedUser.setFirstName("updated");
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.ConsumerAction<>(loggedUsers::updateUser, updatedUser)
+ ));
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+ User result2 = (User) httpSession2.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertEquals(updatedUser.getFirstName(), result1.getFirstName());
+ Assert.assertEquals(updatedUser.getFirstName(), result2.getFirstName());
+ }
+
+ @Test
+ public void when_updateUser_for_one_user_and_two_session_then_no_set_no_updated_user_in_two_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setFirstName("nonupdated");
+ User updatedUser = TestUtils.newUser(123);
+ updatedUser.setFirstName("updated");
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ TestConcurrentUtils.biConsumer(1, Arrays.asList(
+ new TestConcurrentUtils.ConsumerAction<>(loggedUsers::updateUser, updatedUser)
+ ));
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+ User result2 = (User) httpSession2.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertNotEquals(user.getFirstName(), result1.getFirstName());
+ Assert.assertNotEquals(user.getFirstName(), result2.getFirstName());
+ }
+}
\ No newline at end of file
diff --git a/test/com/serotonin/mango/vo/LoggedUsersTest.java b/test/com/serotonin/mango/vo/LoggedUsersTest.java
new file mode 100644
index 0000000000..b44bc49113
--- /dev/null
+++ b/test/com/serotonin/mango/vo/LoggedUsersTest.java
@@ -0,0 +1,535 @@
+package com.serotonin.mango.vo;
+
+import br.org.scadabr.db.utils.TestUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.scada_lts.login.ILoggedUsers;
+import org.scada_lts.login.LoggedUsers;
+import org.scada_lts.web.beans.ApplicationBeans;
+import org.springframework.mock.web.MockHttpSession;
+import utils.TestConcurrentUtils;
+
+import javax.servlet.http.HttpSession;
+import java.util.*;
+
+import static com.serotonin.mango.Common.SESSION_USER;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ApplicationBeans.class})
+// resources/org/powermock/extensions/configuration.properties is not working
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*",
+ "javax.activation.*", "javax.management.*"})
+public class LoggedUsersTest {
+
+ private final ILoggedUsers loggedUsers = new LoggedUsers();
+
+ @Before
+ public void config() {
+ mockStatic(ApplicationBeans.class);
+ when(ApplicationBeans.getLoggedUsersBean()).thenReturn(loggedUsers);
+ }
+
+ @Test
+ public void when_addUser_for_one_user_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+
+ //when:
+ loggedUsers.addUser(user, httpSession1);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_one_removeUser_for_one_user_and_same_session_as_addUser_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_one_removeUser_for_one_user_and_other_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ loggedUsers.removeUser(user, new MockHttpSession());
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_one_removeUser_for_one_user_and_two_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_one_user_and_two_session_as_addUser_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+ loggedUsers.removeUser(user, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_one_user_and_one_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+ loggedUsers.removeUser(user, new MockHttpSession());
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_for_one_user_and_other_session_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+ loggedUsers.updateUser(user);
+ loggedUsers.removeUser(user, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_for_one_user_and_other_session_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+
+ //when:
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.updateUser(user);
+ loggedUsers.addUser(user, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_two_user_and_same_session_as_addUser_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+ loggedUsers.removeUser(user2, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_addUser_for_two_user_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId(), user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+
+ //when:
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_two_user_and_other_session_as_addUser_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId(), user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ loggedUsers.removeUser(user, new MockHttpSession());
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_two_user_and_two_session_as_addUser_then_logged_one_user() {
+
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_three_removeUser_for_two_user_and_three_session_as_addUser_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ HttpSession httpSession3 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+ loggedUsers.addUser(user2, httpSession3);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+ loggedUsers.removeUser(user, httpSession2);
+ loggedUsers.removeUser(user2, httpSession3);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_three_removeUser_for_two_user_and_two_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ HttpSession httpSession3 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+ loggedUsers.addUser(user2, httpSession3);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+ loggedUsers.removeUser(user, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_three_removeUser_for_two_user_and_one_session_as_addUser_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId(), user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ HttpSession httpSession3 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+ loggedUsers.addUser(user2, httpSession3);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_three_removeUser_for_two_user_and_one_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ HttpSession httpSession3 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+ loggedUsers.addUser(user2, httpSession3);
+
+ //when:
+ loggedUsers.removeUser(user2, httpSession3);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_two_removeUser_for_two_user_and_one_session_as_addUser_then_logged_one_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ loggedUsers.removeUser(user, httpSession1);
+ loggedUsers.removeUser(user2, new MockHttpSession());
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_and_two_removeUser_for_two_user_then_logged_any_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Collections.emptySet();
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //when:
+ loggedUsers.updateUser(user);
+ loggedUsers.removeUser(user, httpSession1);
+ loggedUsers.removeUser(user2, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_addUser_and_updateUser_and_addUser_for_two_user_then_logged_two_user() {
+ //given:
+ User user = TestUtils.newUser(123);
+ User user2 = TestUtils.newUser(345);
+ Set expected = Set.of(user.getId(), user2.getId());
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+
+ //when:
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.updateUser(user);
+ loggedUsers.addUser(user2, httpSession2);
+
+ //then:
+ Assert.assertEquals(expected, loggedUsers.getUserIds());
+ }
+
+ @Test
+ public void when_updateUser_for_updated_user_and_two_session_then_set_updated_user_in_two_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setAdmin(false);
+ User updatedUser = TestUtils.newUser(123);
+ updatedUser.setAdmin(true);
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ loggedUsers.updateUser(updatedUser);
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+ User result2 = (User) httpSession2.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertEquals(updatedUser.isAdmin(), result1.isAdmin());
+ Assert.assertEquals(updatedUser.isAdmin(), result1.isAdmin());
+ }
+
+ @Test
+ public void when_updateUser_for_two_updated_user_and_two_session_then_set_second_updated_user_in_two_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setAdmin(false);
+ user.setFirstName("");
+ User firstUpdatedUser = TestUtils.newUser(123);
+ firstUpdatedUser.setAdmin(true);
+ User secondUpdatedUser = TestUtils.newUser(123);
+ secondUpdatedUser.setFirstName("firstName");
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ loggedUsers.updateUser(firstUpdatedUser);
+ loggedUsers.updateUser(secondUpdatedUser);
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+ User result2 = (User) httpSession2.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertEquals(secondUpdatedUser.getFirstName(), result1.getFirstName());
+ Assert.assertEquals(secondUpdatedUser.getFirstName(), result2.getFirstName());
+ }
+
+ @Test
+ public void when_updateUser_for_updated_user_then_set_updated_user_in_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setAdmin(false);
+ User updatedUser = TestUtils.newUser(123);
+ updatedUser.setAdmin(true);
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ loggedUsers.updateUser(updatedUser);
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertEquals(updatedUser.isAdmin(), result1.isAdmin());
+ }
+
+ @Test
+ public void when_updateUser_for_updated_user_then_not_set_nonupdated_user_in_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setAdmin(false);
+ User updatedUser = TestUtils.newUser(123);
+ updatedUser.setAdmin(true);
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ loggedUsers.updateUser(updatedUser);
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertNotEquals(user.isAdmin(), result1.isAdmin());
+ }
+
+ @Test
+ public void when_updateUser_for_two_updated_user_then_set_second_updated_user_in_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setAdmin(false);
+ user.setFirstName("");
+ User fisrtUpdatedUser = TestUtils.newUser(123);
+ fisrtUpdatedUser.setAdmin(true);
+ User secondUpdatedUser = TestUtils.newUser(123);
+ secondUpdatedUser.setFirstName("firstName");
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ loggedUsers.updateUser(fisrtUpdatedUser);
+ loggedUsers.updateUser(secondUpdatedUser);
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertEquals(secondUpdatedUser.getFirstName(), result1.getFirstName());
+ }
+
+ @Test
+ public void when_updateUser_for_two_updated_user_then_set_not_first_updated_user_in_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setAdmin(false);
+ user.setFirstName("");
+ User firstUpdatedUser = TestUtils.newUser(123);
+ firstUpdatedUser.setAdmin(true);
+ User secondUpdatedUser = TestUtils.newUser(123);
+ secondUpdatedUser.setFirstName("firstName");
+ HttpSession httpSession1 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+
+ //when:
+ loggedUsers.updateUser(firstUpdatedUser);
+ loggedUsers.updateUser(secondUpdatedUser);
+ User result = (User) httpSession1.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertNotEquals(firstUpdatedUser.getFirstName(), result.getFirstName());
+ }
+
+ @Test
+ public void when_updateUser_for_updated_user_then_not_set_nonupdated_user_in_two_session() {
+ //given:
+ User user = TestUtils.newUser(123);
+ user.setAdmin(false);
+ User updatedUser = TestUtils.newUser(123);
+ updatedUser.setAdmin(true);
+ HttpSession httpSession1 = new MockHttpSession();
+ HttpSession httpSession2 = new MockHttpSession();
+ loggedUsers.addUser(user, httpSession1);
+ loggedUsers.addUser(user, httpSession2);
+
+ //when:
+ loggedUsers.updateUser(updatedUser);
+ User result1 = (User) httpSession1.getAttribute(SESSION_USER);
+ User result2 = (User) httpSession2.getAttribute(SESSION_USER);
+
+ //then:
+ Assert.assertNotEquals(user.isAdmin(), result1.isAdmin());
+ Assert.assertNotEquals(user.isAdmin(), result2.isAdmin());
+ }
+}
\ No newline at end of file
diff --git a/test/org/scada_lts/ds/messaging/channel/MessagingChannelsMultiThreadTest.java b/test/org/scada_lts/ds/messaging/channel/MessagingChannelsMultiThreadTest.java
index 07f0cca158..e5bd0842d9 100644
--- a/test/org/scada_lts/ds/messaging/channel/MessagingChannelsMultiThreadTest.java
+++ b/test/org/scada_lts/ds/messaging/channel/MessagingChannelsMultiThreadTest.java
@@ -220,16 +220,16 @@ public void when_removeChannel_and_initChannel_on_other_dataPoints_then_one_size
//given:
messagingChannels.initChannel(dataPointRT2, () -> messagingChannelOpenned1);
- TestConcurrentUtils.Action action1 =
- new TestConcurrentUtils.Action<>((dp, timeout) -> {
+ TestConcurrentUtils.BiConsumerAction action1 =
+ new TestConcurrentUtils.BiConsumerAction<>((dp, timeout) -> {
try {
messagingChannels.initChannel(dp, () -> messagingChannelOpenned1);
} catch (Exception e) {
throw new RuntimeException(e);
}
}, dataPointRT1, 1000);
- TestConcurrentUtils.Action action2 =
- new TestConcurrentUtils.Action<>((dp, timeout) -> {
+ TestConcurrentUtils.BiConsumerAction action2 =
+ new TestConcurrentUtils.BiConsumerAction<>((dp, timeout) -> {
try {
messagingChannels.removeChannel(dp);
} catch (Exception e) {
@@ -250,16 +250,16 @@ public void when_removeChannel_and_initChannel_on_other_dataPoints_then_one_isOp
//given:
messagingChannels.initChannel(dataPointRT2, () -> messagingChannelOpenned1);
- TestConcurrentUtils.Action action1 =
- new TestConcurrentUtils.Action<>((dp, timeout) -> {
+ TestConcurrentUtils.BiConsumerAction action1 =
+ new TestConcurrentUtils.BiConsumerAction<>((dp, timeout) -> {
try {
messagingChannels.initChannel(dp, () -> messagingChannelOpenned1);
} catch (Exception e) {
throw new RuntimeException(e);
}
}, dataPointRT1, 1000);
- TestConcurrentUtils.Action action2 =
- new TestConcurrentUtils.Action<>((dp, timeout) -> {
+ TestConcurrentUtils.BiConsumerAction action2 =
+ new TestConcurrentUtils.BiConsumerAction<>((dp, timeout) -> {
try {
messagingChannels.removeChannel(dp);
} catch (Exception e) {
@@ -301,24 +301,24 @@ public void when_isOpenChannel_without_initChannel_then_false() {
public void when_initChannel_with_three_dataPoints_then_size_three() throws Exception {
//given:
- TestConcurrentUtils.Action> action1 =
- new TestConcurrentUtils.Action<>((a, b) -> {
+ TestConcurrentUtils.BiConsumerAction> action1 =
+ new TestConcurrentUtils.BiConsumerAction<>((a, b) -> {
try {
messagingChannels.initChannel(a, b);
} catch (Exception e) {
e.printStackTrace();
}
}, dataPointRT1, () -> messagingChannelOpenned1);
- TestConcurrentUtils.Action> action2 =
- new TestConcurrentUtils.Action<>((a, b) -> {
+ TestConcurrentUtils.BiConsumerAction> action2 =
+ new TestConcurrentUtils.BiConsumerAction<>((a, b) -> {
try {
messagingChannels.initChannel(a, b);
} catch (Exception e) {
e.printStackTrace();
}
}, dataPointRT2, () -> messagingChannelOpenned2);
- TestConcurrentUtils.Action> action3 =
- new TestConcurrentUtils.Action<>((a, b) -> {
+ TestConcurrentUtils.BiConsumerAction> action3 =
+ new TestConcurrentUtils.BiConsumerAction<>((a, b) -> {
try {
messagingChannels.initChannel(a, b);
} catch (Exception e) {
diff --git a/test/utils/MultiThreadEngine.java b/test/utils/MultiThreadEngine.java
index e47c5a5323..784d9b2b8a 100644
--- a/test/utils/MultiThreadEngine.java
+++ b/test/utils/MultiThreadEngine.java
@@ -11,7 +11,7 @@
public class MultiThreadEngine {
- private static Logger logger = LoggerFactory.getLogger(MultiThreadEngine.class);
+ private static Logger LOG = LoggerFactory.getLogger(MultiThreadEngine.class);
public static void execute(final Executor executor, int concurrency, final Runnable action) {
final CountDownLatch ready = new CountDownLatch(concurrency);
@@ -24,7 +24,7 @@ public static void execute(final Executor executor, int concurrency, final Runna
start.await();
action.run();
} catch (InterruptedException ex) {
- logger.error(ex.getMessage(), ex);
+ LOG.error(ex.getMessage(), ex);
} finally {
done.countDown();
}
@@ -35,9 +35,9 @@ public static void execute(final Executor executor, int concurrency, final Runna
long startNanos = System.nanoTime();
start.countDown();
done.await();
- logger.info("time: {}", (System.nanoTime() - startNanos)/1000000000.0);
+ LOG.info("time: {}", (System.nanoTime() - startNanos)/1000000000.0);
} catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
+ LOG.error(ex.getMessage(), ex);
}
}
@@ -54,7 +54,7 @@ public static List execute(final Executor executor, int concurrency, fina
R result = action.call();
results.add(result);
} catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
+ LOG.error(ex.getMessage(), ex);
} finally {
done.countDown();
}
@@ -65,9 +65,9 @@ public static List execute(final Executor executor, int concurrency, fina
long startNanos = System.nanoTime();
start.countDown();
done.await();
- logger.info("time: {}", (System.nanoTime() - startNanos) / 1000000000.0);
+ LOG.info("time: {}", (System.nanoTime() - startNanos) / 1000000000.0);
} catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
+ LOG.error(ex.getMessage(), ex);
}
return results;
}
@@ -84,7 +84,7 @@ public static void execute(final Executor executor, int concurrency, final List<
start.await();
runnable.run();
} catch (InterruptedException ex) {
- logger.error(ex.getMessage(), ex);
+ LOG.error(ex.getMessage(), ex);
} finally {
done.countDown();
}
@@ -96,9 +96,9 @@ public static void execute(final Executor executor, int concurrency, final List<
long startNanos = System.nanoTime();
start.countDown();
done.await();
- logger.info("time: {}", (System.nanoTime() - startNanos)/1000000000.0);
+ LOG.info("time: {}", (System.nanoTime() - startNanos)/1000000000.0);
} catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
+ LOG.error(ex.getMessage(), ex);
}
}
}
\ No newline at end of file
diff --git a/test/utils/TestConcurrentUtils.java b/test/utils/TestConcurrentUtils.java
index 9bc8ef321d..d315839db1 100644
--- a/test/utils/TestConcurrentUtils.java
+++ b/test/utils/TestConcurrentUtils.java
@@ -32,10 +32,10 @@ public static void biConsumer(int numberOfLaunches, BiConsumer fun,
executor.shutdownNow();
}
- public static void biConsumer(int numberOfLaunches, List> actions) {
+ public static void biConsumer(int numberOfLaunches, List actions) {
ExecutorService executor = Executors.newFixedThreadPool(numberOfLaunches * actions.size());
List runnables = new ArrayList<>();
- for(Action, ?> action: actions) {
+ for(SupplierVoid action: actions) {
runnables.add(action::execute);
}
MultiThreadEngine.execute(executor, numberOfLaunches, runnables);
@@ -92,19 +92,64 @@ public interface SupplierVoid {
void execute();
}
- public static class Action {
- private BiConsumer fun;
+ public static class BiConsumerAction implements SupplierVoid {
+ private final BiConsumer fun;
A keyA;
B keyB;
- public Action(BiConsumer fun, A keyA, B keyB) {
+ public BiConsumerAction(BiConsumer fun, A keyA, B keyB) {
this.fun = fun;
this.keyA = keyA;
this.keyB = keyB;
}
+ @Override
public void execute() {
fun.accept(keyA, keyB);
}
}
+
+ public static class ConsumerAction implements SupplierVoid {
+ private final Consumer fun;
+ A keyA;
+
+ public ConsumerAction(Consumer fun, A keyA) {
+ this.fun = fun;
+ this.keyA = keyA;
+ }
+ @Override
+ public void execute() {
+ fun.accept(keyA);
+ }
+ }
+
+ public static class FunctionAction implements SupplierVoid {
+ private final Function fun;
+ A keyA;
+
+ public FunctionAction(Function fun, A keyA) {
+ this.fun = fun;
+ this.keyA = keyA;
+ }
+ @Override
+ public void execute() {
+ fun.apply(keyA);
+ }
+ }
+
+ public static class BiFunctionAction implements SupplierVoid {
+ private final BiFunction fun;
+ A keyA;
+ B keyB;
+
+ public BiFunctionAction(BiFunction fun, A keyA, B keyB) {
+ this.fun = fun;
+ this.keyA = keyA;
+ this.keyB = keyB;
+ }
+ @Override
+ public void execute() {
+ fun.apply(keyA, keyB);
+ }
+ }
}
\ No newline at end of file
diff --git a/test/utils/mock/EventServiceMock.java b/test/utils/mock/EventServiceMock.java
index 246df5fa19..2b28d870ef 100644
--- a/test/utils/mock/EventServiceMock.java
+++ b/test/utils/mock/EventServiceMock.java
@@ -91,11 +91,6 @@ public List getPendingEvents(int typeId, int typeRef1, int userId
return Collections.emptyList();
}
- @Override
- public List getPendingSimpleEvents(int typeId, int typeRef1, int userId) {
- return Collections.emptyList();
- }
-
@Override
public List getEventsForDataPoint(int dataPointId, int userId) {
return Collections.emptyList();
@@ -111,11 +106,6 @@ public List getPendingEventsForDataSource(int dataSourceId, int u
return Collections.emptyList();
}
- @Override
- public List getPendingSimpleEventsForDataSource(int dataSourceId, int userId) {
- return Collections.emptyList();
- }
-
@Override
public List getPendingEventsForPublisher(int publisherId, int userId) {
return Collections.emptyList();
diff --git a/webapp-resources/env.properties b/webapp-resources/env.properties
index 2c2c4b9b82..4a07896f29 100644
--- a/webapp-resources/env.properties
+++ b/webapp-resources/env.properties
@@ -57,7 +57,7 @@ abilit.disableDataSourcesOnServerStart=false
abilit.api.replace.alert.onview=true
-abilit.cacheEnable=false
+abilit.cacheEnable=true
abilit.START_UPDATE_UNSILENCED_ALARM_LEVEL=100000
abilit.START_UPDATE_EVENT_DETECTORS=100000
abilit.START_UPDATE_PENDING_EVENTS=100000
@@ -132,4 +132,5 @@ view.forceFullScreen=false
view.hideShortcutDisableFullScreen=false
eventdetector.cache.enabled=true
event.pending.limit=101
+event.pending.update.limit=5001
thread.name.additional.length=255
\ No newline at end of file