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/31 13:31:28 UTC

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

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/server/Server.java
----------------------------------------------------------------------
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/server/Server.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/server/Server.java
deleted file mode 100644
index 046bc92..0000000
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/server/Server.java
+++ /dev/null
@@ -1,304 +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.db.entity.server;
-
-import java.util.Calendar;
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.Lob;
-import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.apache.openjpa.persistence.jdbc.ForeignKey;
-import org.apache.openmeetings.db.entity.IDataProviderEntity;
-import org.apache.openmeetings.db.entity.user.User;
-import org.simpleframework.xml.Element;
-import org.simpleframework.xml.Root;
-
-@Entity
-@NamedQueries({
-		@NamedQuery(name = "getAllServers", query = "SELECT s FROM Server s WHERE s.deleted = false ORDER BY s.id"),
-		@NamedQuery(name = "getServerCount", query = "SELECT COUNT(s) FROM Server s WHERE s.deleted = false"),
-		@NamedQuery(name = "getServerById", query = "SELECT s FROM Server s LEFT JOIN FETCH s.insertedby LEFT JOIN FETCH s.updatedby WHERE s.deleted = false AND s.id = :id"),
-		@NamedQuery(name = "getServerByName", query = "SELECT s FROM Server s WHERE s.deleted = false AND s.name LIKE :name"),
-		@NamedQuery(name = "getServerByAddress", query = "SELECT s FROM Server s WHERE s.deleted = false AND s.address LIKE :address"),
-		@NamedQuery(name = "getServersWithNoUsers", query = "SELECT s FROM Server s WHERE s.deleted = false AND s.id NOT IN (SELECT u.server.id FROM User u where u.server.id IS NOT NULL)"),
-		@NamedQuery(name = "getServerWithMinimumUsers", query = "SELECT s.id, COUNT(u) AS cnt FROM User u JOIN u.server s WHERE s.deleted = false GROUP BY s.id ORDER BY cnt"),
-		@NamedQuery(name = "getActiveServers", query = "SELECT s FROM Server s WHERE s.deleted = false AND s.active = true") //
-})
-@Table(name = "server")
-@Root
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-public class Server implements IDataProviderEntity {
-	private static final long serialVersionUID = 1L;
-
-	@Id
-	@GeneratedValue(strategy = GenerationType.IDENTITY)
-	@Column(name = "id")
-	@Element(data = true)
-	private Long id;
-
-	@Column(name = "name")
-	@Element(data = true)
-	private String name;
-
-	@Column(name = "address")
-	@Element(data = true)
-	private String address;
-
-	@Column(name = "inserted")
-	public Date inserted;
-
-	@Column(name = "updated")
-	public Date updated;
-
-	@ManyToOne(fetch = FetchType.LAZY)
-	@JoinColumn(name = "insertedby_id", updatable = true, insertable = true)
-	@ForeignKey(enabled = true)
-	public User insertedby;
-
-	@ManyToOne(fetch = FetchType.LAZY)
-	@JoinColumn(name = "updatedby_id", updatable = true, insertable = true)
-	@ForeignKey(enabled = true)
-	public User updatedby;
-
-	@Lob
-	@Column(name = "comment", length = 2048)
-	@Element(data = true, required = false)
-	private String comment;
-
-	@Column(name = "last_ping", nullable = true)
-	@Element(data = true, required = false)
-	private Calendar lastPing;
-	
-	@Column(name = "port", nullable = true)
-	@Element(data = true, required = false)
-	private int port;
-
-	@Column(name = "protocol", nullable = true)
-	@Element(data = true, required = false)
-	private String protocol;
-
-	@Column(name = "webapp", nullable = true)
-	@Element(data = true, required = false)
-	private String webapp;
-
-	@Column(name = "login", nullable = true)
-	@Element(data = true, required = false)
-	private String user;
-
-	@Column(name = "pass", nullable = true)
-	@Element(data = true, required = false)
-	private String pass;
-
-	@Column(name = "active", nullable = false)
-	@Element(data = true, required = false)
-	private boolean active;
-	
-	@Column(name = "deleted", nullable = false)
-	@Element(data = true)
-	private boolean deleted = false;
-
-	@Override
-	public Long getId() {
-		return id;
-	}
-
-	@Override
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String getAddress() {
-		return address;
-	}
-
-	public void setAddress(String address) {
-		this.address = address;
-	}
-
-	public boolean isDeleted() {
-		return deleted;
-	}
-
-	public void setDeleted(boolean deleted) {
-		this.deleted = deleted;
-	}
-
-	public Date getInserted() {
-		return inserted;
-	}
-
-	public void setInserted(Date inserted) {
-		this.inserted = inserted;
-	}
-
-	public Date getUpdated() {
-		return updated;
-	}
-
-	public void setUpdated(Date updated) {
-		this.updated = updated;
-	}
-
-	public User getInsertedby() {
-		return insertedby;
-	}
-
-	public void setInsertedby(User insertedby) {
-		this.insertedby = insertedby;
-	}
-
-	public User getUpdatedby() {
-		return updatedby;
-	}
-
-	public void setUpdatedby(User updatedby) {
-		this.updatedby = updatedby;
-	}
-
-	public String getComment() {
-		return comment;
-	}
-
-	public void setComment(String comment) {
-		this.comment = comment;
-	}
-	
-	public Calendar getLastPing() {
-		return lastPing;
-	}
-
-	public void setLastPing(Calendar lastPing) {
-		this.lastPing = lastPing;
-	}
-
-	public int getPort() {
-		return port;
-	}
-
-	public void setPort(int port) {
-		this.port = port;
-	}
-
-	public String getProtocol() {
-		return protocol;
-	}
-
-	public void setProtocol(String protocol) {
-		this.protocol = protocol;
-	}
-
-	public String getWebapp() {
-		return webapp;
-	}
-
-	public void setWebapp(String webapp) {
-		this.webapp = webapp;
-	}
-
-	public String getUser() {
-		return user;
-	}
-
-	public void setUser(String user) {
-		this.user = user;
-	}
-
-	public String getPass() {
-		return pass;
-	}
-
-	public void setPass(String pass) {
-		this.pass = pass;
-	}
-
-	public void setId(long id) {
-		this.id = id;
-	}
-
-	public boolean isActive() {
-		return active;
-	}
-
-	public void setActive(boolean active) {
-		this.active = active;
-	}
-
-	@Override
-	public String toString() {
-		return "Server [id=" + id + ", name=" + name + ", address=" + address
-				+ ", port=" + port + ", user=" + user + ", pass=" + pass
-				+ ", protocol=" + protocol 
-				+ ", active=" + active + ", webapp=" + webapp + ", deleted="
-				+ deleted + "]";
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((address == null) ? 0 : address.hashCode());
-		result = prime * result + ((id == null) ? 0 : id.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		Server other = (Server) obj;
-		if (address == null) {
-			if (other.address != null)
-				return false;
-		} else if (!address.equals(other.address))
-			return false;
-		if (id == null) {
-			if (other.id != null)
-				return false;
-		} else if (!id.equals(other.id))
-			return false;
-		return true;
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java
----------------------------------------------------------------------
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java
index 267d178..17bf2e7 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupExport.java
@@ -49,7 +49,6 @@ import org.apache.openmeetings.db.dao.room.RoomDao;
 import org.apache.openmeetings.db.dao.room.RoomGroupDao;
 import org.apache.openmeetings.db.dao.server.LdapConfigDao;
 import org.apache.openmeetings.db.dao.server.OAuth2Dao;
-import org.apache.openmeetings.db.dao.server.ServerDao;
 import org.apache.openmeetings.db.dao.user.GroupDao;
 import org.apache.openmeetings.db.dao.user.PrivateMessageDao;
 import org.apache.openmeetings.db.dao.user.PrivateMessageFolderDao;
@@ -124,8 +123,6 @@ public class BackupExport {
 	@Autowired
 	private OAuth2Dao auth2Dao;
 	@Autowired
-	private ServerDao serverDao;
-	@Autowired
 	private GroupDao groupDao;
 	@Autowired
 	private RoomDao roomDao;
@@ -249,12 +246,6 @@ public class BackupExport {
 			progressHolder.setProgress(35);
 
 			/*
-			 * ##################### Cluster servers
-			 */
-			writeList(ser, zos, "servers.xml", "servers", serverDao.get(0, Integer.MAX_VALUE));
-			progressHolder.setProgress(40);
-
-			/*
 			 * ##################### OAuth2 servers
 			 */
 			writeList(ser, zos, "oauth2servers.xml", "oauth2servers", auth2Dao.get(0, Integer.MAX_VALUE));

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
----------------------------------------------------------------------
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
index c4660c7..fad26ab 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java
@@ -81,7 +81,6 @@ import org.apache.openmeetings.db.dao.room.RoomDao;
 import org.apache.openmeetings.db.dao.room.RoomGroupDao;
 import org.apache.openmeetings.db.dao.server.LdapConfigDao;
 import org.apache.openmeetings.db.dao.server.OAuth2Dao;
-import org.apache.openmeetings.db.dao.server.ServerDao;
 import org.apache.openmeetings.db.dao.user.GroupDao;
 import org.apache.openmeetings.db.dao.user.PrivateMessageDao;
 import org.apache.openmeetings.db.dao.user.PrivateMessageFolderDao;
@@ -104,7 +103,6 @@ import org.apache.openmeetings.db.entity.room.RoomPoll;
 import org.apache.openmeetings.db.entity.room.RoomPollAnswer;
 import org.apache.openmeetings.db.entity.server.LdapConfig;
 import org.apache.openmeetings.db.entity.server.OAuthServer;
-import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.openmeetings.db.entity.user.Address;
 import org.apache.openmeetings.db.entity.user.Group;
 import org.apache.openmeetings.db.entity.user.GroupUser;
@@ -172,8 +170,6 @@ public class BackupImport {
 	@Autowired
 	private ChatDao chatDao;
 	@Autowired
-	private ServerDao serverDao;
-	@Autowired
 	private OAuth2Dao auth2Dao;
 	@Autowired
 	private GroupDao groupDao;
@@ -519,19 +515,7 @@ public class BackupImport {
 			}
 		}
 
-		log.info("Meeting members import complete, starting cluster server import");
-		/*
-		 * ##################### Cluster servers
-		 */
-		{
-			List<Server> list = readList(simpleSerializer, f, "servers.xml", "servers", Server.class, true);
-			for (Server s : list) {
-				s.setId(null);
-				serverDao.update(s, null);
-			}
-		}
-
-		log.info("Cluster servers import complete, starting recordings import");
+		log.info("Meeting members import complete, starting recordings server import");
 		/*
 		 * ##################### Import Recordings
 		 */

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
----------------------------------------------------------------------
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
index 2780549..ce08026 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
@@ -165,8 +165,7 @@ public class ImportInitvalues {
 		navimanagement.addMainStructure("adminModuleLDAP", null, 20, "1103", LEVEL_ADMIN, "Administration of LDAP Configs", admin.getId(), "1460");
 		navimanagement.addMainStructure("adminModuleOAuth", null, 21, "1571", LEVEL_ADMIN, "Administration of OAuth2 servers", admin.getId(), "1572");
 		navimanagement.addMainStructure("adminModuleBackup", null, 22, "367", LEVEL_ADMIN, "Administration of Backups", admin.getId(), "1461");
-		navimanagement.addMainStructure("adminModuleServers", null, 23, "1498", LEVEL_ADMIN, "Administration of Servers", admin.getId(), "1499");
-		navimanagement.addMainStructure("adminModuleEmail", null, 24, "main.menu.admin.email", LEVEL_ADMIN, "Administration of Emails", admin.getId(), "main.menu.admin.email.desc");
+		navimanagement.addMainStructure("adminModuleEmail", null, 23, "main.menu.admin.email", LEVEL_ADMIN, "Administration of Emails", admin.getId(), "main.menu.admin.email.desc");
 		log.debug("MainMenu ADDED");
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-server/src/site/xdoc/Clustering.xml
----------------------------------------------------------------------
diff --git a/openmeetings-server/src/site/xdoc/Clustering.xml b/openmeetings-server/src/site/xdoc/Clustering.xml
index e791f6e..a76ac5f 100644
--- a/openmeetings-server/src/site/xdoc/Clustering.xml
+++ b/openmeetings-server/src/site/xdoc/Clustering.xml
@@ -132,22 +132,12 @@
 						]]></source>
 					</li>
 					<li>
-						<p>In the file <tt>/opt/red5/webapps/openmeetings/WEB-INF/classes/applicationContext.xml</tt>:</p>
+						<p>In the file <tt>/opt/red5/webapps/openmeetings/WEB-INF/classes/hazelcast.xml</tt>:</p>
 						<ul>
+							<li>Set <tt>instance-name</tt> for each server to unique value</li>
 							<li>
-								For each node uncomment line:
-								<source>
-<![CDATA[
-<!-- Need to be uncommented and set to the real ID if in cluster mode-->
-<property name="serverId" value="1" />
-]]>
-								</source>
-								and input the unique value for each node.
-							</li>
-							<li>
-								Replace <tt>&lt;ref bean="openmeetings.HashMapStore" /&gt;  &lt;!-- Memory based session cache by default --&gt;</tt><br/>
-								with <tt>&lt;ref bean="openmeetings.DatabaseStore" /&gt;</tt>
-								(Currently commented out with following comment: <tt>"The following section should be used in clustering mode"</tt>)
+								In case there are more than one network interface with multicast support and/or additional hazelcast configuration is required
+								Based on the following documentation: <a href="http://docs.hazelcast.org/docs/3.8.3/manual/html-single/index.html">http://docs.hazelcast.org/docs/3.8.3/manual/html-single/index.html</a>
 							</li>
 						</ul>
 					</li>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
index bcef9cf..489751d 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
@@ -31,7 +31,7 @@ import java.util.Map;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.apache.openmeetings.core.data.whiteboard.WhiteboardCache;
-import org.apache.openmeetings.core.session.SessionManager;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.server.SessiondataDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.dto.room.Whiteboard;
@@ -52,7 +52,7 @@ public class CleanupJob extends AbstractJob {
 	@Autowired
 	private SessiondataDao sessionDao;
 	@Autowired
-	private SessionManager sessionManager;
+	private ISessionManager sessionManager;
 	@Autowired
 	private WhiteboardCache wbManager;
 	@Autowired
@@ -128,7 +128,7 @@ public class CleanupJob extends AbstractJob {
 							}
 						}
 					}
-					if (folder.isDirectory() && roomId != null && sessionManager.getClientListByRoom(roomId).isEmpty()) {
+					if (folder.isDirectory() && roomId != null && sessionManager.listByRoom(roomId).isEmpty()) {
 						File[] files = folder.listFiles();
 						//TODO need to rework this and remove hardcodings
 						if (files != null) {

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
----------------------------------------------------------------------
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
index 8d2a829..a42cbcc 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/user/UserManager.java
@@ -413,7 +413,7 @@ public class UserManager implements IUserManager {
 		try {
 			sessionDao.clearSessionByRoomId(roomId);
 
-			for (StreamClient rcl : sessionManager.getClientListByRoom(roomId)) {
+			for (StreamClient rcl : sessionManager.listByRoom(roomId)) {
 				if (rcl == null) {
 					return true;
 				}
@@ -436,9 +436,9 @@ public class UserManager implements IUserManager {
 	}
 
 	@Override
-	public boolean kickById(Long id) {
+	public boolean kickById(String uid) {
 		try {
-			StreamClient rcl = sessionManager.get(id);
+			StreamClient rcl = sessionManager.get(uid);
 
 			if (rcl == null) {
 				return true;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-web/pom.xml
----------------------------------------------------------------------
diff --git a/openmeetings-web/pom.xml b/openmeetings-web/pom.xml
index 7e4a52c..7b41678 100644
--- a/openmeetings-web/pom.xml
+++ b/openmeetings-web/pom.xml
@@ -407,6 +407,11 @@
 			<version>${wickets.version}</version>
 		</dependency>
 		<dependency>
+			<groupId>org.wicketstuff</groupId>
+			<artifactId>wicketstuff-datastore-hazelcast</artifactId>
+			<version>${wickets.version}</version>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.wicket</groupId>
 			<artifactId>wicket-auth-roles</artifactId>
 			<version>${wicket.version}</version>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
index c7426af..37e315d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
@@ -27,10 +27,10 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.apache.openmeetings.db.dao.server.ISessionManager;
+import org.apache.openmeetings.db.dao.user.IUserManager;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.IClient;
 import org.apache.openmeetings.db.entity.room.StreamClient;
-import org.apache.openmeetings.service.user.UserManager;
 import org.apache.openmeetings.web.admin.AdminPanel;
 import org.apache.openmeetings.web.admin.SearchableDataView;
 import org.apache.openmeetings.web.app.Application;
@@ -58,7 +58,7 @@ public class ConnectionsPanel extends AdminPanel {
 
 			private List<IClient> list() {
 				List<IClient> l = new ArrayList<>();
-				l.addAll(getBean(ISessionManager.class).getClientsWithServer());
+				l.addAll(getBean(ISessionManager.class).list());
 				l.addAll(Application.getClients());
 				return l;
 			}
@@ -90,8 +90,7 @@ public class ConnectionsPanel extends AdminPanel {
 					protected void onSubmit(AjaxRequestTarget target) {
 						IClient _c = item.getModelObject();
 						if (_c instanceof StreamClient) {
-							StreamClient c = (StreamClient)_c;
-							getBean(UserManager.class).kickById(c.getId());
+							getBean(IUserManager.class).kickById(_c.getUid());
 						} else {
 							Client c = (Client)_c;
 							Application.get().invalidateClient(c.getUserId(), c.getSessionId());
@@ -105,7 +104,6 @@ public class ConnectionsPanel extends AdminPanel {
 					item.add(new Label("login", c.getUsername()));
 					item.add(new Label("since", c.getConnectedSince()));
 					item.add(new Label("scope"));
-					item.add(new Label("server", c.getServer() == null ? "no cluster" : c.getServer().getAddress())); //FIXME localization
 					confirm.setEnabled(!c.isSharing());
 				} else {
 					Client c = (Client)_c;
@@ -113,8 +111,8 @@ public class ConnectionsPanel extends AdminPanel {
 					item.add(new Label("login", c.getUser().getLogin()));
 					item.add(new Label("since", c.getConnectedSince()));
 					item.add(new Label("scope", c.getRoomId() == null ? "html5" : "" + c.getRoomId()));
-					item.add(new Label("server", ""));
 				}
+				item.add(new Label("server", _c.getServerId()));
 				item.add(confirm);
 				item.add(new AjaxEventBehavior("click") {
 					private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
index 869b36d..1afba1d 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
@@ -96,7 +96,7 @@ public class RoomForm extends AdminBaseForm<Room> {
 					@Override
 					protected void onSubmit(AjaxRequestTarget target) {
 						StreamClient c = item.getModelObject();
-						getBean(UserManager.class).kickById(c.getId());
+						getBean(UserManager.class).kickById(c.getUid());
 						updateClients(target);
 					}
 				});
@@ -321,7 +321,7 @@ public class RoomForm extends AdminBaseForm<Room> {
 
 	void updateClients(AjaxRequestTarget target) {
 		long roomId = (getModelObject().getId() != null ? getModelObject().getId() : 0);
-		final List<StreamClient> clientsInRoom = getBean(ISessionManager.class).getClientListByRoom(roomId);
+		final List<StreamClient> clientsInRoom = getBean(ISessionManager.class).listByRoom(roomId);
 		clients.setDefaultModelObject(clientsInRoom);
 		target.add(clientsContainer);
 	}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServerForm.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServerForm.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServerForm.java
deleted file mode 100644
index c40315e..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServerForm.java
+++ /dev/null
@@ -1,140 +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.web.admin.servers;
-
-import static org.apache.openmeetings.util.OpenmeetingsVariables.WEB_DATE_PATTERN;
-import static org.apache.wicket.datetime.markup.html.basic.DateLabel.forDatePattern;
-
-import org.apache.openmeetings.db.dao.server.ServerDao;
-import org.apache.openmeetings.db.entity.server.Server;
-import org.apache.openmeetings.web.admin.AdminBaseForm;
-import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.app.WebSession;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.form.AjaxFormValidatingBehavior;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.form.CheckBox;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.form.RequiredTextField;
-import org.apache.wicket.markup.html.form.TextArea;
-import org.apache.wicket.markup.html.form.TextField;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.util.time.Duration;
-
-/**
- * Form component to insert/update/delete {@link Server}
- *
- * @author swagner
- *
- */
-public class ServerForm extends AdminBaseForm<Server> {
-	private final WebMarkupContainer listContainer;
-	private static final long serialVersionUID = 1L;
-
-	public ServerForm(String id, WebMarkupContainer listContainer, final Server server) {
-		super(id, new CompoundPropertyModel<>(server));
-		setOutputMarkupId(true);
-		this.listContainer = listContainer;
-
-		add(new RequiredTextField<String>("name").setLabel(Model.of(Application.getString(1500))));
-		add(new CheckBox("active"));
-		add(new RequiredTextField<String>("address").setLabel(Model.of(Application.getString(1501))));
-		add(new TextField<Integer>("port"));
-		add(new TextField<String>("user"));
-		add(new TextField<String>("pass"));
-		add(new TextField<String>("webapp"));
-		add(new TextField<String>("protocol"));
-		add(forDatePattern("lastPing", WEB_DATE_PATTERN));
-		//add(new Label("pingRunning"));
-		add(forDatePattern("inserted", WEB_DATE_PATTERN));
-		add(new Label("insertedby.login"));
-		add(forDatePattern("updated", WEB_DATE_PATTERN));
-		add(new Label("updatedby.login"));
-		add(new TextArea<String>("comment"));
-
-		// attach an ajax validation behavior to all form component's keydown
-		// event and throttle it down to once per second
-		add(new AjaxFormValidatingBehavior("keydown", Duration.ONE_SECOND));
-	}
-
-	@Override
-	protected void onSaveSubmit(AjaxRequestTarget target, Form<?> form) {
-		Application.getBean(ServerDao.class).update(getModelObject(), WebSession.getUserId());
-		Server server = Application.getBean(ServerDao.class).get(getModelObject().getId());
-		setModelObject(server);
-		hideNewRecord();
-		target.add(this);
-		target.add(listContainer);
-		target.appendJavaScript("adminPanelInit();");
-	}
-
-	@Override
-	protected void onNewSubmit(AjaxRequestTarget target, Form<?> form) {
-		Server s = new Server();
-		s.setWebapp("openmeetings");
-		s.setProtocol("http");
-		setModelObject(s);
-		target.add(this);
-		target.appendJavaScript("adminPanelInit();");
-	}
-
-	@Override
-	protected void onRefreshSubmit(AjaxRequestTarget target, Form<?> form) {
-		Server server = getModelObject();
-		if (server.getId() != null) {
-			server = Application.getBean(ServerDao.class).get(server.getId());
-		} else {
-			server = new Server();
-		}
-		setModelObject(server);
-		target.add(this);
-		target.appendJavaScript("adminPanelInit();");
-	}
-
-	@Override
-	protected void onDeleteSubmit(AjaxRequestTarget target, Form<?> form) {
-		Application.getBean(ServerDao.class).delete(getModelObject(), WebSession.getUserId());
-		this.setModelObject(new Server());
-		target.add(listContainer);
-		target.add(this);
-		target.appendJavaScript("adminPanelInit();");
-	}
-
-	@Override
-	protected void onSaveError(AjaxRequestTarget target, Form<?> form) {
-		// TODO Auto-generated method stub
-	}
-
-	@Override
-	protected void onNewError(AjaxRequestTarget target, Form<?> form) {
-		// TODO Auto-generated method stub
-	}
-
-	@Override
-	protected void onRefreshError(AjaxRequestTarget target, Form<?> form) {
-		// TODO Auto-generated method stub
-	}
-
-	@Override
-	protected void onDeleteError(AjaxRequestTarget target, Form<?> form) {
-		// TODO Auto-generated method stub
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServersPanel.html
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServersPanel.html b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServersPanel.html
deleted file mode 100644
index 187b748..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServersPanel.html
+++ /dev/null
@@ -1,103 +0,0 @@
-<?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.
-
--->
-<html xmlns:wicket="http://wicket.apache.org">
-<wicket:extend>
-	<div class="adminPanelColumnTable">
-		<span wicket:id="navigator">[dataview navigator]</span>
-		<table class="adminListTable">
-			<thead>
-				<tr>
-					<th class="three_column_layout_column1 ui-widget-header"><span wicket:id="orderById"></span><wicket:message key="188" /></th>
-					<th class="three_column_layout_column2 ui-widget-header"><span wicket:id="orderByName"></span><wicket:message key="1500" /></th>
-					<th class="three_column_layout_column3 ui-widget-header"><span wicket:id="orderByAddress"></span><wicket:message key="1501" /></th>
-				</tr>
-			</thead>
-		</table>
-		<div class="tableWrapper" id="adminTable">
-			<table class="adminListTable">
-				<tbody wicket:id="listContainer">
-					<tr wicket:id="serverList">
-						<td class="three_column_layout_column1"><div class="three_column_layout_divcolumn1"><span wicket:id="id"></span></div></td>
-						<td class="three_column_layout_column2"><div class="three_column_layout_divcolumn2"><span wicket:id="name"></span></div></td>
-						<td class="three_column_layout_column3"><div class="three_column_layout_divcolumn3"><span wicket:id="address"></span></div></td>
-					</tr>
-				</tbody>
-			</table>
-		</div>
-	</div>
-	<div class="adminPanelColumnForm">
-		<form wicket:id="form" class="adminForm">
-			<div wicket:id="buttons"></div>
-			<div class="scrollcontent" id="adminForm">
-				<fieldset class="ui-widget-content">
-					<legend class="ui-widget-header"><wicket:message key="1502" /></legend>
-					<div class="formelement">
-						<label wicket:for="name"><wicket:message key="1500" /></label><input type="text" wicket:id="name"/>
-					</div>
-					<div class="formelement">
-						<label wicket:for="active"><wicket:message key="1525" /></label><input type="checkbox" class="formcheckbox" wicket:id="active" />
-					</div>
-					<div class="formelement">
-						<label wicket:for="address"><wicket:message key="1501" /></label><input type="text" wicket:id="address"/>
-					</div>
-					<div class="formelement">
-						<label wicket:for="port"><wicket:message key="1519" /></label><input type="text" wicket:id="port"/>
-					</div>
-					<div class="formelement">
-						<label wicket:for="user"><wicket:message key="1520" /></label><input type="text" wicket:id="user"/>
-					</div>
-					<div class="formelement">
-						<label wicket:for="pass"><wicket:message key="1521" /></label><input type="text" wicket:id="pass"/>
-					</div>
-					<div class="formelement">
-						<label wicket:for="webapp"><wicket:message key="1522" /></label><input type="text" wicket:id="webapp"/>
-					</div>
-					<div class="formelement">
-						<label wicket:for="protocol"><wicket:message key="1523" /></label><input type="text" wicket:id="protocol"/>
-					</div>
-					<div class="formelement">
-						<div class="info-text"><wicket:message key="1518" /></div>
-							<br/>
-						<label><wicket:message key="1517" /></label><span wicket:id="lastPing"/>
-						<!-- br/>
-						<label wicket:for="pingRunning"><wicket:message key="1524" /></label><span wicket:id="pingRunning"/-->
-					</div>
-					<div class="formelement">
-						<label><wicket:message key="1110" /></label><span wicket:id="inserted"/>
-					</div>
-					<div class="formelement">
-						<label><wicket:message key="1111" /></label><span wicket:id="insertedby.login"/>
-					</div>
-					<div class="formelement">
-						<label><wicket:message key="1112" /></label><span wicket:id="updated"/>
-					</div>
-					<div class="formelement">
-						<label><wicket:message key="1113" /></label><span wicket:id="updatedby.login"/>
-					</div>
-					<div class="formelement">
-						<label wicket:for="comment"><wicket:message key="270" /></label><textarea wicket:id="comment"/>
-					</div>
-				</fieldset>
-			</div>
-		</form>
-	</div>
-</wicket:extend>
-</html>

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServersPanel.java
----------------------------------------------------------------------
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServersPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServersPanel.java
deleted file mode 100644
index 1a60552..0000000
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/servers/ServersPanel.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.web.admin.servers;
-
-import org.apache.openmeetings.db.dao.server.ServerDao;
-import org.apache.openmeetings.db.entity.server.Server;
-import org.apache.openmeetings.web.admin.AdminPanel;
-import org.apache.openmeetings.web.admin.SearchableDataView;
-import org.apache.openmeetings.web.common.PagedEntityListPanel;
-import org.apache.openmeetings.web.data.DataViewContainer;
-import org.apache.openmeetings.web.data.OmOrderByBorder;
-import org.apache.openmeetings.web.data.SearchableDataProvider;
-import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.ajax.AjaxEventBehavior;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.repeater.Item;
-
-/**
- * Form component with list and form to manipulate {@link Server}
- *
- * @author swagner
- *
- */
-public class ServersPanel extends AdminPanel {
-	private static final long serialVersionUID = 1L;
-	final WebMarkupContainer listContainer = new WebMarkupContainer("listContainer");
-	private ServerForm form;
-
-	public ServersPanel(String id) {
-		super(id);
-		SearchableDataView<Server> dataView = new SearchableDataView<Server>("serverList",
-				new SearchableDataProvider<>(ServerDao.class)) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			protected void populateItem(final Item<Server> item) {
-				final Server server = item.getModelObject();
-				item.add(new Label("id"));
-				item.add(new Label("name"));
-				item.add(new Label("address"));
-				item.add(new AjaxEventBehavior("click") {
-					private static final long serialVersionUID = 1L;
-
-					@Override
-					protected void onEvent(AjaxRequestTarget target) {
-						form.setModelObject(server);
-						form.hideNewRecord();
-						target.add(form, listContainer);
-						target.appendJavaScript("adminPanelInit();");
-					}
-				});
-				item.add(AttributeModifier.replace("class", getRowClass(server.getId(), form.getModelObject().getId())));
-			}
-		};
-
-		add(listContainer.add(dataView).setOutputMarkupId(true));
-		PagedEntityListPanel navigator = new PagedEntityListPanel("navigator", dataView) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			protected void onEvent(AjaxRequestTarget target) {
-				target.add(listContainer);
-			}
-		};
-		DataViewContainer<Server> container = new DataViewContainer<>(listContainer, dataView, navigator);
-		container.addLink(new OmOrderByBorder<>("orderById", "id", container))
-			.addLink(new OmOrderByBorder<>("orderByName", "name", container))
-			.addLink(new OmOrderByBorder<>("orderByAddress", "address", container));
-		add(container.getLinks());
-		add(navigator);
-
-		form = new ServerForm("form", listContainer, new Server());
-		form.showNewRecord();
-		add(form);
-
-	}
-}

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/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 aba8c43..03ca5cd 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;
@@ -90,6 +89,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;
@@ -102,6 +102,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.ws.WebSocketAwareCsrfPreventionRequestCycleListener;
 import org.apache.wicket.protocol.ws.api.WebSocketResponse;
 import org.apache.wicket.request.IRequestHandler;
@@ -121,14 +122,23 @@ 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.MemberAttributeEvent;
+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, String> UID_BY_SID = 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 UID_BY_SID_KEY = "UID_BY_SID_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
@@ -142,6 +152,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() {
@@ -149,6 +160,26 @@ 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 memberAttributeChanged(MemberAttributeEvent memberAttributeEvent) {
+			}
+
+			@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
@@ -251,10 +282,43 @@ 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);
+	}
+
+	private Map<String, String> getUidBySid() {
+		return hazelcast.getMap(UID_BY_SID_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);
-		UID_BY_SID.put(c.getSid(), c.getUid());
+		c.setServerId(get().getServerId());
+		get().getOnlineUsers().put(c.getUid(), c);
+		get().getUidBySid().put(c.getSid(), c.getUid());
 	}
 
 	public static void exitRoom(Client c) {
@@ -273,7 +337,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));
 		}
 	}
 
@@ -283,8 +347,8 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 				exitRoom(c);
 			}
 			log.debug("Removing online client: {}, room: {}", c.getUid(), c.getRoomId());
-			ONLINE_USERS.remove(c.getUid());
-			UID_BY_SID.remove(c.getSid());
+			get().getOnlineUsers().remove(c.getUid());
+			get().getUidBySid().remove(c.getSid());
 		}
 	}
 
@@ -386,7 +450,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
@@ -395,17 +459,6 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	}
 
 	@Override
-	public List<Long> getActiveRooms() {
-		Set<Long> ids = new HashSet<>();
-		for (Map.Entry<String, Client> e : ONLINE_USERS.entrySet()) {
-			if (e.getValue().getRoomId() != null) {
-				ids.add(e.getValue().getRoomId());
-			}
-		}
-		return new ArrayList<>(ids);
-	}
-
-	@Override
 	public Client getOmClientBySid(String sid) {
 		return getClientBySid(sid);
 	}
@@ -414,13 +467,13 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 		if (sid == null) {
 			return null;
 		}
-		String uid = UID_BY_SID.get(sid);
-		return uid == null ? null : ONLINE_USERS.get(uid);
+		String uid = get().getUidBySid().get(sid);
+		return uid == null ? null : get().getOnlineUsers().get(uid);
 	}
 
 	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;
@@ -430,12 +483,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;
@@ -446,7 +499,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;
@@ -460,27 +513,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;
 	}
 
@@ -488,13 +551,13 @@ 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.clear();
+			update(c);
 		}
 		return c;
 	}
@@ -515,7 +578,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);
@@ -530,7 +593,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)) {
@@ -542,7 +605,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)) {
@@ -731,4 +794,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/bbcdbf7e/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 c0af7b7..688a57d 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,10 +20,10 @@ 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.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;
@@ -34,8 +34,7 @@ public class RoomBroadcaster {
 	private static final Logger log = Red5LoggerFactory.getLogger(RoomBroadcaster.class, webAppRootKey);
 
 	public static StreamClient getClient(String publicSid) {
-		ClientSessionInfo csi = getBean(SessionManager.class).getClientByUidAnyServer(publicSid);
-		return csi == null ? null : csi.getRcl();
+		return getBean(ISessionManager.class).get(publicSid);
 	}
 
 	public static void broadcast(String publicSid, String method, Object obj) {
@@ -61,8 +60,9 @@ public class RoomBroadcaster {
 		}
 
 		// Put the mod-flag to true for this client
-		getBean(SessionManager.class).update(rcl);
+		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/bbcdbf7e/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 ee6c671..cac817e 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
@@ -25,6 +25,7 @@ import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getClientBySid;
 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.room.wb.WbPanel.WB_JS_REFERENCE;
@@ -160,7 +161,7 @@ public class RoomPanel extends BasePanel {
 		for (Client c: getRoomClients(getRoom().getId()) ) {
 			boolean self = getClient().getUid().equals(c.getUid());
 			for (Client.Stream s : c.getStreams()) {
-				JSONObject jo = RoomHelper.videoJson(c, self, c.getSid(), getBean(ISessionManager.class), s.getStreamClientId());
+				JSONObject jo = RoomHelper.videoJson(c, self, c.getSid(), getBean(ISessionManager.class), s.getUid());
 				sb.append(String.format("VideoManager.play(%s);", jo));
 			}
 		}
@@ -173,7 +174,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);
 
@@ -341,7 +342,7 @@ public class RoomPanel extends BasePanel {
 								return;
 							}
 							recordingUser = null;
-							c.remove(Client.Activity.record);
+							update(c.remove(Client.Activity.record));
 							menu.update(handler);
 						}
 						break;
@@ -354,7 +355,7 @@ public class RoomPanel extends BasePanel {
 								return;
 							}
 							recordingUser = uid;
-							c.set(Client.Activity.record);
+							update(c.set(Client.Activity.record));
 							menu.update(handler);
 						}
 						break;
@@ -415,14 +416,14 @@ public class RoomPanel extends BasePanel {
 							return;
 						}
 						boolean self = getClient().getUid().equals(uid);
-						String broadcastId = obj.getString("stream");
-						Long streamClientId = obj.getLong("streamClientId");
+						String broadcastId = obj.getString("streamName");
+						Long streamId = obj.getLong("streamId");
 						if (!self) {
-							JSONObject jo = RoomHelper.videoJson(c, self, getClient().getSid(), getBean(ISessionManager.class), streamClientId);
+							JSONObject jo = RoomHelper.videoJson(c, self, getClient().getSid(), getBean(ISessionManager.class), uid);
 							handler.appendJavaScript(String.format("VideoManager.play(%s);", jo));
 						}
 						if (getClient().getSid().equals(c.getSid())) {
-							c.addStream(streamClientId, broadcastId, share);
+							c.addStream(uid, streamId, broadcastId, share);
 						}
 					}
 						break;
@@ -519,11 +520,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);
 				}
 			}
 		}
@@ -604,7 +607,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
@@ -646,6 +649,7 @@ public class RoomPanel extends BasePanel {
 
 	public void allowRight(Client client, Right... rights) {
 		client.allow(rights);
+		update(client);
 		broadcast(client);
 	}
 
@@ -659,6 +663,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);
 	}
 

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/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 23c03b0..6e82ac3 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
@@ -27,8 +27,13 @@ import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.wicket.RuntimeConfigurationType.DEVELOPMENT;
 
 import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.openmeetings.core.remote.ScopeApplicationAdapter;
