You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2017/07/30 15:55:48 UTC

[2/5] openmeetings git commit: [OPENMEETINGS-1677] Hazelcast is added to handle cluster

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 48e8dbe..54f6f15 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -41,7 +41,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Predicate;
 
 import org.apache.directory.api.util.Strings;
@@ -61,6 +60,7 @@ import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.util.InitializationContainer;
@@ -86,6 +86,7 @@ import org.apache.openmeetings.web.user.record.Mp4RecordingResourceReference;
 import org.apache.openmeetings.web.util.GroupLogoResourceReference;
 import org.apache.openmeetings.web.util.ProfileImageResourceReference;
 import org.apache.openmeetings.web.util.UserDashboardPersister;
+import org.apache.wicket.DefaultPageManagerProvider;
 import org.apache.wicket.Localizer;
 import org.apache.wicket.Page;
 import org.apache.wicket.RestartResponseException;
@@ -98,6 +99,7 @@ import org.apache.wicket.core.request.handler.BookmarkableListenerRequestHandler
 import org.apache.wicket.core.request.handler.ListenerRequestHandler;
 import org.apache.wicket.core.request.mapper.MountedMapper;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.pageStore.IDataStore;
 import org.apache.wicket.protocol.http.CsrfPreventionRequestCycleListener;
 import org.apache.wicket.protocol.ws.api.WebSocketMessageBroadcastHandler;
 import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
@@ -119,13 +121,21 @@ import org.wicketstuff.dashboard.WidgetRegistry;
 import org.wicketstuff.dashboard.web.DashboardContext;
 import org.wicketstuff.dashboard.web.DashboardContextInjector;
 import org.wicketstuff.dashboard.web.DashboardSettings;
+import org.wicketstuff.datastores.hazelcast.HazelcastDataStore;
+
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.Member;
+import com.hazelcast.core.MembershipEvent;
+import com.hazelcast.core.MembershipListener;
 
 public class Application extends AuthenticatedWebApplication implements IApplication {
 	private static final Logger log = getLogger(Application.class, webAppRootKey);
 	private static boolean isInstalled;
-	private static ConcurrentHashMap<String, Client> ONLINE_USERS = new ConcurrentHashMap<>();
-	private static ConcurrentHashMap<String, Client> INVALID_SESSIONS = new ConcurrentHashMap<>();
-	private static ConcurrentHashMap<Long, Set<String>> ROOMS = new ConcurrentHashMap<>();
+	private final static String ONLINE_USERS_KEY = "ONLINE_USERS_KEY";
+	private final static String INVALID_SESSIONS_KEY = "INVALID_SESSIONS_KEY";
+	private final static String ROOMS_KEY = "ROOMS_KEY";
+	private final static String STREAM_CLIENT_KEY = "STREAM_CLIENT_KEY";
 	//additional maps for faster searching should be created
 	private DashboardContext dashboardContext;
 	private static Set<String> STRINGS_WITH_APP = new HashSet<>(); //FIXME need to be removed
@@ -139,6 +149,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	public static final String NOTINIT_MAPPING = "/notinited";
 	private String xFrameOptions = HEADER_XFRAME_SAMEORIGIN;
 	private String contentSecurityPolicy = OpenmeetingsVariables.HEADER_CSP_SELF;
+	private final HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
 
 	@Override
 	protected void init() {
@@ -146,6 +157,22 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 		getSecuritySettings().setAuthenticationStrategy(new OmAuthenticationStrategy());
 		getApplicationSettings().setAccessDeniedPage(AccessDeniedPage.class);
 
+		hazelcast.getCluster().addMembershipListener(new MembershipListener() {
+			@Override
+			public void memberRemoved(MembershipEvent membershipEvent) {
+				//server down, need to remove all online clients
+			}
+
+			@Override
+			public void memberAdded(MembershipEvent membershipEvent) {
+			}
+		});
+		setPageManagerProvider(new DefaultPageManagerProvider(this) {
+			@Override
+			protected IDataStore newDataStore() {
+				return new HazelcastDataStore(hazelcast);
+			}
+		});
 		//Add custom resource loader at the beginning, so it will be checked first in the
 		//chain of Resource Loaders, if not found it will search in Wicket's internal
 		//Resource Loader for a the property key
@@ -257,9 +284,38 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 		return get().dashboardContext;
 	}
 
+	private Map<String, Client> getOnlineUsers() {
+		return hazelcast.getMap(ONLINE_USERS_KEY);
+	}
+
+	private Map<String, String> getInvalidSessions() {
+		return hazelcast.getMap(INVALID_SESSIONS_KEY);
+	}
+
+	private Map<Long, Set<String>> getRooms() {
+		return hazelcast.getMap(ROOMS_KEY);
+	}
+
+	@Override
+	public Set<Long> getActiveRoomIds() {
+		return getRooms().keySet();
+	}
+
+	@Override
+	public Map<String, StreamClient> getStreamClients() {
+		return hazelcast.getMap(STREAM_CLIENT_KEY);
+	}
+
+	@Override
+	public StreamClient update(StreamClient c) {
+		hazelcast.getMap(STREAM_CLIENT_KEY).put(c.getUid(), c);
+		return c;
+	}
+
 	public static void addOnlineUser(Client c) {
 		log.debug("Adding online client: {}, room: {}", c.getUid(), c.getRoomId());
-		ONLINE_USERS.put(c.getUid(), c);
+		c.setServerId(get().getServerId());
+		get().getOnlineUsers().put(c.getUid(), c);
 	}
 
 	public static void exitRoom(Client c) {
@@ -278,7 +334,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	@Override
 	public void exit(String uid) {
 		if (uid != null) {
-			exit(ONLINE_USERS.get(uid));
+			exit(getOnlineUsers().get(uid));
 		}
 	}
 
@@ -288,11 +344,11 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 				exitRoom(c);
 			}
 			log.debug("Removing online client: {}, room: {}", c.getUid(), c.getRoomId());
-			ONLINE_USERS.remove(c.getUid());
+			get().getOnlineUsers().remove(c.getUid());
 		}
 	}
 
-	private static boolean hasVideo(org.apache.openmeetings.db.entity.room.Client rcl) {
+	private static boolean hasVideo(StreamClient rcl) {
 		return rcl != null && rcl.getAvsettings().contains("v");
 	}
 
@@ -301,7 +357,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	}
 
 	@Override
