Author: sebawagner
Date: Fri Dec 14 07:41:54 2012
New Revision: 1421702

URL: http://svn.apache.org/viewvc?rev=1421702&view=rev
Log:
OPENMEETINGS-460 Fixes: When a user is hosted on a slave and uploads a 
document, the document is uploaded via HTTP and send to the server. The upload 
complete message has to be send to the slave server first, the master can't 
send a upload complete message.
Also fixes a Bug + provides a JUnit test for an bug in the getServerForSession 
method

Added:
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStoreSyncBug.java
Modified:
    
incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/presenter/guiPresenter.lzx
    
incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/upload/uploadWindowExplorer.lzx
    
incubator/openmeetings/trunk/singlewebapp/WebContent/src/modules/admin/connections/roomClient.lzx
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebService.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebServiceFacade.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/ServerDTO.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/sync/RestClient.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/documents/beans/UploadCompleteMessage.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/quartz/scheduler/ClusterSlaveJob.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/BackupImportController.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/ImportController.java
    
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/UploadController.java

Modified: 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/presenter/guiPresenter.lzx
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/presenter/guiPresenter.lzx?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/presenter/guiPresenter.lzx
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/presenter/guiPresenter.lzx
 Fri Dec 14 07:41:54 2012
@@ -128,6 +128,10 @@
     <handler name="onwidth" args="w">
         <![CDATA[
             if (this.isresizeing){
+               if (w<40){
+                       this.setAttribute('width',41); 
+                       this._resizeview.onmouseup.sendEvent();
+               }
                 if (w<_titlebar._title.width+70) {
                     this.setAttribute('width',_titlebar._title.width+71); 
                     this._resizeview.onmouseup.sendEvent();
@@ -454,7 +458,7 @@
                                colorTo="$once{ 
canvas.getThemeColor('styleMenuBarBaseColor') }" >
                </gradientview>
                
-        <text fontsize="10" height="17" x="6" y="1" text="${ 
this.parent.parent.title }" 
+        <text name="_title" fontsize="10" height="17" x="6" y="1" text="${ 
this.parent.parent.title }" 
                        fgcolor="0xFFFFFF" resize="true" fontstyle="bold" />
                        
            <view name="_toolbar" visibility="$once{ 
((parent.parent.fullToolBar) ? 'visible' : 'hidden' ) }" 

Modified: 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/upload/uploadWindowExplorer.lzx
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/upload/uploadWindowExplorer.lzx?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/upload/uploadWindowExplorer.lzx
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/base/components/upload/uploadWindowExplorer.lzx
 Fri Dec 14 07:41:54 2012
