/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License") + you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
package org.apache.openmeetings.session; | |
import java.math.BigInteger; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collection; | |
import java.util.Date; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Map.Entry; | |
import java.util.Random; | |
import org.apache.openmeetings.OpenmeetingsVariables; | |
import org.apache.openmeetings.data.beans.basic.SearchResult; | |
import org.apache.openmeetings.persistence.beans.basic.Server; | |
import org.apache.openmeetings.persistence.beans.room.Client; | |
import org.apache.openmeetings.session.store.IClientPersistenceStore; | |
import org.apache.openmeetings.utils.crypt.ManageCryptStyle; | |
import org.red5.logging.Red5LoggerFactory; | |
import org.slf4j.Logger; | |
import org.springframework.beans.factory.annotation.Autowired; | |
/** | |
* Handle {@link Client} objects. | |
* | |
* Use a kind of decorator pattern to inject the {@link Server} into every call. | |
* | |
* @author sebawagner | |
* | |
*/ | |
public class SessionManager implements ISessionManager { | |
protected static final Logger log = Red5LoggerFactory.getLogger( | |
SessionManager.class, OpenmeetingsVariables.webAppRootKey); | |
@Autowired | |
private ServerUtil serverUtil; | |
@Autowired | |
private ManageCryptStyle manageCryptStyle; | |
/** | |
* Injected via Spring, needs a getter/setter because it can be configured | |
* Autowired will not suit here as there are multiple implementations of the | |
* {@link IClientPersistenceStore} | |
*/ | |
private IClientPersistenceStore cache; | |
public IClientPersistenceStore getCache() { | |
return cache; | |
} | |
public void setCache(IClientPersistenceStore cache) { | |
this.cache = cache; | |
} | |
private ISessionManager sessionManager = new ISessionManager() { | |
public synchronized Client addClientListItem(String streamId, | |
String scopeName, Integer remotePort, String remoteAddress, | |
String swfUrl, boolean isAVClient, Server server) { | |
try { | |
// Store the Connection into a bean and add it to the HashMap | |
Client rcm = new Client(); | |
rcm.setConnectedSince(new Date()); | |
rcm.setStreamid(streamId); | |
rcm.setScope(scopeName); | |
long random = System.currentTimeMillis() + new BigInteger(256, new Random()).longValue(); | |
rcm.setPublicSID(manageCryptStyle.getInstanceOfCrypt() | |
.createPassPhrase(String.valueOf(random).toString())); | |
rcm.setServer(server); | |
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(rcm.getStreamid(), rcm); | |
return rcm; | |
} catch (Exception err) { | |
log.error("[addClientListItem]", err); | |
} | |
return null; | |
} | |
public synchronized Collection<Client> getClients() { | |
return cache.getClients(); | |
} | |
public synchronized Collection<Client> getClientsWithServer() { | |
return cache.getClientsWithServer(); | |
} | |
public synchronized Client getClientByStreamId(String streamId, Server server) { | |
try { | |
if (!cache.containsKey(server, streamId)) { | |
log.debug("Tried to get a non existing Client " + streamId + " server " + server); | |
return null; | |
} | |
return cache.get(server, streamId); | |
} catch (Exception err) { | |
log.error("[getClientByStreamId]", err); | |
} | |
return null; | |
} | |
public Client getClientByPublicSID(String publicSID, boolean isAVClient, Server server) { | |
try { | |
for (Client rcl : cache.getClientsByPublicSID(server, publicSID)) { | |
if (rcl.getIsAVClient() != isAVClient) { | |
continue; | |
} | |
return rcl; | |
} | |
} catch (Exception err) { | |
log.error("[getClientByPublicSID]", err); | |
} | |
return null; | |
} | |
public ClientSessionInfo getClientByPublicSIDAnyServer(String publicSID, boolean isAVClient) { | |
try { | |
for (Entry<Long,List<Client>> entry : cache.getClientsByPublicSID(publicSID).entrySet()) { | |
for (Client rcl : entry.getValue()) { | |
if (rcl.getIsAVClient() != isAVClient) { | |
continue; | |
} | |
return new ClientSessionInfo(rcl, entry.getKey()); | |
} | |
} | |
} catch (Exception err) { | |
log.error("[getClientByPublicSIDAnyServer]", err); | |
} | |
return null; | |
} | |
public synchronized Client getClientByUserId(Long userId) { | |
try { | |
for (Client rcl : cache.getClientsByUserId(null, userId)) { | |
if (rcl.getIsScreenClient() != null && rcl.getIsScreenClient()) { | |
continue; | |
} | |
if (rcl.getIsAVClient()) { | |
continue; | |
} | |
return rcl; | |
} | |
} catch (Exception err) { | |
log.error("[getClientByUserId]", err); | |
} | |
return null; | |
} | |
public synchronized Boolean updateAVClientByStreamId(String streamId, Client rcm, Server server) { | |
try { | |
// get the corresponding user session object and update the settings | |
Client rclUsual = getClientByPublicSID(rcm.getPublicSID(), false, server); | |
if (rclUsual != null) { | |
rclUsual.setBroadCastID(rcm.getBroadCastID()); | |
rclUsual.setAvsettings(rcm.getAvsettings()); | |
rclUsual.setVHeight(rcm.getVHeight()); | |
rclUsual.setVWidth(rcm.getVWidth()); | |
rclUsual.setVX(rcm.getVX()); | |
rclUsual.setVY(rcm.getVY()); | |
Client rclSaved = cache.get(server, rclUsual.getStreamid()); | |
if (rclSaved != null) { | |
cache.put(rclUsual.getStreamid(), rclUsual); | |
} else { | |
log.debug("Tried to update a non existing Client " + rclUsual.getStreamid()); | |
} | |
} | |
updateClientByStreamId(streamId, rcm, false, server); | |
} catch (Exception err) { | |
log.error("[updateAVClientByStreamId]", err); | |
} | |
return null; | |
} | |
public synchronized Boolean updateClientByStreamId(String streamId, | |
Client rcm, boolean updateRoomCount, Server server) { | |
try { | |
Client rclSaved = cache.get(server, streamId); | |
if (rclSaved != null) { | |
cache.put(streamId, rcm); | |
return true; | |
} else { | |
log.debug("Tried to update a non existing Client " + streamId); | |
return false; | |
} | |
} catch (Exception err) { | |
log.error("[updateClientByStreamId]", err); | |
} | |
return null; | |
} | |
public synchronized Boolean removeClient(String streamId, Server server) { | |
try { | |
if (cache.containsKey(server,streamId)) { | |
cache.remove(server,streamId); | |
return true; | |
} else { | |
log.debug("Tried to remove a non existing Client " + streamId); | |
return false; | |
} | |
} catch (Exception err) { | |
log.error("[removeClient]", err); | |
} | |
return null; | |
} | |
public synchronized ArrayList<Client> getClientListByRoom(Long roomId) { | |
ArrayList<Client> roomClientList = new ArrayList<Client>(); | |
try { | |
for (Client rcl : cache.getClientsByRoomId(roomId)) { | |
if (rcl.getIsScreenClient() == null || rcl.getIsScreenClient()) { | |
continue; | |
} | |
if (rcl.getIsAVClient()) { | |
continue; | |
} | |
// Only parse really those users out that are really a full session object | |
// and no pseudo session object like the audio/video or screen | |
// sharing connection | |
roomClientList.add(rcl); | |
} | |
} catch (Exception err) { | |
log.error("[getClientListByRoom]", err); | |
} | |
return roomClientList; | |
} | |
public synchronized Collection<Client> getClientListByRoomAll(Long roomId) { | |
try { | |
return cache.getClientsByRoomId(roomId); | |
} catch (Exception err) { | |
log.error("[getClientListByRoomAll]", err); | |
} | |
return null; | |
} | |
public synchronized List<Client> getCurrentModeratorByRoom(Long room_id) { | |
List<Client> rclList = new LinkedList<Client>(); | |
List<Client> currentClients = this.getClientListByRoom(room_id); | |
for (Client rcl : currentClients) { | |
if (rcl.getIsMod()) { | |
rclList.add(rcl); | |
} | |
} | |
return rclList; | |
} | |
// FIXME not sorted | |
public synchronized SearchResult<Client> getListByStartAndMax( | |
int start, int max, String orderby, boolean asc) { | |
SearchResult<Client> sResult = new SearchResult<Client>(); | |
sResult.setObjectName(Client.class.getName()); | |
sResult.setRecords(Long.valueOf(cache.size()).longValue()); | |
sResult.setResult(cache.getClientsWithServer()); | |
return sResult; | |
} | |
public long getRecordingCount(long roomId) { | |
List<Client> currentClients = this.getClientListByRoom(roomId); | |
int numberOfRecordingUsers = 0; | |
for (Client rcl : currentClients) { | |
if (rcl.isStartRecording()) { | |
numberOfRecordingUsers++; | |
} | |
} | |
return numberOfRecordingUsers; | |
} | |
public long getPublishingCount(long roomId) { | |
List<Client> currentClients = this.getClientListByRoom(roomId); | |
int numberOfPublishingUsers = 0; | |
for (Client rcl : currentClients) { | |
if (rcl.isStreamPublishStarted()) { | |
numberOfPublishingUsers++; | |
} | |
} | |
return numberOfPublishingUsers; | |
} | |
public List<Long> getActiveRoomIdsByServer(Server server) { | |
return cache.getRoomsIdsByServer(server); | |
} | |
public String getSessionStatistics() { | |
return cache.getDebugInformation(Arrays.asList(IClientPersistenceStore.DEBUG_DETAILS.SIZE)); | |
} | |
public void sessionStart() { | |
// TODO Auto-generated method stub | |
} | |
}; | |
public Client addClientListItem(String streamId, String scopeName, | |
Integer remotePort, String remoteAddress, String swfUrl, | |
boolean isAVClient, Server server) { | |
if (server == null) { | |
server = serverUtil.getCurrentServer(); | |
} | |
return sessionManager.addClientListItem(streamId, scopeName, | |
remotePort, remoteAddress, swfUrl, isAVClient, server); | |
} | |
public Collection<Client> getClients() { | |
return sessionManager.getClients(); | |
} | |
public Collection<Client> getClientsWithServer() { | |
return sessionManager.getClientsWithServer(); | |
} | |
public Client getClientByStreamId(String streamId, Server server) { | |
if (server == null) { | |
server = serverUtil.getCurrentServer(); | |
} | |
return sessionManager.getClientByStreamId(streamId, server); | |
} | |
public Client getClientByPublicSID(String publicSID, boolean isAVClient, | |
Server server) { | |
if (server == null) { | |
server = serverUtil.getCurrentServer(); | |
} | |
return sessionManager.getClientByPublicSID(publicSID, isAVClient, | |
server); | |
} | |
public ClientSessionInfo getClientByPublicSIDAnyServer(String publicSID, | |
boolean isAVClient) { | |
return sessionManager.getClientByPublicSIDAnyServer(publicSID, | |
isAVClient); | |
} | |
public Client getClientByUserId(Long userId) { | |
return sessionManager.getClientByUserId(userId); | |
} | |
public Boolean updateAVClientByStreamId(String streamId, Client rcm, Server server) { | |
if (server == null) { | |
server = serverUtil.getCurrentServer(); | |
} | |
return sessionManager.updateAVClientByStreamId(streamId, rcm, server); | |
} | |
public Boolean updateClientByStreamId(String streamId, Client rcm, | |
boolean updateRoomCount, Server server) { | |
if (server == null) { | |
server = serverUtil.getCurrentServer(); | |
} | |
return sessionManager.updateClientByStreamId(streamId, rcm, | |
updateRoomCount, server); | |
} | |
public Boolean removeClient(String streamId, Server server) { | |
if (server == null) { | |
server = serverUtil.getCurrentServer(); | |
} | |
return sessionManager.removeClient(streamId, server); | |
} | |
public List<Client> getClientListByRoom(Long room_id) { | |
return sessionManager.getClientListByRoom(room_id); | |
} | |
public Collection<Client> getClientListByRoomAll(Long room_id) { | |
return sessionManager.getClientListByRoomAll(room_id); | |
} | |
public List<Client> getCurrentModeratorByRoom(Long room_id) { | |
return sessionManager.getCurrentModeratorByRoom(room_id); | |
} | |
public SearchResult<Client> getListByStartAndMax(int start, int max, | |
String orderby, boolean asc) { | |
return sessionManager.getListByStartAndMax(start, max, orderby, asc); | |
} | |
public long getRecordingCount(long roomId) { | |
return sessionManager.getRecordingCount(roomId); | |
} | |
public long getPublishingCount(long roomId) { | |
return sessionManager.getPublishingCount(roomId); | |
} | |
public List<Long> getActiveRoomIdsByServer(Server server) { | |
return sessionManager.getActiveRoomIdsByServer(server == null ? serverUtil.getCurrentServer() : server); | |
} | |
public String getSessionStatistics() { | |
return sessionManager.getSessionStatistics(); | |
} | |
public void sessionStart() { | |
sessionManager.sessionStart(); | |
} | |
} |