+import org.apache.openmeetings.db.dao.room.RoomDao;
+import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.common.BasePanel;
 import org.apache.openmeetings.web.common.OmAjaxClientInfoBehavior;
@@ -49,6 +54,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;
@@ -163,4 +171,47 @@ public class SwfPanel extends BasePanel {
 		}
 		return arr.toString();
 	}
+
+	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;
+	}
+
+	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());
+		}
+
+		long minimum = -1;
+		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 {}", m.getAddress());
+				return addServer(pp, m);
+			}
+			activeRoomsMap.put(m, roomIds);
+		}
+		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: {} 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/bbcdbf7e/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 73ff489..d003fff 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
@@ -317,13 +317,13 @@ public class RoomMenuPanel extends Panel {
 		StringBuilder roomTitle = new StringBuilder();
 		if (room.getRecordingUser() != null) {
 			ISessionManager sessMngr = getBean(ISessionManager.class);
-			StreamClient recUser = sessMngr.getClientByUid(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");
 			}
-			StreamClient pubUser = sessMngr.getClientByUid(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/bbcdbf7e/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 3f935a6..0f05691 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
@@ -32,10 +32,10 @@ import static org.apache.wicket.util.time.Duration.NONE;
 import java.io.InputStream;
 
 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.dao.server.ISessionManager;
 import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.web.app.Application;
@@ -96,7 +96,7 @@ public class StartSharingButton extends OmButton {
 			String _url = s.getString(VideoSettings.URL);
 			long roomId = c.getRoomId();
 			Room room = getBean(RoomDao.class).get(roomId);
-			SessionManager sessionManager = getBean(SessionManager.class);
+			ISessionManager sessionManager = getBean(ISessionManager.class);
 			app = app.replace("$native", "" + s.getBoolean(FLASH_NATIVE_SSL))
 					.replace("$codebase", WebSession.get().getExtendedProperties().getCodebase())
 					.replace("$applicationName", cfgDao.getAppName())

http://git-wip-us.apache.org/repos/asf/openmeetings/blob/bbcdbf7e/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 3897ca9..8233ac9 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;
 
@@ -38,7 +39,6 @@ import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder;
 import org.apache.openmeetings.web.common.ConfirmableAjaxBorder.ConfirmableBorderDialog;
 import org.apache.openmeetings.web.common.NameDialog;
-import org.apache.openmeetings.web.room.RoomBroadcaster;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 import org.apache.openmeetings.web.room.VideoSettings;
@@ -141,6 +141,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 != null && 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/bbcdbf7e/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/bbcdbf7e/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 1355008..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.StreamClient</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/bbcdbf7e/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 3be6772..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.StreamClient</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/bbcdbf7e/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 1cac922..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.StreamClient</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/bbcdbf7e/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 c7000f2..ee81c1c 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.StreamClient</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/bbcdbf7e/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 f8dd5dd..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.StreamClient</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/bbcdbf7e/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 95f7d00..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.StreamClient</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/bbcdbf7e/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 5990b80..53db861 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
@@ -40,35 +40,12 @@
 	<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" />
 
-	<!-- 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="openmeetings.FileProcessor" class="org.apache.openmeetings.core.data.file.FileProcessor" />
@@ -79,7 +56,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
@@ -197,9 +173,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/bbcdbf7e/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/bbcdbf7e/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>