@@ -116,23 +116,21 @@
             
             if (parent._loadToWhiteboard.getValue()) {
                
-               var fileExplorerItem = tArrayValueObj.fileExplorerItem;
-               
                if ($debug) Debug.write(tArrayValueObj);
-               if (fileExplorerItem.isPresentation) {
-                       var url = this.formatURL(fileExplorerItem.fileHash);
+               if (tArrayValueObj.isPresentation) {
+                       var url = this.formatURL(tArrayValueObj.fileHash);
                        
-                       var uploadmoduleimgfolderVar = '/' + 
fileExplorerItem.fileHash;
+                       var uploadmoduleimgfolderVar = '/' + 
tArrayValueObj.fileHash;
                        
                        if ($debug) Debug.write(url);
                        
-                       
canvas._drawarea.loadSWFPresentationSynced(url,fileExplorerItem.fileHash + 
".swf",
+                       
canvas._drawarea.loadSWFPresentationSynced(url,tArrayValueObj.fileHash + ".swf",
                               
"videoconf1",uploadmoduleimgfolderVar,"files",hib.conferencedomain,1,
-                              fileExplorerItem.fileName);
-               } else if (fileExplorerItem.isImage) {
-                       
canvas._drawarea.parent.parent.clearAreaAndAddImage(this.generateFileLink(fileExplorerItem.fileHash),0,0,
+                              tArrayValueObj.fileSystemName);
+               } else if (tArrayValueObj.isImage) {
+                       
canvas._drawarea.parent.parent.clearAreaAndAddImage(this.generateFileLink(tArrayValueObj.fileHash),0,0,
                       canvas.getUrl() +'DownloadHandler',
-                      
fileExplorerItem.fileHash,"videoconf1","/","files",hib.conferencedomain);
+                      
tArrayValueObj.fileHash,"videoconf1","/","files",hib.conferencedomain);
                }
             }
             

Modified: 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/modules/admin/connections/roomClient.lzx
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/WebContent/src/modules/admin/connections/roomClient.lzx?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/modules/admin/connections/roomClient.lzx
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/WebContent/src/modules/admin/connections/roomClient.lzx
 Fri Dec 14 07:41:54 2012
@@ -78,8 +78,8 @@
                        var tServer = "master";
                        var serverId = 0;
                        if (records[i].server != null) {
-                               serverId = records[i].server.id;
-                               tServer = "slave "+records[i].server.address+" 
["+records[i].server.id+"]";
+                               serverId = records[i].server;
+                               tServer = "slave " + " ["+serverId+"]";
                        }
                
                        new lz.roomClientListItem(this._innerlist._inn._inn,{

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebService.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebService.java?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebService.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/axis/services/RoomWebService.java
 Fri Dec 14 07:41:54 2012
@@ -41,6 +41,7 @@ import org.apache.openmeetings.data.conf
 import org.apache.openmeetings.data.conference.Roommanagement;
 import org.apache.openmeetings.data.flvrecord.FlvRecordingDao;
 import org.apache.openmeetings.data.user.Usermanagement;
+import org.apache.openmeetings.documents.beans.UploadCompleteMessage;
 import org.apache.openmeetings.persistence.beans.calendar.Appointment;
 import org.apache.openmeetings.persistence.beans.flvrecord.FlvRecording;
 import org.apache.openmeetings.persistence.beans.invitation.Invitations;
@@ -2487,17 +2488,15 @@ public class RoomWebService {
         * @param paramName
         * @param paramValue
         * @return 1 in case of success, -2 if permissions are insufficient
-        * @throws AxisFault if any error ocurred
+        * @throws AxisFault if any error occurred
         */
        public int modifyRoomParameter(String SID, Long room_id, String 
paramName, String paramValue)
                        throws AxisFault {
                try {
                        Long users_id = sessionManagement.checkSession(SID);
                        Long user_level = 
userManagement.getUserLevelByID(users_id);
-       
-                       log.debug("closeRoom 1 " + room_id);
-       
                        if 
(authLevelManagement.checkWebServiceLevel(user_level)) {
+                               log.debug("closeRoom 1 " + room_id);
                                Rooms r = roomDao.get(room_id);
                                PropertyUtils.setSimpleProperty(r, paramName, 
paramValue);
                                roomDao.update(r, users_id);
@@ -2511,4 +2510,51 @@ public class RoomWebService {
                        throw new AxisFault(err.getMessage());
                }
        }
+       
+       /**
+        * This method is used in cluster mode to send the sync event from the 
master to the slave
+        * 
+        * @param SID The SID of the User. This SID must be marked as logged'in
+        * @param publicSID The publicSID that will receive the message
+        * @param userId part of sync message of document upload
+        * @param message part of sync message of document upload
+        * @param action part of sync message of document upload
+        * @param error part of sync message of document upload
+        * @param hasError part of sync message of document upload
+        * @param fileName part of sync message of document upload
+        * @param fileSystemName part of sync message of document upload
+        * @param isPresentation part of sync message of document upload
+        * @param isImage part of sync message of document upload
+        * @param isVideo part of sync message of document upload
+        * @param fileHash part of sync message of document upload
+        * @return
+        * @throws AxisFault if any error occurred
+        */
+       public boolean syncUploadCompleteMessage(String SID, String publicSID,
+                       Long userId, String message, String action, String 
error,
+                       boolean hasError, String fileName, String 
fileSystemName,
+                       boolean isPresentation, boolean isImage, boolean 
isVideo,
+                       String fileHash) throws AxisFault {
+
+               try {
+                       Long users_id = sessionManagement.checkSession(SID);
+                       Long user_level = 
userManagement.getUserLevelByID(users_id);
+                       if 
(authLevelManagement.checkWebServiceLevel(user_level)) {
+
+                               
scopeApplicationAdapter.sendMessageWithClientByPublicSID(
+                                               new 
UploadCompleteMessage(userId, message, action,
+                                                               error, 
hasError, fileName, fileSystemName,
+                                                               isPresentation, 
isImage, isVideo, fileHash),
+                                               publicSID);
+
+                               return true;
+                       }
+               } catch (Exception err) {
+                       log.error("[syncUploadCompleteMessage] ", err);
+
+                       throw new AxisFault(err.getMessage());
+               }
+               return false;
+       }
+       
 }

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=1421702&r1=1421701&r2=1421702&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
 Fri Dec 14 07:41:54 2012
@@ -51,7 +51,8 @@ public class RoomWebServiceFacade {
        private RoomWebService getRoomServiceProxy() {
                try {
                        if (!ScopeApplicationAdapter.initComplete) {
-                               throw new Exception("Server not yet 
initialized, retry in couple of seconds");
+                               throw new Exception(
+                                               "Server not yet initialized, 
retry in couple of seconds");
                        }
                        ApplicationContext context = WebApplicationContextUtils
                                        
.getWebApplicationContext(getServletContext());
@@ -669,8 +670,20 @@ public class RoomWebServiceFacade {
                return this.getRoomServiceProxy().closeRoom(SID, room_id, 
status);
        }
 
-       public int modifyRoomParameter(String SID, Long room_id, String 
paramName, String paramValue)
-                       throws AxisFault {
-               return getRoomServiceProxy().modifyRoomParameter(SID, room_id, 
paramName, paramValue);
+       public int modifyRoomParameter(String SID, Long room_id, String 
paramName,
+                       String paramValue) throws AxisFault {
+               return getRoomServiceProxy().modifyRoomParameter(SID, room_id,
+                               paramName, paramValue);
+       }
+
+       public boolean syncUploadCompleteMessage(String SID, String publicSID,
+                       Long userId, String message, String action, String 
error,
+                       boolean hasError, String fileName, String 
fileSystemName,
+                       boolean isPresentation, boolean isImage, boolean 
isVideo,
+                       String fileHash) throws AxisFault {
+               return getRoomServiceProxy().syncUploadCompleteMessage(SID, 
publicSID,
+                               userId, message, action, error, hasError, 
fileName,
+                               fileSystemName, isPresentation, isImage, 
isVideo, fileHash);
        }
+       
 }

Modified: 
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=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/ServerDTO.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/beans/ServerDTO.java
 Fri Dec 14 07:41:54 2012
@@ -78,5 +78,10 @@ public class ServerDTO {
        public void setWebapp(String webapp) {
                this.webapp = webapp;
        }
+       
+       @Override
+       public String toString() {
+               return "id "+id+" address "+address+" port "+port+" protocol 
"+protocol;
+       }
 
 }

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/sync/RestClient.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/sync/RestClient.java?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/sync/RestClient.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/cluster/sync/RestClient.java
 Fri Dec 14 07:41:54 2012
@@ -37,6 +37,7 @@ import org.apache.axis2.transport.http.H
 import org.apache.openmeetings.OpenmeetingsVariables;
 import org.apache.openmeetings.conference.room.RoomClient;
 import org.apache.openmeetings.conference.room.SlaveClientDto;
+import org.apache.openmeetings.documents.beans.UploadCompleteMessage;
 import org.apache.openmeetings.persistence.beans.basic.Server;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -55,7 +56,12 @@ public class RestClient {
                        RestClient.class, OpenmeetingsVariables.webAppRootKey);
        
        private enum Action {
-               PING, KICK_USER
+               //send a ping to the user
+               PING, 
+               //kick the user from the server
+               KICK_USER,
+               //send a sync message to a client on that server
+               SYNC_MESSAGE
        }
 
        /**
@@ -77,6 +83,15 @@ public class RestClient {
        private boolean pingRunning = false;
 
        private String publicSID;
+
+       private UploadCompleteMessage uploadCompleteMessage;
+
+       /**
+        * there are two publicSIDs, one for the kickUser REST call and one for 
the syncMessage call
+        * theoretically they could be performed at the same time but to 
different users, so we don't want
+        * to use the same variable for both
+        */
+       private String publicSIDSync;
        
        private static String nameSpaceForSlaveDto = 
"http://room.conference.openmeetings.apache.org/xsd";;
        
@@ -100,6 +115,11 @@ public class RestClient {
                return protocol + "://" + host + ":" + port + "/" + webapp
                                + "/services/ServerService";
        }
+       
+       private String getRoomServiceEndPoint() {
+               return protocol + "://" + host + ":" + port + "/" + webapp
+                               + "/services/RoomService";
+       }
 
        /**
         * The observerInstance will be notified whenever a ping was completed
@@ -200,21 +220,8 @@ public class RestClient {
         */
        public void loginUser(Action action) throws Exception {
 
-               Options options = new Options();
-               options.setTo(new EndpointReference(getUserServiceEndPoint()));
-               options.setProperty(Constants.Configuration.ENABLE_REST,
-                               Constants.VALUE_TRUE);
-               int timeOutInMilliSeconds = 2000;
-               // setting timeout to 2 second should be sufficient, if the 
server is
-               // not available within the 3 second interval you got a problem 
anyway
-               options.setTimeOutInMilliSeconds(timeOutInMilliSeconds);
-               options.setProperty(HTTPConstants.SO_TIMEOUT, 
timeOutInMilliSeconds);
-               options.setProperty(HTTPConstants.CONNECTION_TIMEOUT, 
timeOutInMilliSeconds); 
-
-               ServiceClient sender = new ServiceClient();
-               sender.engageModule(new QName(Constants.MODULE_ADDRESSING)
-                               .getLocalPart());
-               sender.setOptions(options);
+               ServiceClient sender = 
createServiceClient(getUserServiceEndPoint());
+               
                OMElement getSessionResult = sender
                                .sendReceive(getPayloadMethodGetSession());
                sessionId = getSessionIdFromResult(getSessionResult);
@@ -228,12 +235,117 @@ public class RestClient {
                        ping();
                } else if (action == Action.KICK_USER) {
                        kickUserInternl();
+               } else if (action == Action.SYNC_MESSAGE) {
+                       syncMessageInternl();
+               }
+
+       }
+       
+       private ServiceClient createServiceClient(String serviceEndPoint) 
throws Exception {
+               ServiceClient sender = new ServiceClient();
+               sender.engageModule(new QName(Constants.MODULE_ADDRESSING)
+                               .getLocalPart());
+               Options options = new Options();
+               options.setTo(new EndpointReference(serviceEndPoint));
+               options.setProperty(Constants.Configuration.ENABLE_REST,
+                               Constants.VALUE_TRUE);
+               int timeOutInMilliSeconds = 2000;
+               // setting timeout to 2 second should be sufficient, if the 
server is
+               // not available within the 3 second interval you got a problem 
anyway
+               options.setTimeOutInMilliSeconds(timeOutInMilliSeconds);
+               options.setProperty(HTTPConstants.SO_TIMEOUT, 
timeOutInMilliSeconds);
+               options.setProperty(HTTPConstants.CONNECTION_TIMEOUT, 
timeOutInMilliSeconds);
+               sender.setOptions(options);
+               
+               return sender;
+       }
+       
+       private OMElement createOMElement(OMFactory fac, OMNamespace omNs, 
String name, String value) {
+               OMElement omElement = fac.createOMElement(name, omNs);
+               omElement.addChild(fac.createOMText(omElement, value));
+               return omElement;
+       }
+
+       
+       /**
+        * set s the publicSID the message object and sends it to the slave by 
calling a REST service
+        * 
+        * @param publicSID
+        * @param uploadCompleteMessage
+        */
+       public void syncMessage(String publicSID, UploadCompleteMessage 
uploadCompleteMessage) {
+               this.publicSIDSync = publicSID;
+               this.uploadCompleteMessage = uploadCompleteMessage;
+               syncMessageInternl();
+       }
+       
+       private void syncMessageInternl() {
+               try {
+                       
+                       if (!loginSuccess) {
+                               loginUser(Action.SYNC_MESSAGE);
+                       }
+                       
+                       ServiceClient sender = 
createServiceClient(getRoomServiceEndPoint());
+                       OMElement syncMessageResult = sender
+                                       
.sendReceive(getPayloadMethodSyncMessage());
+                       Boolean result = 
syncMessageResultFromResult(syncMessageResult);
+                       
+                       if (!result) {
+                               throw new Exception("Could not sync message to 
slave host");
+                       }
+                       
+               } catch (Exception err) {
+                       log.error("[syncMessage failed]", err);
                }
+       }
+       
+       private Boolean syncMessageResultFromResult(OMElement result) throws 
Exception {
+               QName kickUserResult = new QName(NAMESPACE_PREFIX, "return");
 
+               @SuppressWarnings("unchecked")
+               Iterator<OMElement> elements = 
result.getChildrenWithName(kickUserResult);
+               if (elements.hasNext()) {
+                       OMElement resultElement = elements.next();
+                       if (resultElement.getText().equals("true")) {
+                               return true;
+                       } else {
+                               throw new Exception("Could not delete user from 
slave host, returns: "
+                                               + resultElement.getText());
+                       }
+               } else {
+                       throw new Exception("Could not parse 
kickUserByPublicSID result");
+               }
        }
        
+       private OMElement getPayloadMethodSyncMessage() {
+               
+               OMFactory fac = OMAbstractFactory.getOMFactory();
+               OMNamespace omNs = fac.createOMNamespace(NAMESPACE_PREFIX, 
"pre");
+               OMElement method = 
fac.createOMElement("syncUploadCompleteMessage", omNs);
+
+               method.addChild(createOMElement(fac, omNs, "SID", sessionId));
+               method.addChild(createOMElement(fac, omNs, "publicSID", 
publicSIDSync));
+               method.addChild(createOMElement(fac, omNs, "userId", ""+ 
uploadCompleteMessage.getUserId()));
+               method.addChild(createOMElement(fac, omNs, "message", 
uploadCompleteMessage.getMessage()));
+               method.addChild(createOMElement(fac, omNs, "action", 
uploadCompleteMessage.getAction()));
+               method.addChild(createOMElement(fac, omNs, "error", 
uploadCompleteMessage.getError()));
+               method.addChild(createOMElement(fac, omNs, "hasError", 
""+uploadCompleteMessage.isHasError()));
+               method.addChild(createOMElement(fac, omNs, "fileName", 
uploadCompleteMessage.getFileName()));
+               
+               method.addChild(createOMElement(fac, omNs, "fileSystemName", 
uploadCompleteMessage.getFileSystemName()));
+               method.addChild(createOMElement(fac, omNs, "isPresentation", 
""+uploadCompleteMessage.getIsPresentation()));
+               method.addChild(createOMElement(fac, omNs, "isImage", 
""+uploadCompleteMessage.getIsImage()));
+               method.addChild(createOMElement(fac, omNs, "isVideo", 
""+uploadCompleteMessage.getIsVideo()));
+               method.addChild(createOMElement(fac, omNs, "fileHash", 
uploadCompleteMessage.getFileHash()));
+               
+               return method;
+       }
+
        /**
         * sets the publicSID and removes a user from a slave host by calling a 
REST service
+        * 
+        * @param publicSID
         */
        public void kickUser(String publicSID) {
                this.publicSID = publicSID;
@@ -246,22 +358,9 @@ public class RestClient {
                        if (!loginSuccess) {
                                loginUser(Action.KICK_USER);
                        }
+
+                       ServiceClient sender = 
createServiceClient(getUserServiceEndPoint());
                        
-                       Options options = new Options();
-                       options.setTo(new 
EndpointReference(getUserServiceEndPoint()));
-                       options.setProperty(Constants.Configuration.ENABLE_REST,
-                                       Constants.VALUE_TRUE);
-                       int timeOutInMilliSeconds = 2000;
-                       // setting timeout to 2 second should be sufficient, if 
the server is
-                       // not available within the 3 second interval you got a 
problem anyway
-                       options.setTimeOutInMilliSeconds(timeOutInMilliSeconds);
-                       options.setProperty(HTTPConstants.SO_TIMEOUT, 
timeOutInMilliSeconds);
-                       options.setProperty(HTTPConstants.CONNECTION_TIMEOUT, 
timeOutInMilliSeconds); 
-
-                       ServiceClient sender = new ServiceClient();
-                       sender.engageModule(new 
QName(Constants.MODULE_ADDRESSING)
-                                       .getLocalPart());
-                       sender.setOptions(options);
                        OMElement kickUserByPublicSIDResult = sender
                                        
.sendReceive(getPayloadMethodKickUserByPublicSID());
                        Boolean result = 
kickUserByPublicSIDFromResult(kickUserByPublicSIDResult);
@@ -297,15 +396,8 @@ public class RestClient {
                OMFactory fac = OMAbstractFactory.getOMFactory();
                OMNamespace omNs = fac.createOMNamespace(NAMESPACE_PREFIX, 
"pre");
                OMElement method = fac.createOMElement("kickUserByPublicSID", 
omNs);
-
-               OMElement sid = fac.createOMElement("SID", omNs);
-               sid.addChild(fac.createOMText(sid, sessionId));
-               method.addChild(sid);
-
-               OMElement publicSIDOmElement = fac.createOMElement("publicSID", 
omNs);
-               
publicSIDOmElement.addChild(fac.createOMText(publicSIDOmElement, publicSID));
-               method.addChild(publicSIDOmElement);
-
+               method.addChild(createOMElement(fac, omNs, "SID", sessionId));
+               method.addChild(createOMElement(fac, omNs, "publicSID", 
publicSID));
                return method;
        }
 
@@ -326,22 +418,7 @@ public class RestClient {
                                loginUser(Action.PING);
                        } else {
                                 
-                               Options options = new Options();
-                               options.setTo(new 
EndpointReference(getServerServiceEndPoint()));
-                               
options.setProperty(Constants.Configuration.ENABLE_REST,
-                                               Constants.VALUE_TRUE);
-                               int timeOutInMilliSeconds = 2000;
-                               // setting timeout to 2 second should be 
sufficient, if the server is
-                               // not available within the 3 second interval 
you got a problem anyway
-                               
options.setTimeOutInMilliSeconds(timeOutInMilliSeconds);
-                               options.setProperty(HTTPConstants.SO_TIMEOUT, 
timeOutInMilliSeconds);
-                               
options.setProperty(HTTPConstants.CONNECTION_TIMEOUT, timeOutInMilliSeconds); 
-
-                               ServiceClient sender = new ServiceClient();
-                               sender.engageModule(new 
QName(Constants.MODULE_ADDRESSING)
-                                               .getLocalPart());
-                               sender.setOptions(options);
-
+                               ServiceClient sender = 
createServiceClient(getServerServiceEndPoint());
                                OMElement pingResult = sender
                                                
.sendReceive(getPayloadMethodPingTemp());
 
@@ -412,19 +489,9 @@ public class RestClient {
                OMFactory fac = OMAbstractFactory.getOMFactory();
                OMNamespace omNs = fac.createOMNamespace(NAMESPACE_PREFIX, 
"pre");
                OMElement method = fac.createOMElement("loginUser", omNs);
-
-               OMElement sid = fac.createOMElement("SID", omNs);
-               sid.addChild(fac.createOMText(sid, sessionId));
-               method.addChild(sid);
-
-               OMElement username = fac.createOMElement("username", omNs);
-               username.addChild(fac.createOMText(username, user));
-               method.addChild(username);
-
-               OMElement userpass = fac.createOMElement("userpass", omNs);
-               userpass.addChild(fac.createOMText(userpass, pass));
-               method.addChild(userpass);
-
+               method.addChild(createOMElement(fac, omNs, "SID", sessionId));
+               method.addChild(createOMElement(fac, omNs, "username", user));
+               method.addChild(createOMElement(fac, omNs, "userpass", pass));
                return method;
        }
 
@@ -464,11 +531,7 @@ public class RestClient {
                OMFactory fac = OMAbstractFactory.getOMFactory();
                OMNamespace omNs = fac.createOMNamespace(NAMESPACE_PREFIX, 
"pre");
                OMElement method = fac.createOMElement("ping", omNs);
-
-               OMElement sid = fac.createOMElement("SID", omNs);
-               sid.addChild(fac.createOMText(sid, sessionId));
-               method.addChild(sid);
-
+               method.addChild(createOMElement(fac, omNs, "SID", sessionId));
                return method;
        }
 
@@ -541,5 +604,6 @@ public class RestClient {
                }
                return null;
        }
-
+       
+       
 }

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/documents/beans/UploadCompleteMessage.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/documents/beans/UploadCompleteMessage.java?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/documents/beans/UploadCompleteMessage.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/documents/beans/UploadCompleteMessage.java
 Fri Dec 14 07:41:54 2012
@@ -19,78 +19,162 @@
 package org.apache.openmeetings.documents.beans;
 
 import org.apache.openmeetings.persistence.beans.files.FileExplorerItem;
-import org.apache.openmeetings.persistence.beans.user.Users;
+
 
 /**
- * Helper bean that is send to client(s) once the servlet has completed the 
upload
+ * Helper bean that is send to client(s) once the servlet has completed the
+ * upload
  * 
  * @author sebawagner
- *
+ * 
  */
 public class UploadCompleteMessage {
-       
-       private Users user;
+
+       private Long userId;
        private String message;
        private String action;
        private String error;
        private boolean hasError = false;
        private String fileName;
-       private FileExplorerItem fileExplorerItem;
-       
+
+       // Properties from the file explorerItem
+       private String fileSystemName;
+       private Boolean isPresentation = false;
+       private Boolean isImage = false;
+       private Boolean isVideo = false;
+       private String fileHash;
+
        public UploadCompleteMessage() {
        }
-       
-       public UploadCompleteMessage(Users user, String message, String action,
+
+       public UploadCompleteMessage(Long userId, String message, String action,
                        String error, String fileName) {
                super();
-               this.user = user;
+               this.userId = userId;
                this.message = message;
                this.action = action;
                this.error = error;
                this.fileName = fileName;
        }
 
-       public Users getUser() {
-               return user;
+       public UploadCompleteMessage(Long userId, String message, String action,
+                       String error, boolean hasError, String fileName,
+                       String fileSystemName, boolean isPresentation, boolean 
isImage,
+                       boolean isVideo, String fileHash) {
+               super();
+               this.userId = userId;
+               this.message = message;
+               this.action = action;
+               this.error = error;
+               this.hasError = hasError;
+               this.fileName = fileName;
+               this.fileSystemName = fileSystemName;
+               this.isPresentation = isPresentation;
+               this.isImage = isImage;
+               this.isVideo = isVideo;
+               this.fileHash = fileHash;
        }
-       public void setUser(Users user) {
-               this.user = user;
+
+       public Long getUserId() {
+               return userId;
+       }
+
+       public void setUserId(Long userId) {
+               this.userId = userId;
        }
+
        public String getMessage() {
                return message;
        }
+
        public void setMessage(String message) {
                this.message = message;
        }
+
        public String getAction() {
                return action;
        }
+
        public void setAction(String action) {
                this.action = action;
        }
+
        public String getError() {
                return error;
        }
+
        public void setError(String error) {
                this.error = error;
        }
+
        public String getFileName() {
                return fileName;
        }
+
        public void setFileName(String fileName) {
                this.fileName = fileName;
        }
+
        public boolean isHasError() {
                return hasError;
        }
+
        public void setHasError(boolean hasError) {
                this.hasError = hasError;
        }
-       public FileExplorerItem getFileExplorerItem() {
-               return fileExplorerItem;
+
+       public String getFileSystemName() {
+               return fileSystemName;
+       }
+
+       public void setFileSystemName(String fileSystemName) {
+               this.fileSystemName = fileSystemName;
+       }
+
+       public Boolean getIsPresentation() {
+               return isPresentation;
+       }
+
+       public void setIsPresentation(Boolean isPresentation) {
+               this.isPresentation = isPresentation;
+       }
+
+       public Boolean getIsImage() {
+               return isImage;
+       }
+
+       public void setIsImage(Boolean isImage) {
+               this.isImage = isImage;
+       }
+
+       public Boolean getIsVideo() {
+               return isVideo;
+       }
+
+       public void setIsVideo(Boolean isVideo) {
+               this.isVideo = isVideo;
        }
+
+       public String getFileHash() {
+               return fileHash;
+       }
+
+       public void setFileHash(String fileHash) {
+               this.fileHash = fileHash;
+       }
+
        public void setFileExplorerItem(FileExplorerItem fileExplorerItem) {
-               this.fileExplorerItem = fileExplorerItem;
+               if (fileExplorerItem.getIsImage() != null) {
+                       isImage = fileExplorerItem.getIsImage();
+               }
+               if (fileExplorerItem.getIsVideo() != null) {
+                       isVideo = fileExplorerItem.getIsVideo();
+               }
+               if (fileExplorerItem.getIsPresentation() != null) {
+                       isPresentation = fileExplorerItem.getIsPresentation();
+               }
+               fileSystemName = fileExplorerItem.getFileName();
+               fileHash = fileExplorerItem.getFileHash();
        }
 
 }

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/quartz/scheduler/ClusterSlaveJob.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/quartz/scheduler/ClusterSlaveJob.java?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/quartz/scheduler/ClusterSlaveJob.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/quartz/scheduler/ClusterSlaveJob.java
 Fri Dec 14 07:41:54 2012
@@ -29,6 +29,7 @@ import org.apache.openmeetings.cluster.s
 import org.apache.openmeetings.conference.room.ISharedSessionStore;
 import org.apache.openmeetings.conference.room.SlaveClientDto;
 import org.apache.openmeetings.data.basic.dao.ServerDao;
+import org.apache.openmeetings.documents.beans.UploadCompleteMessage;
 import org.apache.openmeetings.persistence.beans.basic.Server;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
@@ -145,5 +146,28 @@ public class ClusterSlaveJob implements 
                rClient.kickUser(publicSID);
                
        }
+       
+       /**
+        * Gets the current {@link RestClient} from the session store and then
+        * performs a kickUser on that. It is not possible that there is no
+        * {@link RestClient}, because if you want to kick a user from a slave, 
the
+        * master <i>must</i> already have loaded the sessions from the slave, 
so
+        * there logically <i>must</i> by a {@link RestClient} available that 
has an 
+        * open connection to that slave / {@link Server}
+        * 
+        * @param server
+        * @param publicSID
+        * @param uploadCompleteMessage
+        * @throws Exception
+        */
+       public void syncMessageToClientOnSlave(Server server, String publicSID, 
UploadCompleteMessage uploadCompleteMessage) throws Exception {
+               RestClient rClient = getRestClient(server);
+               
+               if (rClient == null) {
+                       throw new Exception("No RestClient found for server " + 
server);
+               }
+               
+               rClient.syncMessage(publicSID, uploadCompleteMessage);
+       }
 
 }

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/BackupImportController.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/BackupImportController.java?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/BackupImportController.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/BackupImportController.java
 Fri Dec 14 07:41:54 2012
@@ -643,7 +643,7 @@ public class BackupImportController exte
                        performImport(is);
 
                        UploadCompleteMessage uploadCompleteMessage = new 
UploadCompleteMessage(
-                                               usersDao.get(info.userId),
+                                               info.userId,
                                                "library", //message
                                                "import", //action
                                                "", //error

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/ImportController.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/ImportController.java?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/ImportController.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/ImportController.java
 Fri Dec 14 07:41:54 2012
@@ -89,7 +89,7 @@ public class ImportController extends Ab
                        log.debug("moduleName.equals(userprofile) ! ");
                        
                        UploadCompleteMessage uploadCompleteMessage = new 
UploadCompleteMessage(
-                                       usersDao.get(info.userId),
+                                       info.userId,
                                        "library", //message
                                        "import", //action
                                        "", //error

Modified: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/UploadController.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/UploadController.java?rev=1421702&r1=1421701&r2=1421702&view=diff
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/UploadController.java
 (original)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/servlet/outputhandler/UploadController.java
 Fri Dec 14 07:41:54 2012
@@ -108,12 +108,13 @@ public class UploadController extends Ab
                                                        parentFolderId, 
info.filename, 0L, ""); // externalFilesId, externalType
        
                        UploadCompleteMessage uploadCompleteMessage = new 
UploadCompleteMessage();
-               uploadCompleteMessage.setUser(usersDao.get(info.userId));
+               uploadCompleteMessage.setUserId(info.userId);
        
                        // Flash cannot read the response of an upload
                        // httpServletResponse.getWriter().print(returnError);
                uploadCompleteMessage.setMessage("library");
                uploadCompleteMessage.setAction("newFile");
+               
                uploadCompleteMessage.setFileExplorerItem(
                                        
fileExplorerItemDao.getFileExplorerItemsById(
                                                        
returnError.getFileExplorerItemId()));
@@ -162,7 +163,7 @@ public class UploadController extends Ab
                        fileSystemName = 
StringUtils.deleteWhitespace(fileSystemName);
        
                        UploadCompleteMessage uploadCompleteMessage = new 
UploadCompleteMessage();
-               uploadCompleteMessage.setUser(usersDao.get(info.userId));
+               uploadCompleteMessage.setUserId(info.userId);
                        
                        // Flash cannot read the response of an upload
                        // httpServletResponse.getWriter().print(returnError);

Added: 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStoreSyncBug.java
URL: 
http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStoreSyncBug.java?rev=1421702&view=auto
==============================================================================
--- 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStoreSyncBug.java
 (added)
+++ 
incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/test/cluster/TestHashMapStoreSyncBug.java
 Fri Dec 14 07:41:54 2012
@@ -0,0 +1,189 @@
+package org.apache.openmeetings.test.cluster;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+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.RoomClient;
+import org.apache.openmeetings.conference.room.SlaveClientDto;
+import org.apache.openmeetings.conference.room.cache.HashMapStore;
+import org.apache.openmeetings.data.basic.dao.ServerDao;
+import org.apache.openmeetings.data.user.Usermanagement;
+import org.apache.openmeetings.persistence.beans.basic.Server;
+import org.apache.openmeetings.persistence.beans.basic.Sessiondata;
+import org.apache.openmeetings.persistence.beans.user.Users;
+import org.apache.openmeetings.remote.ConferenceService;
+import org.apache.openmeetings.remote.MainService;
+import org.apache.openmeetings.test.AbstractOpenmeetingsSpringTest;
+import org.apache.openmeetings.utils.crypt.ICryptString;
+import org.apache.openmeetings.utils.crypt.MD5Implementation;
+import org.apache.openmeetings.utils.math.CalendarPatterns;
+import org.junit.Test;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class TestHashMapStoreSyncBug extends AbstractOpenmeetingsSpringTest {
+
+       protected static final Logger log = Red5LoggerFactory.getLogger(
+                       TestHashMapStoreSyncBug.class, 
OpenmeetingsVariables.webAppRootKey);
+
+       private ClientListHashMapStoreTesting sessionManager = new 
ClientListHashMapStoreTesting();
+
+       @Autowired
+       private MainService mService;
+       @Autowired
+       private Usermanagement userManagement;
+       @Autowired
+       private ConferenceService conferenceService;
+       @Autowired
+       private ServerDao serverDao;
+
+       int localSessions = 200;
+       int slaveSessionSize = 200;
+
+       @Test
+       public void doClientTest() {
+
+               log.debug("Cache size " + 
sessionManager.getAllClients().size());
+               
+               this.sessionManager.addClientListItem("streamId0", "hibernate",
+                               123, "localhost", "", false);
+               
+               RoomClient rcl = 
this.sessionManager.getClientByStreamId("streamId0", null);
+               rcl.setUser_id(Long.parseLong("1"));
+               rcl.setRoom_id(1L);
+               this.sessionManager.updateClientByStreamId("streamId0", rcl, 
false);
+
+               Server s1 = serverDao.get(1L);
+               if (s1 == null) {
+                       serverDao.saveServer(1L, "name 1", "127.0.0.1", 5080, 
"swagner",
+                                       "qweqwe", "openmeetings", "http", true, 
"", 1L);
+                       s1 = serverDao.get(1L);
+               }
+
+               List<SlaveClientDto> clients = new ArrayList<SlaveClientDto>();
+               SlaveClientDto slaveDto = new SlaveClientDto(
+                               //
+                               "streamId0" , //
+                               "publicSID_slave1", //
+                               2L, //
+                               2L, //
+                               "firstName 2" , //
+                               "lastName 2" , //
+                               false, //
+                               "2", //
+                               "username 2" , //
+                               CalendarPatterns
+                                               
.getDateWithTimeByMiliSeconds(new Date())); //
+               clients.add(slaveDto);
+
+               this.sessionManager.syncSlaveClientSession(s1, clients);
+
+               sessionManager.getCache().printDebugInformation(
+                               Arrays.asList(HashMapStore.DEBUG_DETAILS.SIZE,
+                                               
HashMapStore.DEBUG_DETAILS.CLIENT_BY_STREAMID,
+                                               
HashMapStore.DEBUG_DETAILS.CLIENT_BY_PUBLICSID,
+                                               
HashMapStore.DEBUG_DETAILS.CLIENT_BY_USERID,
+                                               
HashMapStore.DEBUG_DETAILS.CLIENT_BY_ROOMID));
+
+               Sessiondata sessionData = mService.getsessiondata();
+
+               Users us = (Users) userManagement.loginUser(
+                               sessionData.getSession_id(), username, 
userpass, null, false);
+
+               log.debug("us " + us);
+
+               assertTrue(us != null);
+               
+               // Is running already on server null
+               ServerDTO server = conferenceService.getServerForSession(
+                               sessionData.getSession_id(), 1);
+               log.debug("server " + server);
+               assertTrue(server == null);
+
+               // Is running already on server 1
+               ServerDTO servert2 = conferenceService.getServerForSession(
+                               sessionData.getSession_id(), 2);
+               log.debug("servert2 " + servert2);
+               assertEquals(servert2.getId().longValue(), 1);
+               
+               //empty server 1
+               List<SlaveClientDto> clientsServer1 = new 
ArrayList<SlaveClientDto>();
+               this.sessionManager.syncSlaveClientSession(s1, clientsServer1);
+               
+               log.debug("\n\r##################### \n\r AFTER USER IS REMOVED 
\n\r####################");
+
+               sessionManager.getCache().printDebugInformation(
+                               Arrays.asList(HashMapStore.DEBUG_DETAILS.SIZE,
+                                               
HashMapStore.DEBUG_DETAILS.CLIENT_BY_STREAMID,
+                                               
HashMapStore.DEBUG_DETAILS.CLIENT_BY_PUBLICSID,
+                                               
HashMapStore.DEBUG_DETAILS.CLIENT_BY_USERID,
+                                               
HashMapStore.DEBUG_DETAILS.CLIENT_BY_ROOMID));
+               
+               // Is running already on server null
+               ServerDTO servert3 = conferenceService.getServerForSession(
+                               sessionData.getSession_id(), 1);
+               log.debug("servert3 " + servert3);
+               assertTrue(servert3 == null);
+
+       }
+
+       private class ClientListHashMapStoreTesting extends 
ClientListHashMapStore {
+
+               public synchronized RoomClient addClientListItem(String 
streamId,
+                               String scopeName, Integer remotePort, String 
remoteAddress,
+                               String swfUrl, boolean isAVClient) {
+                       try {
+
+                               // Store the Connection into a bean and add it 
to the HashMap
+                               RoomClient rcm = new RoomClient();
+                               rcm.setConnectedSince(new Date());
+                               rcm.setStreamid(streamId);
+                               rcm.setScope(scopeName);
+
+                               long random = System.currentTimeMillis()
+                                               + new BigInteger(256, new 
Random()).longValue();
+
+                               ICryptString cryptStyle = new 
MD5Implementation();
+
+                               
rcm.setPublicSID(cryptStyle.createPassPhrase(String.valueOf(
+                                               random).toString()));
+
+                               rcm.setUserport(remotePort);
+                               rcm.setUserip(remoteAddress);
+                               rcm.setSwfurl(swfUrl);
+                               rcm.setIsMod(new Boolean(false));
+                               rcm.setCanDraw(new Boolean(false));
+                               rcm.setIsAVClient(isAVClient);
+
+                               if (cache.containsKey(null, streamId)) {
+                                       log.error("Tried to add an existing 
Client " + streamId);
+                                       return null;
+                               }
+
+                               cache.put(null, rcm.getStreamid(), rcm);
+
+                               return rcm;
+                       } catch (Exception err) {
+                               log.error("[addClientListItem]", err);
+                       }
+                       return null;
+               }
+
+               public HashMapStore getCache() {
+                       return cache;
+               }
+
+       }
+
+}


Reply via email to