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;
+ }
+
+ }
+
+}