Author: sebawagner
Date: Wed Dec 12 22:18:03 2012
New Revision: 1421019

URL: http://svn.apache.org/viewvc?rev=1421019&view=rev
Log:
OPENMEETINGS-460 Cluster login working. Clients are redirected to slave for 
RTMP traffic, HTTP traffic still goes through master. Logout from room and 
return to master working too. There are a few drawbacks that needs to be fixed 
now and the rew txt documentation needs to be transformed into the website.
Also some WebService methods have been protected, if invoked before server has 
done startup, the request of a Bean via the WebApplicationContextUtils can 
cause the server to hang in the startup process.

Added:
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/ServerDTO.java
    incubator/openmeetings/trunk/singlewebapp/test/ClusterRoomLoginProcess.txt
Modified:
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/CalendarWebServiceFacade.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/FileWebServiceFacade.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/JabberWebServiceFacade.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebServiceFacade.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/ServerWebServiceFacade.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/UserWebServiceFacade.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/ConferenceService.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStore.java

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/CalendarWebServiceFacade.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/CalendarWebServiceFacade.java?rev=1421019&r1=1421018&r2=1421019&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/CalendarWebServiceFacade.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/CalendarWebServiceFacade.java
 Wed Dec 12 22:18:03 2012
@@ -32,6 +32,7 @@ import org.apache.openmeetings.data.cale
 import org.apache.openmeetings.persistence.beans.calendar.Appointment;
 import org.apache.openmeetings.persistence.beans.calendar.AppointmentCategory;
 import 