-	public org.apache.openmeetings.db.entity.room.Client updateClient(org.apache.openmeetings.db.entity.room.Client rcl, boolean forceSize) {
+	public StreamClient updateClient(StreamClient rcl, boolean forceSize) {
 		if (rcl == null) {
 			return null;
 		}
@@ -389,7 +445,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	}
 
 	public static Client getOnlineClient(String uid) {
-		return uid == null ? null : ONLINE_USERS.get(uid);
+		return uid == null ? null : get().getOnlineUsers().get(uid);
 	}
 
 	@Override
@@ -399,7 +455,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 
 	public static boolean isUserOnline(Long userId) {
 		boolean isUserOnline = false;
-		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+		for (Map.Entry<String, Client> e : get().getOnlineUsers().entrySet()) {
 			if (e.getValue().getUserId().equals(userId)) {
 				isUserOnline = true;
 				break;
@@ -409,12 +465,12 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	}
 
 	public static List<Client> getClients() {
-		return new ArrayList<>(ONLINE_USERS.values());
+		return new ArrayList<>(get().getOnlineUsers().values());
 	}
 
 	public static List<Client> getClients(Long userId) {
 		List<Client> result =  new ArrayList<>();
-		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+		for (Map.Entry<String, Client> e : get().getOnlineUsers().entrySet()) {
 			if (e.getValue().getUserId().equals(userId)) {
 				result.add(e.getValue());
 				break;
@@ -425,7 +481,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 
 	public static Client getClientByKeys(Long userId, String sessionId) {
 		Client client = null;
-		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
+		for (Map.Entry<String, Client> e : get().getOnlineUsers().entrySet()) {
 			Client c = e.getValue();
 			if (c.getUserId().equals(userId) && c.getSessionId().equals(sessionId)) {
 				client = c;
@@ -439,27 +495,37 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	public void invalidateClient(Long userId, String sessionId) {
 		Client client = getClientByKeys(userId, sessionId);
 		if (client != null) {
-			if (!INVALID_SESSIONS.containsKey(client.getSessionId())) {
-				INVALID_SESSIONS.put(client.getSessionId(), client);
+			Map<String, String> invalid = getInvalidSessions();
+			if (!invalid.containsKey(client.getSessionId())) {
+				invalid.put(client.getSessionId(), client.getUid());
 				exit(client);
 			}
 		}
 	}
 
 	public static boolean isInvaldSession(String sessionId) {
-		return sessionId == null ? false : INVALID_SESSIONS.containsKey(sessionId);
+		return sessionId == null ? false : get().getInvalidSessions().containsKey(sessionId);
 	}
 
 	public static void removeInvalidSession(String sessionId) {
 		if (sessionId != null){
-			INVALID_SESSIONS.remove(sessionId);
+			get().getInvalidSessions().remove(sessionId);
 		}
 	}
 
+	public static Client update(Client c) {
+		get().getOnlineUsers().put(c.getUid(), c); // update in storage
+		return c;
+	}
+
 	public static Client addUserToRoom(Client c) {
 		log.debug("Adding online room client: {}, room: {}", c.getUid(), c.getRoomId());
-		ROOMS.putIfAbsent(c.getRoomId(), new ConcurrentHashSet<String>());
-		ROOMS.get(c.getRoomId()).add(c.getUid());
+		Map<Long, Set<String>> rooms = get().getRooms();
+		rooms.putIfAbsent(c.getRoomId(), new ConcurrentHashSet<String>());
+		Set<String> set = rooms.get(c.getRoomId());
+		set.add(c.getUid());
+		rooms.put(c.getRoomId(), set);
+		update(c);
 		return c;
 	}
 
@@ -467,14 +533,14 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 		Long roomId = c.getRoomId();
 		log.debug("Removing online room client: {}, room: {}", c.getUid(), roomId);
 		if (roomId != null) {
-			Set<String> clients = ROOMS.get(roomId);
+			Set<String> clients = get().getRooms().get(roomId);
 			if (clients != null) {
 				clients.remove(c.getUid());
-				c.setRoomId(null);
 			}
 			getBean(ScopeApplicationAdapter.class).roomLeaveByScope(c.getUid(), roomId);
-			c.getActivities().clear();
+			c.clearActivities();
 			c.clearRights();
+			update(c);
 		}
 		return c;
 	}
@@ -495,7 +561,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	public static List<Client> getRoomClients(Long roomId, Predicate<Client> filter) {
 		List<Client> clients = new ArrayList<>();
 		if (roomId != null) {
-			Set<String> uids = ROOMS.get(roomId);
+			Set<String> uids = get().getRooms().get(roomId);
 			if (uids != null) {
 				for (String uid : uids) {
 					Client c = getOnlineClient(uid);
@@ -510,7 +576,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 
 	public static Set<Long> getUserRooms(Long userId) {
 		Set<Long> result = new HashSet<>();
-		for (Entry<Long, Set<String>> me : ROOMS.entrySet()) {
+		for (Entry<Long, Set<String>> me : get().getRooms().entrySet()) {
 			for (String uid : me.getValue()) {
 				Client c = getOnlineClient(uid);
 				if (c != null && c.getUserId().equals(userId)) {
@@ -522,7 +588,7 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	}
 
 	public static boolean isUserInRoom(long roomId, long userId) {
-		Set<String> clients = ROOMS.get(roomId);
+		Set<String> clients = get().getRooms().get(roomId);
 		if (clients != null) {
 			for (String uid : clients) {
 				if (getOnlineClient(uid).getUserId().equals(userId)) {
@@ -706,4 +772,13 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	public void setContentSecurityPolicy(String contentSecurityPolicy) {
 		this.contentSecurityPolicy = contentSecurityPolicy;
 	}
+
+	@Override
+	public String getServerId() {
+		return hazelcast.getName();
+	}
+
+	public List<Member> getServers() {
+		return new ArrayList<>(hazelcast.getCluster().getMembers());
+	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
index 17a0a57..46dcecb 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
@@ -20,11 +20,12 @@ package org.apache.openmeetings.web.room;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getBean;
+import static org.apache.openmeetings.web.app.Application.update;
 
 import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
-import org.apache.openmeetings.core.session.SessionManager;
-import org.apache.openmeetings.db.dto.server.ClientSessionInfo;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
+import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.web.app.Application;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -32,13 +33,12 @@ import org.slf4j.Logger;
 public class RoomBroadcaster {
 	private static final Logger log = Red5LoggerFactory.getLogger(RoomBroadcaster.class, webAppRootKey);
 
-	public static Client getClient(String publicSid) {
-		ClientSessionInfo csi = getBean(SessionManager.class).getClientByPublicSIDAnyServer(publicSid);
-		return csi == null ? null : csi.getRcl();
+	public static StreamClient getClient(String publicSid) {
+		return getBean(ISessionManager.class).get(publicSid);
 	}
 
 	public static void broadcast(String publicSid, String method, Object obj) {
-		Client rc = getClient(publicSid);
+		StreamClient rc = getClient(publicSid);
 		if (rc == null) {
 			return;
 		}
@@ -50,8 +50,8 @@ public class RoomBroadcaster {
 		sa.sendToScope(roomId, method, obj);
 	}
 
-	public static void sendUpdatedClient(org.apache.openmeetings.db.entity.basic.Client client) {
-		org.apache.openmeetings.db.entity.room.Client rcl = Application.get().updateClient(getClient(client.getUid()), true);
+	public static void sendUpdatedClient(Client client) {
+		StreamClient rcl = Application.get().updateClient(getClient(client.getUid()), true);
 		log.debug("-----------  sendUpdatedClient ");
 
 		if (rcl == null) {
@@ -59,8 +59,9 @@ public class RoomBroadcaster {
 		}
 
 		// Put the mod-flag to true for this client
-		getBean(SessionManager.class).updateClientByStreamId(rcl.getStreamid(), rcl, false, null);
+		getBean(ISessionManager.class).update(rcl);
 		// Notify all clients of the same scope (room)
 		broadcast(client.getRoomId(), "clientUpdated", rcl);
+		update(client);
 	}
 }

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 341edd5..72764cd 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -24,6 +24,7 @@ import static org.apache.openmeetings.web.app.Application.exitRoom;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getOnlineClient;
 import static org.apache.openmeetings.web.app.Application.getRoomClients;
+import static org.apache.openmeetings.web.app.Application.update;
 import static org.apache.openmeetings.web.app.WebSession.getDateFormat;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
@@ -52,6 +53,7 @@ import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.room.RoomGroup;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.server.SOAPLogin;
 import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
@@ -169,7 +171,7 @@ public class RoomPanel extends BasePanel {
 	protected void onInitialize() {
 		super.onInitialize();
 		//let's refresh user in client
-		getClient().updateUser(getBean(UserDao.class));
+		update(getClient().updateUser(getBean(UserDao.class)));
 		Component accessDenied = new WebMarkupContainer(ACCESS_DENIED_ID).setVisible(false);
 		Component eventDetail = new WebMarkupContainer(EVENT_DETAILS_ID).setVisible(false);
 
@@ -342,7 +344,7 @@ public class RoomPanel extends BasePanel {
 								log.error("Not existing user has stopped recording {} !!!!", uid);
 								return;
 							}
-							c.getActivities().remove(Client.Activity.record);
+							update(c.remove(Client.Activity.record));
 						}
 						break;
 					case recordingStarted:
@@ -354,7 +356,7 @@ public class RoomPanel extends BasePanel {
 								log.error("Not existing user has started recording {} !!!!", recordingUser);
 								return;
 							}
-							c.getActivities().add(Client.Activity.record);
+							update(c.set(Client.Activity.record));
 						}
 						break;
 					case sharingStoped:
@@ -448,11 +450,13 @@ public class RoomPanel extends BasePanel {
 			SOAPLogin soap = WebSession.get().getSoapLogin();
 			if (soap != null && soap.isModerator()) {
 				c.allow(Right.superModerator);
+				update(c);
 			} else {
 				//FIXME TODO !!! c.getUser != getUserId
 				Set<Right> rr = AuthLevelUtil.getRoomRight(c.getUser(), r, r.isAppointment() ? getBean(AppointmentDao.class).getByRoom(r.getId()) : null, getRoomClients(r.getId()).size());
 				if (!rr.isEmpty()) {
 					c.allow(rr);
+					update(c);
 				}
 			}
 		}
@@ -536,7 +540,7 @@ public class RoomPanel extends BasePanel {
 				return;
 			} else {
 				// we found no-one we can ask, allow right
-				broadcast(getClient().allow(right));
+				broadcast(update(getClient().allow(right)));
 			}
 		}
 		// ask
@@ -575,6 +579,7 @@ public class RoomPanel extends BasePanel {
 
 	public void allowRight(Client client, Right... rights) {
 		client.allow(rights);
+		update(client);
 		broadcast(client);
 	}
 
@@ -588,6 +593,7 @@ public class RoomPanel extends BasePanel {
 		if (client.hasActivity(Client.Activity.broadcastV) && !client.hasRight(Right.video)) {
 			client.remove(Client.Activity.broadcastV);
 		}
+		update(client);
 		broadcast(client);
 	}
 
@@ -610,7 +616,7 @@ public class RoomPanel extends BasePanel {
 
 	public boolean screenShareAllowed() {
 		Room r = getRoom();
-		org.apache.openmeetings.db.entity.room.Client rcl = RoomBroadcaster.getClient(getMainPanel().getClient().getUid());
+		StreamClient rcl = RoomBroadcaster.getClient(getMainPanel().getClient().getUid());
 		return Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing)
 				&& r.isAllowRecording() && getClient().hasRight(Right.share)
 				&& getSharingUser() == null && rcl != null && rcl.getUserId() != null;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
index 2c537dd..b40658c 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/SwfPanel.java
@@ -26,14 +26,12 @@ import static org.apache.openmeetings.web.app.WebSession.getSid;
 import static org.apache.wicket.RuntimeConfigurationType.DEVELOPMENT;
 
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
-import org.apache.openmeetings.core.session.SessionManager;
 import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.dao.server.ServerDao;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
-import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.BasePanel;
@@ -58,6 +56,9 @@ import org.slf4j.Logger;
 
 import com.github.openjson.JSONArray;
 import com.github.openjson.JSONObject;
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.Member;
+import com.hazelcast.instance.MemberImpl;
 
 public class SwfPanel extends BasePanel {
 	private static final long serialVersionUID = 1L;
@@ -184,38 +185,45 @@ public class SwfPanel extends BasePanel {
 		return arr.toString();
 	}
 
-	private static PageParameters addServer(PageParameters pp, Server s) {
-		return pp.add("protocol", s.getProtocol()).add("host", s.getAddress()).add("port", s.getPort()).add("context", s.getWebapp());
+	private static PageParameters addServer(PageParameters pp, Member m) {
+		//TODO check this return pp.add("protocol", s.getProtocol()).add("host", s.getAddress()).add("port", s.getPort()).add("context", s.getWebapp());
+		return pp;
 	}
 
-	public static PageParameters addServer(Long roomId, boolean addBasic) {
+	private static PageParameters addServer(Long roomId, boolean addBasic) {
 		PageParameters pp = new PageParameters();
 		if (addBasic) {
 			pp.add("wicketsid", getSid()).add(WICKET_ROOM_ID, roomId).add("language", getLanguage());
 		}
-		List<Server> serverList = getBean(ServerDao.class).getActiveServers();
 
 		long minimum = -1;
-		Server result = null;
-		Map<Server, List<Long>> activeRoomsMap = new HashMap<>();
-		for (Server server : serverList) {
-			List<Long> roomIds = getBean(SessionManager.class).getActiveRoomIdsByServer(server);
+		Member result = null;
+		Map<Member, Set<Long>> activeRoomsMap = new HashMap<>();
+		for (Member _m : Application.get(). getServers()) {
+			String serverId = null;
+			MemberImpl m = (MemberImpl)_m;
+			try {
+				HazelcastInstance ins = (HazelcastInstance)MemberImpl.class.getDeclaredField("instance").get(m);
+				serverId = ins.getName();
+			} catch (Exception e) {
+				//no-op
+			}
+			Set<Long> roomIds = getBean(ISessionManager.class).getActiveRoomIds(serverId);
 			if (roomIds.contains(roomId)) {
 				// if the room is already opened on a server, redirect the user to that one,
-				log.debug("Room is already opened on a server " + server.getAddress());
-				return addServer(pp, server);
+				log.debug("Room is already opened on a server {}", m.getAddress());
+				return addServer(pp, m);
 			}
-			activeRoomsMap.put(server, roomIds);
+			activeRoomsMap.put(m, roomIds);
 		}
-		for (Map.Entry<Server, List<Long>> entry : activeRoomsMap.entrySet()) {
-			List<Long> roomIds = entry.getValue();
+		for (Map.Entry<Member, Set<Long>> entry : activeRoomsMap.entrySet()) {
+			Set<Long> roomIds = entry.getValue();
 			long capacity = getBean(RoomDao.class).getRoomsCapacityByIds(roomIds);
 			if (minimum < 0 || capacity < minimum) {
 				minimum = capacity;
 				result = entry.getKey();
 			}
-			log.debug("Checking server: " + entry.getKey() + " Number of rooms " + roomIds.size() + " RoomIds: "
-					+ roomIds + " max(Sum): " + capacity);
+			log.debug("Checking server: {} Number of rooms {} RoomIds: {} max(Sum): {}", entry.getKey(), roomIds.size(), roomIds, capacity);
 		}
 		return result == null ? pp : addServer(pp, result);
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
index 37d7115..111aa50 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
@@ -38,6 +38,7 @@ import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.room.RoomPoll;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.db.entity.user.Group;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.util.message.RoomMessage.Type;
@@ -300,13 +301,13 @@ public class RoomMenuPanel extends Panel {
 		StringBuilder roomTitle = new StringBuilder();
 		if (room.getRecordingUser() != null) {
 			ISessionManager sessMngr = getBean(ISessionManager.class);
-			org.apache.openmeetings.db.entity.room.Client recUser = sessMngr.getClientByPublicSID(room.getRecordingUser(), null); //TODO check server
+			StreamClient recUser = sessMngr.get(room.getRecordingUser());
 			if (recUser != null) {
 				roomTitle.append(String.format("%s %s %s %s %s", getString("419")
 						, recUser.getUsername(), recUser.getFirstname(), recUser.getLastname(), df.format(recUser.getConnectedSince())));
 				roomClass.append(" screen");
 			}
-			org.apache.openmeetings.db.entity.room.Client pubUser = sessMngr.getClientByPublicSID(room.getPublishingUser(), null); //TODO check server
+			StreamClient pubUser = sessMngr.get(room.getPublishingUser());
 			if (pubUser != null) {
 				if (recUser != null) {
 					roomTitle.append('\n');

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
index f37ee23..d05446d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
@@ -36,12 +36,13 @@ import java.util.Properties;
 
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.io.IOUtils;
-import org.apache.openmeetings.core.session.SessionManager;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
+import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.room.StreamClient;
 import org.apache.openmeetings.util.OmFileHelper;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
@@ -60,7 +61,7 @@ public class StartSharingButton extends OmButton {
 	private static final String CDATA_BEGIN = "<![CDATA[";
 	private static final String CDATA_END = "]]>";
 	private final AjaxDownload download;
-	private final org.apache.openmeetings.db.entity.basic.Client c;
+	private final Client c;
 	private enum Protocol {
 		rtmp
 		, rtmpe
@@ -68,7 +69,7 @@ public class StartSharingButton extends OmButton {
 		, rtmpt
 	}
 
-	public StartSharingButton(String id, org.apache.openmeetings.db.entity.basic.Client c) {
+	public StartSharingButton(String id, Client c) {
 		super(id);
 		this.c = c;
 		setOutputMarkupPlaceholderTag(true);
@@ -92,7 +93,7 @@ public class StartSharingButton extends OmButton {
 			ConfigurationDao cfgDao = getBean(ConfigurationDao.class);
 			app = IOUtils.toString(jnlp, UTF_8);
 			String publicSid = c.getUid();
-			Client rc = getClient(publicSid);
+			StreamClient rc = getClient(publicSid);
 			if (rc == null || rc.getUserId() == null) {
 				throw new RuntimeException(String.format("Unable to find client by publicSID '%s'", publicSid));
 			}
@@ -100,7 +101,7 @@ public class StartSharingButton extends OmButton {
 			URI url = new URI(_url);
 			long roomId = c.getRoomId();
 			Room room = getBean(RoomDao.class).get(roomId);
-			SessionManager sessionManager = getBean(SessionManager.class);
+			ISessionManager sessionManager = getBean(ISessionManager.class);
 			String path = url.getPath();
 			path = path.substring(path.lastIndexOf('/') + 1);
 			if (Strings.isEmpty(path) || rc.getRoomId() == null || !path.equals(rc.getRoomId().toString()) || !rc.getRoomId().equals(roomId)) {
@@ -151,7 +152,7 @@ public class StartSharingButton extends OmButton {
 		return result.toString();
 	}
 
-	private static String addKeystore(Client rc, String app, Protocol protocol) {
+	private static String addKeystore(StreamClient rc, String app, Protocol protocol) {
 		log.debug("RTMP Sharer Keystore :: start");
 		String keystore = "--dummy--", password = "--dummy--";
 		if (Protocol.rtmps == protocol) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index 46d3cfd..4f0918f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -21,6 +21,7 @@ package org.apache.openmeetings.web.room.sidebar;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.getOnlineClient;
 import static org.apache.openmeetings.web.app.Application.getRoomClients;
+import static org.apache.openmeetings.web.room.RoomBroadcaster.sendUpdatedClient;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 
@@ -34,10 +35,9 @@ import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
-import org.apache.openmeetings.web.room.RoomBroadcaster;
+import org.apache.openmeetings.web.common.NameDialog;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 import org.apache.wicket.AttributeModifier;
@@ -137,6 +137,7 @@ public class RoomSidebar extends Panel {
 								} else {
 									c.remove(Activity.broadcastA);
 								}
+								Application.update(c);
 								room.broadcast(c);
 							}
 						}
@@ -223,7 +224,7 @@ public class RoomSidebar extends Panel {
 						toggleActivity(c, Activity.broadcastAV);
 					}
 				}
-				RoomBroadcaster.sendUpdatedClient(c);
+				sendUpdatedClient(c);
 				room.broadcast(c);
 			}
 		}
@@ -393,11 +394,14 @@ public class RoomSidebar extends Panel {
 		if (c == null) {
 			return;
 		}
+		boolean updated = false;
 		if (!activityAllowed(c, a, room.getRoom()) && room.getClient().hasRight(Right.moderator)) {
 			if (a == Activity.broadcastA || a == Activity.broadcastAV) {
+				updated = true;
 				c.allow(Room.Right.audio);
 			}
 			if (!room.getRoom().isAudioOnly() && (a == Activity.broadcastV || a == Activity.broadcastAV)) {
+				updated = true;
 				c.allow(Room.Right.video);
 			}
 		}
@@ -412,6 +416,7 @@ public class RoomSidebar extends Panel {
 				return;
 			}
 			Pod pod = c.getPod();
+			updated = true;
 			c.setPod(getRequest().getRequestParameters().getParameterValue(PARAM_POD).toOptionalInteger());
 			if (pod != Pod.none && pod != c.getPod()) {
 				//pod has changed, no need to toggle
@@ -421,6 +426,9 @@ public class RoomSidebar extends Panel {
 			}
 			room.broadcast(c);
 		}
+		if (updated) {
+			Application.update(c);
+		}
 	}
 
 	public static boolean activityAllowed(Client c, Activity a, Room room) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/OmUrlFragment.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/OmUrlFragment.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/OmUrlFragment.java
index 6f74dda..9ca152f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/OmUrlFragment.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/OmUrlFragment.java
@@ -37,7 +37,6 @@ import org.apache.openmeetings.web.admin.labels.LangPanel;
 import org.apache.openmeetings.web.admin.ldaps.LdapsPanel;
 import org.apache.openmeetings.web.admin.oauth.OAuthPanel;
 import org.apache.openmeetings.web.admin.rooms.RoomsPanel;
-import org.apache.openmeetings.web.admin.servers.ServersPanel;
 import org.apache.openmeetings.web.admin.users.UsersPanel;
 import org.apache.openmeetings.web.common.BasePanel;
 import org.apache.openmeetings.web.room.RoomPanel;
@@ -67,7 +66,6 @@ public class OmUrlFragment implements Serializable {
 	public static final String TYPE_LANG = "lang";
 	public static final String TYPE_LDAP = "ldap";
 	public static final String TYPE_BACKUP = "backup";
-	public static final String TYPE_SERVER = "server";
 	public static final String TYPE_OAUTH2 = "oauth2";
 	public static final String TYPE_EMAIL = "email";
 	public static final OmUrlFragment DASHBOARD = new OmUrlFragment(AreaKeys.user, TYPE_DASHBOARD);
@@ -100,7 +98,6 @@ public class OmUrlFragment implements Serializable {
 		, adminModuleLanguages
 		, adminModuleLDAP
 		, adminModuleBackup
-		, adminModuleServers
 		, adminModuleOAuth
 		, adminModuleEmail
 	}
@@ -198,10 +195,6 @@ public class OmUrlFragment implements Serializable {
 				setArea(AreaKeys.admin);
 				setType(TYPE_BACKUP);
 				break;
-			case adminModuleServers:
-				setArea(AreaKeys.admin);
-				setType(TYPE_SERVER);
-				break;
 			case adminModuleOAuth:
 				setArea(AreaKeys.admin);
 				setType(TYPE_OAUTH2);
@@ -249,8 +242,6 @@ public class OmUrlFragment implements Serializable {
 					basePanel = new LdapsPanel(CHILD_ID);
 				} else if (TYPE_BACKUP.equals(type)) {
 					basePanel = new BackupPanel(CHILD_ID);
-				} else if (TYPE_SERVER.equals(type)) {
-					basePanel = new ServersPanel(CHILD_ID);
 				} else if (TYPE_OAUTH2.equals(type)) {
 					basePanel = new OAuthPanel(CHILD_ID);
 				} else if (TYPE_EMAIL.equals(type)) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
index 46fc2ef..9d68e0d 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/db2_persistence.xml
@@ -32,7 +32,6 @@
 		<class>org.apache.openmeetings.db.entity.basic.Navimain</class>
 		<class>org.apache.openmeetings.db.entity.server.Sessiondata</class>
 		<class>org.apache.openmeetings.db.entity.server.SOAPLogin</class>
-		<class>org.apache.openmeetings.db.entity.server.Server</class>
 		<class>org.apache.openmeetings.db.entity.calendar.Appointment</class>
 		<class>org.apache.openmeetings.db.entity.calendar.MeetingMember</class>
 		<class>org.apache.openmeetings.db.entity.calendar.OmCalendar</class>
@@ -46,7 +45,6 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
index c6a6d9c..f0600aa 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/derby_persistence.xml
@@ -32,7 +32,6 @@
 		<class>org.apache.openmeetings.db.entity.basic.Navimain</class>
 		<class>org.apache.openmeetings.db.entity.server.Sessiondata</class>
 		<class>org.apache.openmeetings.db.entity.server.SOAPLogin</class>
-		<class>org.apache.openmeetings.db.entity.server.Server</class>
 		<class>org.apache.openmeetings.db.entity.calendar.Appointment</class>
 		<class>org.apache.openmeetings.db.entity.calendar.MeetingMember</class>
 		<class>org.apache.openmeetings.db.entity.calendar.OmCalendar</class>
@@ -46,7 +45,6 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
index 61060be..1d1fce9 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mssql_persistence.xml
@@ -32,7 +32,6 @@
 		<class>org.apache.openmeetings.db.entity.basic.Navimain</class>
 		<class>org.apache.openmeetings.db.entity.server.Sessiondata</class>
 		<class>org.apache.openmeetings.db.entity.server.SOAPLogin</class>
-		<class>org.apache.openmeetings.db.entity.server.Server</class>
 		<class>org.apache.openmeetings.db.entity.calendar.Appointment</class>
 		<class>org.apache.openmeetings.db.entity.calendar.MeetingMember</class>
 		<class>org.apache.openmeetings.db.entity.calendar.OmCalendar</class>
@@ -46,7 +45,6 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.Whiteboard</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
index fc79038..34128ef 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/mysql_persistence.xml
@@ -32,7 +32,6 @@
 		<class>org.apache.openmeetings.db.entity.basic.Navimain</class>
 		<class>org.apache.openmeetings.db.entity.server.Sessiondata</class>
 		<class>org.apache.openmeetings.db.entity.server.SOAPLogin</class>
-		<class>org.apache.openmeetings.db.entity.server.Server</class>
 		<class>org.apache.openmeetings.db.entity.calendar.Appointment</class>
 		<class>org.apache.openmeetings.db.entity.calendar.MeetingMember</class>
 		<class>org.apache.openmeetings.db.entity.calendar.OmCalendar</class>
@@ -46,7 +45,6 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
index 1aca2ae..0105a43 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/oracle_persistence.xml
@@ -32,7 +32,6 @@
 		<class>org.apache.openmeetings.db.entity.basic.Navimain</class>
 		<class>org.apache.openmeetings.db.entity.server.Sessiondata</class>
 		<class>org.apache.openmeetings.db.entity.server.SOAPLogin</class>
-		<class>org.apache.openmeetings.db.entity.server.Server</class>
 		<class>org.apache.openmeetings.db.entity.calendar.Appointment</class>
 		<class>org.apache.openmeetings.db.entity.calendar.MeetingMember</class>
 		<class>org.apache.openmeetings.db.entity.calendar.OmCalendar</class>
@@ -46,7 +45,6 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
index a9ae783..2cab5de 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/META-INF/postgresql_persistence.xml
@@ -32,7 +32,6 @@
 		<class>org.apache.openmeetings.db.entity.basic.Navimain</class>
 		<class>org.apache.openmeetings.db.entity.server.Sessiondata</class>
 		<class>org.apache.openmeetings.db.entity.server.SOAPLogin</class>
-		<class>org.apache.openmeetings.db.entity.server.Server</class>
 		<class>org.apache.openmeetings.db.entity.calendar.Appointment</class>
 		<class>org.apache.openmeetings.db.entity.calendar.MeetingMember</class>
 		<class>org.apache.openmeetings.db.entity.calendar.OmCalendar</class>
@@ -46,7 +45,6 @@
 		<class>org.apache.openmeetings.db.entity.log.ConferenceLog</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPoll</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomPollAnswer</class>
-		<class>org.apache.openmeetings.db.entity.room.Client</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomModerator</class>
 		<class>org.apache.openmeetings.db.entity.room.Room</class>
 		<class>org.apache.openmeetings.db.entity.room.RoomGroup</class>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
index ecc1248..9c95d2b 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
@@ -40,37 +40,13 @@
 	<context:annotation-config />
 	<context:component-scan base-package="org.apache.openmeetings" />
 
-	<!-- New Class for the Streaming Handlers -->
 	<bean id="web.handler" class="org.apache.openmeetings.core.remote.ScopeApplicationAdapter" />
 
-	<!-- Session configuration start -->
-
-	<bean id="openmeetings.SessionManager" class="org.apache.openmeetings.core.session.SessionManager">
-		<property name="cache">
-			<!-- Memory based session cache by default -->
-			<ref bean="openmeetings.HashMapStore" />
-			<!-- The following section should be used in clustering mode
-			<ref bean="openmeetings.DatabaseStore" />
-			-->
-		</property>
-	</bean>
-
-	<!-- Singleton for memory based cache -->
-	<bean id="openmeetings.HashMapStore" scope="singleton" class="org.apache.openmeetings.core.session.store.HashMapStore" />
-	<!-- Database cache -->
-	<bean id="openmeetings.DatabaseStore" class="org.apache.openmeetings.core.session.store.DatabaseStore" />
+	<bean id="openmeetings.SessionManager" class="org.apache.openmeetings.core.session.SessionManager"/>
 	
 	<bean id="whiteboardCache" scope="singleton" class="org.apache.openmeetings.core.data.whiteboard.WhiteboardCache" />
-	<!-- WhiteboardObjectSyncManager can stay in the memory, even on cluster! -->
 	<bean id="whiteboardObjectSyncManager" scope="singleton" class="org.apache.openmeetings.core.data.whiteboard.WhiteboardObjectSyncManager" />
 
-	<!-- Cluster related config start -->
-	<bean id="openmeetings.ServerUtil" scope="singleton" class="org.apache.openmeetings.core.session.ServerUtil">
-		<!-- Need to be uncommented and set to the real ID if in cluster mode
-		<property name="serverId" value="1" />
-		-->
-	</bean>
-
 	<!-- Start of Services -->
 	<bean id="xmlcrm.service" class="org.apache.openmeetings.core.remote.MainService" />
 	<bean id="languageservice.service" class="org.apache.openmeetings.core.remote.LanguageService" />
@@ -86,7 +62,6 @@
 	<bean id="openmeetings.InterviewConverterTask" class="org.apache.openmeetings.core.data.record.converter.InterviewConverterTask" />
 	<bean id="openmeetings.InterviewConverter" class="org.apache.openmeetings.core.converter.InterviewConverter" />
 	<bean id="openmeetings.RecordingConverter" class="org.apache.openmeetings.core.converter.RecordingConverter" />
-	<bean id="openmeetings.SlaveHTTPConnectionManager" class="org.apache.openmeetings.webservice.cluster.SlaveHTTPConnectionManager" />
 
 	<!--
 			5000		== 5 sec
@@ -204,9 +179,7 @@
 	<bean id="soapLoginDao" class="org.apache.openmeetings.db.dao.server.SOAPLoginDao" />
 	<bean id="userContactDao" class="org.apache.openmeetings.db.dao.user.UserContactDao" />
 	<bean id="userDao" class="org.apache.openmeetings.db.dao.user.UserDao" />
-	<bean id="serverDao" class="org.apache.openmeetings.db.dao.server.ServerDao" />
 	<bean id="chatDao" class="org.apache.openmeetings.db.dao.basic.ChatDao" />
-	<bean id="clientDao" class="org.apache.openmeetings.db.dao.room.ClientDao" />
 	<bean id="mailMessageDao" class="org.apache.openmeetings.db.dao.basic.MailMessageDao" />
 	<bean id="oauth2Dao" class="org.apache.openmeetings.db.dao.server.OAuth2Dao" />
 	<bean id="omCalendarDao" class="org.apache.openmeetings.db.dao.calendar.OmCalendarDao" />

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/cxf-servlet.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/cxf-servlet.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/cxf-servlet.xml
index 3fc11be..6387bad 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/cxf-servlet.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/cxf-servlet.xml
@@ -38,7 +38,6 @@
 	<bean id="infoWebService" class="org.apache.openmeetings.webservice.InfoWebService" />
 	<bean id="recordWebService" class="org.apache.openmeetings.webservice.RecordingWebService" />
 	<bean id="roomWebService" class="org.apache.openmeetings.webservice.RoomWebService" />
-	<bean id="serverWebService" class="org.apache.openmeetings.webservice.ServerWebService" />
 	<bean id="userWebService" class="org.apache.openmeetings.webservice.UserWebService"/>
 	<bean id="netTestWebService" class="org.apache.openmeetings.webservice.NetTestWebService" />
 
@@ -52,7 +51,6 @@
 			<ref bean="infoWebService"/>
 			<ref bean="recordWebService"/>
 			<ref bean="roomWebService"/>
-			<ref bean="serverWebService"/>
 			<ref bean="userWebService"/>
 			<ref bean="netTestWebService"/> <!-- JaxRs only -->
 		</jaxrs:serviceBeans>
@@ -69,6 +67,5 @@
 	<jaxws:endpoint id="fileServiceWS" address="/FileService" implementor="#fileWebService" />
 	<jaxws:endpoint id="recordServiceWS" address="/RecordService" implementor="#recordWebService" />
 	<jaxws:endpoint id="roomServiceWS" address="/RoomService" implementor="#roomWebService" />
-	<jaxws:endpoint id="serverServiceWS" address="/ServerService" implementor="#serverWebService" />
 	<jaxws:endpoint id="userServiceWS" address="/UserService" implementor="#userWebService" />
 </beans>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/hazelcast.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/hazelcast.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/hazelcast.xml
new file mode 100644
index 0000000..dfb8d92
--- /dev/null
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/hazelcast.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+
+-->
+<hazelcast
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns="http://www.hazelcast.com/schema/config"
+		xsi:schemaLocation="http://www.hazelcast.com/schema/config https://hazelcast.com/schema/config/hazelcast-config-3.9.xsd"
+	>
+	<instance-name>server-1</instance-name><!-- MAKE SURE THIS ONE IS UNIQUE -->
+	<!--network>
+		<interfaces enabled="true">
+			<interface>192.168.1.*</interface>
+		</interfaces>
+	</network-->
+</hazelcast>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml
index 2106686..3c55b02 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/logback-config.xml
@@ -7,18 +7,17 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-  
+
       http://www.apache.org/licenses/LICENSE-2.0
-    	  
+
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
-  
--->
 
+-->
 <configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 	<contextName>${current_openmeetings_context_name}</contextName>
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel-remote.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel-remote.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel-remote.xml
index 0dce654..25f4a7f 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel-remote.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel-remote.xml
@@ -7,16 +7,16 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-  
+
       http://www.apache.org/licenses/LICENSE-2.0
-    	  
+
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
-  
+
 -->
 <rebel-remote>
 	<id>Openmeetings</id>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel.xml
index 747b192..a693fbe 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/rebel.xml
@@ -7,16 +7,16 @@
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
-  
+
       http://www.apache.org/licenses/LICENSE-2.0
-  
+
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
-  
+
 -->
 <application
 		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/test/java/org/apache/openmeetings/test/poll/TestClientListManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/test/poll/TestClientListManager.java b/openmeetings-web/src/test/java/org/apache/openmeetings/test/poll/TestClientListManager.java
deleted file mode 100644
index c5e1b36..0000000
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/test/poll/TestClientListManager.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License") +  you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openmeetings.test.poll;
-
-import static org.junit.Assert.assertNotNull;
-
-import java.util.Random;
-
-import org.apache.openmeetings.db.dao.server.ISessionManager;
-import org.apache.openmeetings.test.AbstractJUnitDefaults;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class TestClientListManager extends AbstractJUnitDefaults {
-	@Autowired
-	private ISessionManager sessionManager;
-	
-	@Test
-	public void addClientListItem() {
-		Random rnd = new Random();
-		assertNotNull("RoomClientId created is null",
-				sessionManager.addClientListItem(rnd.nextLong() + "ABCDE"
-						+ rnd.nextLong(), "scopeName", 66666, "remoteAddress",
-						"swfUrl", null));
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java
deleted file mode 100644
index 720a7fc..0000000
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSession.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License") +  you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openmeetings.test.session;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.List;
-
-import org.apache.openmeetings.db.dao.room.ClientDao;
-import org.apache.openmeetings.db.dao.server.ServerDao;
-import org.apache.openmeetings.db.entity.room.Client;
-import org.apache.openmeetings.db.entity.server.Server;
-import org.apache.openmeetings.test.AbstractJUnitDefaults;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
-import org.junit.Test;
-import org.red5.logging.Red5LoggerFactory;
-import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class TestDbSession extends AbstractJUnitDefaults {
-	protected static final Logger log = Red5LoggerFactory.getLogger(TestDbSession.class, webAppRootKey);
-
-	@Autowired
-	private ServerDao serverDao;
-
-	@Autowired
-	private ClientDao clientDao;
-
-	@Test
-	public void testDbSessionFunctions() {
-		clientDao.cleanAllClients();
-		
-		List<Server> serverList = serverDao.getActiveServers();
-
-		Server server = null;
-		if (serverList.size() > 0) {
-			server = serverList.get(0);
-		} else {
-			server = new Server();
-			server.setName("Test Server");
-			server.setActive(true);
-			serverDao.update(server, null);
-		}
-
-		Client cl1 = new Client();
-		cl1.setStreamid("1");
-		cl1.setServer(null);
-		cl1.setUserId(1L);
-		cl1.setRoomId(1L);
-		cl1.setPublicSID("public1");
-		clientDao.add(cl1);
-
-		Client cl2 = new Client();
-		cl2.setStreamid("2");
-		cl2.setServer(null);
-		cl2.setRoomId(1L);
-		cl2.setUserId(2L);
-		cl2.setPublicSID("public2");
-		clientDao.add(cl2);
-
-		Client cl3 = new Client();
-		cl3.setStreamid("3");
-		cl3.setServer(server);
-		cl3.setRoomId(3L);
-		cl3.setUserId(3L);
-		cl3.setPublicSID("public3");
-		clientDao.add(cl3);
-		
-		Client clTest = clientDao.getClientByServerAndStreamId(null, "1");
-
-		log.debug("cl1 " + cl1);
-		log.debug("clTest " + clTest);
-
-		assertEquals(clTest.getId(), cl1.getId());
-
-		Client clTest3 = clientDao.getClientByServerAndStreamId(server, "3");
-
-		log.debug("cl3 " + cl3);
-		log.debug("clTest3 " + clTest3);
-
-		assertEquals(clTest3.getId(), cl3.getId());
-
-		Client clTest_NOT_3 = clientDao.getClientByServerAndStreamId(null, "3");
-
-		log.debug("clTest_NOT_3 " + clTest_NOT_3);
-		assertEquals(null, clTest_NOT_3);
-		
-		long numberOfClients1 = clientDao.countClientsByServerAndStreamId(null, "1");
-		assertEquals(1, numberOfClients1);
-		
-		long numberOfClients3 = clientDao.countClientsByServerAndStreamId(server, "3");
-		assertEquals(1, numberOfClients3);
-		
-		long numberOfClients4 = clientDao.countClientsByServerAndStreamId(null, "3");
-		assertEquals(0, numberOfClients4);
-		
-		List<Client> clTest_Pub_1_list = clientDao.getClientsByPublicSIDAndServer(null, "public1");
-		assertEquals(cl1.getId(), clTest_Pub_1_list.get(0).getId());
-		
-		List<Client> clTest_Pub_3_list = clientDao.getClientsByPublicSIDAndServer(server, "public3");
-		assertEquals(cl3.getId(), clTest_Pub_3_list.get(0).getId());
-		
-		List<Client> clTest_Fail_list = clientDao.getClientsByPublicSIDAndServer(null, "public3");
-		assertEquals(0, clTest_Fail_list.size());
-		
-		List<Client> clTest_PubAll_1_list = clientDao.getClientsByPublicSID("public1");
-		assertEquals(cl1.getId(), clTest_PubAll_1_list.get(0).getId());
-		
-		List<Client> clTest_PubAll_3_list = clientDao.getClientsByPublicSID("public3");
-		assertEquals(cl3.getId(), clTest_PubAll_3_list.get(0).getId());
-		
-		List<Client> clTest_FailAll_list = clientDao.getClientsByPublicSID("public4");
-		assertEquals(0, clTest_FailAll_list.size());
-		
-		List<Client> clientsByServerNull = clientDao.getClientsByServer(null);
-		assertEquals(2, clientsByServerNull.size());
-		
-		List<Client> clientsByServer = clientDao.getClientsByServer(server);
-		assertEquals(1, clientsByServer.size());
-		
-		List<Client> clientsAll = clientDao.getClients();
-		assertEquals(3, clientsAll.size());
-		
-		//by userid
-		List<Client> clTest_User_1_list = clientDao.getClientsByUserId(null, 1L);
-		assertEquals(cl1.getId(), clTest_User_1_list.get(0).getId());
-		
-		List<Client> clTest_User_3_list = clientDao.getClientsByUserId(server, 3L);
-		assertEquals(cl3.getId(), clTest_User_3_list.get(0).getId());
-		
-		List<Client> clTest_UserFail_list = clientDao.getClientsByUserId(null, 3L);
-		assertEquals(0, clTest_UserFail_list.size());
-		
-		//by roomid
-		List<Client> clTest_Room_1_list = clientDao.getClientsByRoomId(1L);
-		assertEquals(2, clTest_Room_1_list.size());
-		
-		List<Client> clTest_Room_3_list = clientDao.getClientsByRoomId(3L);
-		assertEquals(cl3.getId(), clTest_Room_3_list.get(0).getId());
-		
-		List<Client> clTest_RoomFail_list = clientDao.getClientsByRoomId(2L);
-		assertEquals(0, clTest_RoomFail_list.size());
-		
-		//count all
-		int countAll = clientDao.countClients();
-		assertEquals(3, countAll);
-		
-		//count by server
-		int clTest_Count_1_list = clientDao.countClientsByServer(null);
-		assertEquals(2, clTest_Count_1_list);
-		
-		int clTest_Count_3_list = clientDao.countClientsByServer(server);
-		assertEquals(1, clTest_Count_3_list);
-		
-		//remove by id
-		clientDao.delete(cl1);
-		
-		int clTest_Count_Delete_list = clientDao.countClientsByServer(null);
-		assertEquals(1, clTest_Count_Delete_list);
-		
-		//remove by server and streamid
-		clientDao.removeClientByServerAndStreamId(null, "2");
-		
-		clTest_Count_Delete_list = clientDao.countClientsByServer(null);
-		assertEquals(0, clTest_Count_Delete_list);
-		
-		clientDao.removeClientByServerAndStreamId(server, "3");
-		
-		clTest_Count_Delete_list = clientDao.countClientsByServer(server);
-		assertEquals(0, clTest_Count_Delete_list);
-		
-		//delete all
-		clientDao.cleanAllClients();
-
-		countAll = clientDao.countClients();
-		assertEquals(0, countAll);
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java
deleted file mode 100644
index 30a0ec1..0000000
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestDbSessionGetRoomIds.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License") +  you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openmeetings.test.session;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.List;
-
-import org.apache.openmeetings.db.dao.room.ClientDao;
-import org.apache.openmeetings.db.dao.server.ServerDao;
-import org.apache.openmeetings.db.entity.room.Client;
-import org.apache.openmeetings.db.entity.server.Server;
-import org.apache.openmeetings.test.AbstractJUnitDefaults;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
-import org.junit.Test;
-import org.red5.logging.Red5LoggerFactory;
-import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class TestDbSessionGetRoomIds extends AbstractJUnitDefaults {
-	protected static final Logger log = Red5LoggerFactory.getLogger(TestDbSessionGetRoomIds.class, webAppRootKey);
-
-	@Autowired
-	private ServerDao serverDao;
-
-	@Autowired
-	private ClientDao clientDao;
-
-	@Test
-	public void testDbSessionFunctions() {
-		clientDao.cleanAllClients();
-		
-		List<Server> serverList = serverDao.getActiveServers();
-
-		Server server = null;
-		if (serverList.size() > 0) {
-			server = serverList.get(0);
-		} else {
-			server = new Server();
-			server.setName("Test Server");
-			server.setActive(true);
-			serverDao.update(server, null);
-		}
-
-		Client cl1 = new Client();
-		cl1.setStreamid("1");
-		cl1.setServer(server);
-		cl1.setUserId(1L);
-		cl1.setRoomId(1L);
-		cl1.setPublicSID("public1");
-		clientDao.add(cl1);
-
-		Client cl2 = new Client();
-		cl2.setStreamid("2");
-		cl2.setServer(server);
-		cl2.setRoomId(1L);
-		cl2.setUserId(2L);
-		cl2.setPublicSID("public2");
-		clientDao.add(cl2);
-
-		Client cl3 = new Client();
-		cl3.setStreamid("3");
-		cl3.setServer(server);
-		cl3.setRoomId(3L);
-		cl3.setUserId(3L);
-		cl3.setPublicSID("public3");
-		clientDao.add(cl3);
-		
-		List<Long> roomids = clientDao.getRoomsIdsByServer(server);
-
-		assertEquals(2, roomids.size());
-		
-		//delete all
-		clientDao.cleanAllClients();
-
-		int countAll = clientDao.countClients();
-		assertEquals(0, countAll);
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java b/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java
deleted file mode 100644
index e3dd291..0000000
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/test/session/TestHashMapSession.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License") +  you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openmeetings.test.session;
-
-import static org.junit.Assert.assertEquals;
-
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Random;
-
-import org.apache.openmeetings.core.session.store.HashMapStore;
-import org.apache.openmeetings.core.session.store.IClientPersistenceStore;
-import org.apache.openmeetings.db.entity.room.Client;
-import org.apache.openmeetings.test.AbstractJUnitDefaults;
-import org.apache.openmeetings.util.OpenmeetingsVariables;
-import org.apache.openmeetings.util.crypt.CryptProvider;
-import org.junit.Test;
-import org.red5.logging.Red5LoggerFactory;
-import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class TestHashMapSession extends AbstractJUnitDefaults {
-	
-	protected static final Logger log = Red5LoggerFactory.getLogger(
-			TestHashMapSession.class, OpenmeetingsVariables.webAppRootKey);
-	
-	@Autowired
-	private HashMapStore cache;
-	
-	@Test
-	public void testHashMapSession() {
-		
-		//make sure the cache is empty before starting the test
-		cache.clear();
-		
-		for (int i=0;i<20;i++) {
-			
-			String streamId = ""+i;
-			
-			Client rcm = new Client();
-			rcm.setConnectedSince(new Date());
-			rcm.setStreamid(streamId);
-			rcm.setScope("scopeName");
-			long random = System.currentTimeMillis() + new BigInteger(256, new Random()).longValue();
-			
-			rcm.setPublicSID(CryptProvider.get().hash(String.valueOf(random).toString()));
-
-			rcm.setUserport(0);
-			rcm.setUserip("remoteAddress");
-			rcm.setSwfurl("swfUrl");
-			rcm.setIsMod(false);
-			rcm.setCanDraw(false);
-
-			if (cache.containsKey(null, streamId)) {
-				log.error("Tried to add an existing Client " + streamId);
-				break;
-			}
-
-			cache.put(rcm.getStreamid(), rcm);
-			
-			cache.remove(null, streamId);
-		
-		}
-		
-		String logString = cache.getDebugInformation(Arrays.asList(IClientPersistenceStore.DEBUG_DETAILS.SIZE));
-		
-		
-		log.debug("######## \n\r "+ logString + " \n\r ########");
-		
-		assertEquals(0, cache.size());
-		
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
----------------------------------------------------------------------
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
index 29e1174..ee17762 100644
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
+++ b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
@@ -43,6 +43,7 @@ import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.room.InvitationDao;
 import org.apache.openmeetings.db.dao.room.RoomDao;
+import org.apache.openmeetings.db.dao.user.IUserManager;
 import org.apache.openmeetings.db.dto.basic.ServiceResult;
 import org.apache.openmeetings.db.dto.basic.ServiceResult.Type;
 import org.apache.openmeetings.db.dto.room.InvitationDTO;
@@ -55,7 +56,6 @@ import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
 import org.apache.openmeetings.service.room.InvitationManager;
-import org.apache.openmeetings.service.user.UserManager;
 import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.webservice.error.ServiceException;
@@ -387,7 +387,7 @@ public class RoomWebService extends BaseWebService {
 	public ServiceResult kick(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) throws ServiceException {
 		try {
 			if (AuthLevelUtil.hasWebServiceLevel(getRights(sid))) {
-				boolean result = getBean(UserManager.class).kickUserByStreamId(sid, id);
+				boolean result = getBean(IUserManager.class).kickUsersByRoomId(sid, id);
 				return new ServiceResult(result ? 1L : 0L, "Kicked", Type.SUCCESS);
 			} else {
 				throw new ServiceException("Insufficient permissions"); //TODO code -26

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/ca559564/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/ServerWebService.java
----------------------------------------------------------------------
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/ServerWebService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/ServerWebService.java
deleted file mode 100644
index 7c66512..0000000
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/ServerWebService.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License") +  you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openmeetings.webservice;
-
-import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
-import static org.apache.openmeetings.webservice.Constants.TNS;
-
-import java.util.List;
-
-import javax.jws.WebMethod;
-import javax.jws.WebParam;
-import javax.jws.WebService;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-
-import org.apache.cxf.feature.Features;
-import org.apache.openmeetings.db.dao.server.ServerDao;
-import org.apache.openmeetings.db.dto.basic.ServiceResult;
-import org.apache.openmeetings.db.dto.basic.ServiceResult.Type;
-import org.apache.openmeetings.db.dto.server.ServerDTO;
-import org.apache.openmeetings.db.entity.server.Server;
-import org.apache.openmeetings.db.entity.server.Sessiondata;
-import org.apache.openmeetings.db.util.AuthLevelUtil;
-import org.apache.openmeetings.webservice.error.ServiceException;
-import org.red5.logging.Red5LoggerFactory;
-import org.slf4j.Logger;
-
-/**
- * This class provides method implementations necessary for OM to manage servers
- * participating in cluster.
- *
- * @author solomax, sebawagner
- *
- */
-@WebService(serviceName="org.apache.openmeetings.webservice.ServerWebService", targetNamespace = TNS)
-@Features(features = "org.apache.cxf.feature.LoggingFeature")
-@Produces({MediaType.APPLICATION_JSON})
-@Path("/server")
-public class ServerWebService extends BaseWebService {
-	private static final Logger log = Red5LoggerFactory.getLogger(ServerWebService.class, webAppRootKey);
-
-	private static ServerDao getDao() {
-		return getBean(ServerDao.class);
-	}
-
-	/**
-	 * Method to retrieve the list of the servers participating in cluster
-	 *
-	 * @param sid
-	 *            - session id to identify the user making request
-	 * @param start
-	 *            - server index to start with
-	 * @param max
-	 *            - Maximum server count
-	 * @return The list of servers participating in cluster
-	 */
-	@WebMethod
-	@GET
-	@Path("/{start}/{max}")
-	public List<ServerDTO> getServers(@QueryParam("sid") @WebParam(name="sid") String sid
-			, @PathParam("start") @WebParam(name="start") int start
-			, @PathParam("max") @WebParam(name="max") int max
-			) throws ServiceException
-	{
-		log.debug("getServers enter");
-		if (AuthLevelUtil.hasWebServiceLevel(getRights(sid))) {
-			return ServerDTO.list(getDao().get(start, max));
-		} else {
-			log.warn("Insuffisient permissions");
-			throw new ServiceException("Insufficient permissions"); //TODO code -26
-		}
-	}
-
-	/**
-	 * Method to retrieve the total count of the servers participating in
-	 * cluster
-	 *
-	 * @param sid
-	 *            - session id to identify the user making request
-	 * @return total count of the servers participating in cluster
-	 */
-	@WebMethod
-	@GET
-	@Path("/count")
-	public long count(@QueryParam("sid") @WebParam(name="sid") String sid) throws ServiceException {
-		log.debug("getServerCount enter");
-		if (AuthLevelUtil.hasWebServiceLevel(getRights(sid))) {
-			return getDao().count();
-		} else {
-			throw new ServiceException("Insufficient permissions"); //TODO code -26
-		}
-	}
-
-	/**
-	 * Method to add/update server
-	 *
-	 * @param sid
-	 *            - session id to identify the user making request
-	 * @param server
-	 *            - server to add/update
-	 * @return the id of saved server
-	 */
-	@WebMethod
-	@POST
-	@Path("/")
-	public ServerDTO add(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="server") @QueryParam("server") ServerDTO server) throws ServiceException {
-		log.debug("saveServerCount enter");
-		Sessiondata sd = check(sid);
-		Long userId = sd.getUserId();
-		if (AuthLevelUtil.hasWebServiceLevel(getRights(userId))) {
-			Server s = server.get();
-			return new ServerDTO(getDao().update(s, userId));
-		} else {
-			log.warn("Insuffisient permissions");
-			throw new ServiceException("Insufficient permissions"); //TODO code -26
-		}
-	}
-
-	/**
-	 * Method to delete server
-	 *
-	 * @param sid
-	 *            - session id to identify the user making request
-	 * @param id
-	 *            - the id of the server to delete
-	 * @return true if the server was deleted, false otherwise
-	 */
-	@WebMethod
-	@DELETE
-	@Path("/{id}")
-	public ServiceResult delete(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) throws ServiceException {
-		log.debug("saveServerCount enter");
-		Sessiondata sd = check(sid);
-		Long userId = sd.getUserId();
-
-		if (AuthLevelUtil.hasWebServiceLevel(getRights(userId))) {
-			ServerDao serverDao = getDao();
-			Server s = serverDao.get(id);
-			if (s != null) {
-				serverDao.delete(s, userId);
-				return new ServiceResult(id, "Deleted", Type.SUCCESS);
-			}
-			return new ServiceResult(0L, "Not found", Type.SUCCESS);
-		} else {
-			log.warn("Insuffisient permissions");
-			throw new ServiceException("Insufficient permissions"); //TODO code -26
-		}
-	}
-}