org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
+import org.apache.openmeetings.remote.red5.ScopeApplicationAdapter;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.context.ApplicationContext;
@@ -50,6 +51,9 @@ public class CalendarWebServiceFacade {
 
        private CalendarWebService getCalendarServiceProxy() {
                try {
+                       if (!ScopeApplicationAdapter.initComplete) {
+                               throw new Exception("Server not yet 
initialized, retry in couple of seconds");
+                       }
                        ApplicationContext context = WebApplicationContextUtils
                                        
.getWebApplicationContext(getServletContext());
                        return (CalendarWebService) 
context.getBean("calendarWebService");

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/FileWebServiceFacade.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/FileWebServiceFacade.java?rev=1421019&r1=1421018&r2=1421019&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/FileWebServiceFacade.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/FileWebServiceFacade.java
 Wed Dec 12 22:18:03 2012
@@ -27,6 +27,7 @@ import org.apache.openmeetings.Openmeeti
 import org.apache.openmeetings.data.file.dto.FileExplorerObject;
 import org.apache.openmeetings.data.file.dto.LibraryPresentation;
 import org.apache.openmeetings.persistence.beans.files.FileExplorerItem;
+import org.apache.openmeetings.remote.red5.ScopeApplicationAdapter;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.context.ApplicationContext;
@@ -45,6 +46,9 @@ public class FileWebServiceFacade {
 
        private FileWebService geFileServiceProxy() {
                try {
+                       if (!ScopeApplicationAdapter.initComplete) {
+                               throw new Exception("Server not yet 
initialized, retry in couple of seconds");
+                       }
                        ApplicationContext context = WebApplicationContextUtils
                                        
.getWebApplicationContext(getServletContext());
                        return (FileWebService) 
context.getBean("fileWebService");

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/JabberWebServiceFacade.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/JabberWebServiceFacade.java?rev=1421019&r1=1421018&r2=1421019&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/JabberWebServiceFacade.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/JabberWebServiceFacade.java
 Wed Dec 12 22:18:03 2012
@@ -24,6 +24,7 @@ import org.apache.axis2.context.MessageC
 import org.apache.axis2.transport.http.HTTPConstants;
 import org.apache.openmeetings.OpenmeetingsVariables;
 import org.apache.openmeetings.persistence.beans.rooms.Rooms;
+import org.apache.openmeetings.remote.red5.ScopeApplicationAdapter;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.context.ApplicationContext;
@@ -48,6 +49,9 @@ public class JabberWebServiceFacade {
 
        private JabberWebService getJabberServiceProxy() {
                try {
+                       if (!ScopeApplicationAdapter.initComplete) {
+                               throw new Exception("Server not yet 
initialized, retry in couple of seconds");
+                       }
                        ApplicationContext context = WebApplicationContextUtils
                                        
.getWebApplicationContext(getServletContext());
 

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebServiceFacade.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebServiceFacade.java?rev=1421019&r1=1421018&r2=1421019&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebServiceFacade.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebServiceFacade.java
 Wed Dec 12 22:18:03 2012
@@ -31,6 +31,7 @@ import org.apache.openmeetings.data.bean
 import org.apache.openmeetings.persistence.beans.flvrecord.FlvRecording;
 import org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
 import org.apache.openmeetings.persistence.beans.rooms.Rooms;
+import org.apache.openmeetings.remote.red5.ScopeApplicationAdapter;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.context.ApplicationContext;
@@ -49,6 +50,9 @@ public class RoomWebServiceFacade {
 
        private RoomWebService getRoomServiceProxy() {
                try {
+                       if (!ScopeApplicationAdapter.initComplete) {
+                               throw new Exception("Server not yet 
initialized, retry in couple of seconds");
+                       }
                        ApplicationContext context = WebApplicationContextUtils
                                        
.getWebApplicationContext(getServletContext());
                        return context.getBean("roomWebService", 
RoomWebService.class);

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/ServerWebServiceFacade.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/ServerWebServiceFacade.java?rev=1421019&r1=1421018&r2=1421019&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/ServerWebServiceFacade.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/ServerWebServiceFacade.java
 Wed Dec 12 22:18:03 2012
@@ -28,6 +28,7 @@ import org.apache.axis2.transport.http.H
 import org.apache.openmeetings.OpenmeetingsVariables;
 import org.apache.openmeetings.conference.room.SlaveClientDto;
 import org.apache.openmeetings.persistence.beans.basic.Server;
+import org.apache.openmeetings.remote.red5.ScopeApplicationAdapter;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.context.ApplicationContext;
@@ -46,6 +47,9 @@ public class ServerWebServiceFacade {
 
        private ServerWebService getServerServiceProxy() {
                try {
+                       if (!ScopeApplicationAdapter.initComplete) {
+                               throw new Exception("Server not yet 
initialized, retry in couple of seconds");
+                       }
                        ApplicationContext context = WebApplicationContextUtils
                                        
.getWebApplicationContext(getServletContext());
                        return context.getBean("serverWebService", 
ServerWebService.class);

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/UserWebServiceFacade.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/UserWebServiceFacade.java?rev=1421019&r1=1421018&r2=1421019&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/UserWebServiceFacade.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/UserWebServiceFacade.java
 Wed Dec 12 22:18:03 2012
@@ -28,6 +28,7 @@ import org.apache.openmeetings.data.bean
 import org.apache.openmeetings.data.beans.basic.SearchResult;
 import org.apache.openmeetings.persistence.beans.basic.Sessiondata;
 import org.apache.openmeetings.persistence.beans.user.Users;
+import org.apache.openmeetings.remote.red5.ScopeApplicationAdapter;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.context.ApplicationContext;
@@ -46,6 +47,9 @@ public class UserWebServiceFacade {
 
        private UserWebService getUserServiceProxy() {
                try {
+                       if (!ScopeApplicationAdapter.initComplete) {
+                               throw new Exception("Server not yet 
initialized, retry in couple of seconds");
+                       }
                        ApplicationContext context = WebApplicationContextUtils
                                        
.getWebApplicationContext(getServletContext());
                        return (UserWebService) 
context.getBean("userWebService");

Added: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/ServerDTO.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/ServerDTO.java?rev=1421019&view=auto
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/ServerDTO.java
 (added)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/ServerDTO.java
 Wed Dec 12 22:18:03 2012
@@ -0,0 +1,82 @@
+/*
+ * 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.cluster.beans;
+
+import org.apache.openmeetings.persistence.beans.basic.Server;
+
+public class ServerDTO {
+
+       private Long id;
+       private String address;
+       private int port;
+       private String protocol;
+       private String webapp;
+
+       public ServerDTO(Server server) {
+               if (server == null) {
+                       return;
+               }
+               id = server.getId();
+               address = server.getAddress();
+               port = server.getPort();
+               protocol = server.getProtocol();
+               webapp = server.getWebapp();
+       }
+
+       public Long getId() {
+               return id;
+       }
+
+       public void setId(Long id) {
+               this.id = id;
+       }
+
+       public String getAddress() {
+               return address;
+       }
+
+       public void setAddress(String address) {
+               this.address = address;
+       }
+
+       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;
+       }
+
+}

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/ConferenceService.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/ConferenceService.java?rev=1421019&r1=1421018&r2=1421019&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/ConferenceService.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/ConferenceService.java
 Wed Dec 12 22:18:03 2012
@@ -32,6 +32,7 @@ import java.util.Map.Entry;
 import java.util.TimeZone;
 
 import org.apache.openmeetings.OpenmeetingsVariables;
+import org.apache.openmeetings.cluster.beans.ServerDTO;
 import org.apache.openmeetings.conference.room.ClientSession;
 import org.apache.openmeetings.conference.room.IClientList;
 import org.apache.openmeetings.conference.room.RoomClient;
@@ -775,7 +776,7 @@ public class ConferenceService {
         * @return null means the user should stay on the master, otherwise a
         *         {@link Server} entity is returned
         */
-       public Server getServerForSession(String SID, long roomId) {
+       public ServerDTO getServerForSession(String SID, long roomId) {
                Long users_id = sessionManagement.checkSession(SID);
                Long user_level = userManagement.getUserLevelByID(users_id);
                if (authLevelManagement.checkUserLevel(user_level)) {
@@ -796,7 +797,7 @@ public class ConferenceService {
                        for (Server server : serverList) {
                                for (Long activeRoomId : 
clientListManager.getActiveRoomIdsByServer(server)) {
                                        if (activeRoomId.equals(roomId)) {
-                                               return server;
+                                               return new ServerDTO(server);
                                        }
                                }
                        }
@@ -831,11 +832,15 @@ public class ConferenceService {
                        Collections.sort(list, new Comparator<Server>() {
                          public int compare(Server s1, Server s2) {
                                  int maxUsersInRoomS1 = 0;
+                                 log.debug("serverRoomMap.get(s1) SIZE 
"+serverRoomMap.get(s1).size());
                                  for (Rooms room : serverRoomMap.get(s1)) {
+                                         log.debug("s1 room: "+room);
                                          maxUsersInRoomS1 += 
room.getNumberOfPartizipants();
                                  }
                                  int maxUsersInRoomS2 = 0;
+                                 log.debug("serverRoomMap.get(s2) SIZE 
"+serverRoomMap.get(s2).size());
                                  for (Rooms room : serverRoomMap.get(s2)) {
+                                         log.debug("s2 room: "+room);
                                          maxUsersInRoomS2 += 
room.getNumberOfPartizipants();
                                  }
                                  
@@ -868,11 +873,22 @@ public class ConferenceService {
 
                        }
 
-                       return 
serverRoomMapOrdered.entrySet().iterator().next().getKey();
+                       log.debug("Resulting Server");
+                       
+                       Server s = 
serverRoomMapOrdered.entrySet().iterator().next().getKey();
+                       
+                       if (s == null) {
+                               return null;
+                       }
+                       
+                       //Somehow this object here cannot be serialized cause 
its abused by OpenJPA
+                       //so get a fresh copy from the entity manager and 
return that
+                       return new ServerDTO(s);
                }
 
+               log.error("Could not get server for cluster session");
                //Empty server object
-               return new Server();
+               return null;
        }
        
 }

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStore.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStore.java?rev=1421019&r1=1421018&r2=1421019&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStore.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStore.java
 Wed Dec 12 22:18:03 2012
@@ -12,6 +12,7 @@ import java.util.List;
 import java.util.Random;
 
 import org.apache.openmeetings.OpenmeetingsVariables;
+import org.apache.openmeetings.cluster.beans.ServerDTO;
 import org.apache.openmeetings.conference.room.ClientListHashMapStore;
 import org.apache.openmeetings.conference.room.ClientSession;
 import org.apache.openmeetings.conference.room.RoomClient;
@@ -246,13 +247,13 @@ public class TestHashMapStore extends Ab
                assertTrue(us != null);
 
                // Is running already on server3
-               Server server = conferenceService.getServerForSession(
+               ServerDTO server = conferenceService.getServerForSession(
                                sessionData.getSession_id(), 8);
                log.debug("server " + server);
                assertEquals(server.getId().longValue(), 3);
 
                // New Room requested that is running on no server
-               Server serverNew = conferenceService.getServerForSession(
+               ServerDTO serverNew = conferenceService.getServerForSession(
                                sessionData.getSession_id(), 9);
                log.debug("serverNew " + serverNew);
                assertEquals(serverNew, null);

Added: 
incubator/openmeetings/trunk/singlewebapp/test/ClusterRoomLoginProcess.txt
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/test/ClusterRoomLoginProcess.txt?rev=1421019&view=auto
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/test/ClusterRoomLoginProcess.txt 
(added)
+++ incubator/openmeetings/trunk/singlewebapp/test/ClusterRoomLoginProcess.txt 
Wed Dec 12 22:18:03 2012
@@ -0,0 +1,71 @@
+
+Some important terms: 
+A rtmp url looks for example like: rtmp://localhost:1935/openmeetings/1
+
+Each part of the URL has a name, so the above URL would mean translated:
+rtmp => protocol
+localhost => domain/host
+1935 => port
+openmeetings => webapp
+1 => scope
+
+Usually messages are synced only between users that are in the same scope.
+So if a user joins a conference room, he will first have to connect via RTMP 
to 
+that scope, so that he can receive messages from that scope.
+
+The goal of the cluster login is: 
+  - RTMP traffic is handled via the slave
+  - HTTP traffic is handled via the master
+  
+Clustering HTTP traffic is not the goal of this Master/Slave login. Its all 
about scaling the 
+RTMP traffic.
+
+OpenMeetings has two RTMP connections (as it consists of two SWFs):
+One RTMP connection only handles sync(push) notifications and usual remoting 
(SWF8)
+The other RTMP connection is used for audio/video streaming (SWF10)
+
+Cluster conference room login process:
+
+1. All users will initialize the UI component testSetup.lzx, no matter how 
they join the room (via invitation, via the list of 
+conference rooms, or for example via the Calendar UI).
+
+2. In testSetup.lzx the RPC call Conferenceservice::getServerForSession is 
performed.
+   In case getServerForSession returns null, the user stays on the same server.
+   He will reconnect but using the same host and port variable just changing 
the scope.
+   
+   That means: by default the URL is: 
rtmp://$MASTER_HOST:$MASTER_PORT/openmeetings/hibernate
+   
+   In case he stays on the same server he will reconnect to: 
rtmp://$MASTER_HOST:$MASTER_PORT/openmeetings/$ROOM_ID
+   
+   In case he connects to a slave, he will use: 
rtmp://$SLAVE_HOST:$SLAVE_PORT/openmeetings/$ROOM_ID
+   
+3. In case getServerForSession returns a server object, the address and 
http-port from the server object is taken, 
+as well as the protocol and webapp and the config.xml from the slave is loaded.
+
+4. The config.xml values from the slave are stored to the variables:
+       slaveRtmphostlocal  = server object's address (not loaded from 
config.xml cause this variable is empty by default)
+       slaveRtmpport = rtmpport from slave's config.xml 
+       slaveRtmpTunnelport = rtmpTunnelport from slave's config.xml 
+       slaveRtmpsslport = rtmpsslport from slave's config.xml
+       slaveWebAppRootKey = webAppRootKey from slave's config.xml
+       
+5. The client UI will set the flag (canvas.)"isSlaveHosted" to true 
(mainAttribues.lzx)
+
+6. hibRtmpConnection.lzx has methods: getHost, getPort, getProtocol, 
getWebappRootKey that does return different values depending
+on if the user is hosted on the slave (isSlaveHosted = true) or not. Based on 
those methods hibRtmpConnection.lzx does create a 
+URL to connect to via rtmp. 
+
+7. This URL is synced to the SWF10 application so that the audio/video part is 
also using the slave's rtmp(t/s) URL. 
+
+8. The usual login process runs through and the client does reconnect to the 
new rtmp(t/s) URL.
+
+9. In canvas of SWF8 and SWF10 there is a method "getUrl". All components that 
upload or download anything via HTTP 
+use those methods to get the HTTP URL. In the getUrl method it is always using 
the rtmphostlocal variable of the 
+master, so that all HTTP traffic goes through the master, not the slave.
+
+Cluster conference room logout process:
+
+1. User clicks on "Exit room"
+
+2. isSlaveHosted is set to false, so that when the user reconnects to the 
scope "hibernate" he will use the master's 
+address,port,webapp again.
\ No newline at end of file


Reply via email to