You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2020/10/22 05:41:41 UTC
[openmeetings] branch master updated: [OPENMEETINGS-2239,
OPENMEETINGS-677] sip transport with user count is added to the room
This is an automated email from the ASF dual-hosted git repository.
solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git
The following commit(s) were added to refs/heads/master by this push:
new 401e498 [OPENMEETINGS-2239, OPENMEETINGS-677] sip transport with user count is added to the room
401e498 is described below
commit 401e4981c184764d21036204a75ef5dd3098c36e
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Thu Oct 22 12:35:47 2020 +0700
[OPENMEETINGS-2239, OPENMEETINGS-677] sip transport with user count is added to the room
---
openmeetings-core/pom.xml | 8 +
.../openmeetings/core/remote/KurentoHandler.java | 85 ++---
.../openmeetings/core/remote/StreamProcessor.java | 15 +-
.../apache/openmeetings/core/sip/SipManager.java | 108 +++++--
.../core/util/ChatWebSocketHelper.java | 5 +-
.../openmeetings/core/util/WebSocketHelper.java | 33 +-
openmeetings-db/pom.xml | 9 -
.../db/dao/calendar/AppointmentDao.java | 2 +-
.../apache/openmeetings/db/dao/room/RoomDao.java | 7 +-
.../apache/openmeetings/db/dao/room/SipConfig.java | 123 -------
.../openmeetings/db/entity/basic/Client.java | 5 +
.../openmeetings/db/manager/IClientManager.java | 6 +-
.../{dao/room => manager}/IInvitationManager.java | 2 +-
.../{IClientManager.java => ISipManager.java} | 20 +-
.../openmeetings/db/util/ApplicationHelper.java | 8 +-
.../openmeetings/db/util/ws/RoomMessage.java | 2 +-
.../installation/ImportInitvalues.java | 4 +-
.../src/site/markdown/AsteriskIntegration.md | 9 +-
.../src/site/markdown/InstallMediaServer.md | 2 +-
openmeetings-server/src/site/site.xml | 2 +-
.../src/site/xdoc/PrivacyStatement.xml | 12 +-
.../src/site/xdoc/voip-sip-integration.xml | 360 ---------------------
.../service/notifier/MailNotifier.java | 2 +-
.../service/room/InvitationManager.java | 2 +-
.../{quartz => }/scheduler/AbstractJob.java | 2 +-
.../service/{quartz => }/scheduler/AtomReader.java | 2 +-
.../service/{quartz => }/scheduler/CleanupJob.java | 25 +-
.../{quartz => }/scheduler/ReminderJob.java | 2 +-
.../web/admin/connection/ConnectionsPanel.java | 12 +-
.../openmeetings/web/admin/rooms/RoomForm.java | 3 +-
.../apache/openmeetings/web/app/Application.java | 10 +
.../apache/openmeetings/web/app/ClientManager.java | 86 ++---
.../apache/openmeetings/web/app/TimerService.java | 61 +++-
.../apache/openmeetings/web/app/UserManager.java | 6 +-
.../apache/openmeetings/web/room/RoomPanel.java | 51 ++-
.../web/room/menu/SipDialerDialog.java | 4 +-
.../web/room/wb/WbWebSocketHelper.java | 3 +-
.../openmeetings/web/user/MessageDialog.java | 2 +-
.../openmeetings/web/user/rooms/RoomListPanel.java | 4 +-
.../openmeetings/web/user/rooms/RoomsPanel.java | 3 +-
.../webapp/WEB-INF/classes/applicationContext.xml | 51 +--
.../webapp/WEB-INF/classes/openmeetings.properties | 65 ++++
.../openmeetings/service/quartz/TestJob.java | 4 +-
.../openmeetings/webservice/RoomWebService.java | 12 +-
pom.xml | 37 ++-
45 files changed, 433 insertions(+), 843 deletions(-)
diff --git a/openmeetings-core/pom.xml b/openmeetings-core/pom.xml
index dd82ded..936ee4c 100644
--- a/openmeetings-core/pom.xml
+++ b/openmeetings-core/pom.xml
@@ -105,6 +105,14 @@
<groupId>org.kurento</groupId>
<artifactId>kurento-client</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.asteriskjava</groupId>
+ <artifactId>asterisk-java</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.sip</groupId>
+ <artifactId>jain-sip-ri</artifactId>
+ </dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
index 0aa2934..5f1214e 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/KurentoHandler.java
@@ -71,10 +71,13 @@ import org.kurento.jsonrpc.client.JsonRpcClientNettyWebSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
import com.github.openjson.JSONArray;
import com.github.openjson.JSONObject;
+@Component
public class KurentoHandler {
private static final Logger log = LoggerFactory.getLogger(KurentoHandler.class);
public static final String PARAM_ICE = "iceServers";
@@ -88,20 +91,30 @@ public class KurentoHandler {
private final ScheduledExecutorService kmsRecheckScheduler = Executors.newScheduledThreadPool(1);
public static final String KURENTO_TYPE = "kurento";
private static int FLOWOUT_TIMEOUT_SEC = 5;
- private long checkTimeout = 120000; //ms
- private long objCheckTimeout = 200; //ms
- private int watchThreadCount = 10;
+ @Value("${kurento.ws.url}")
private String kurentoWsUrl;
+ @Value("${kurento.turn.url}")
private String turnUrl;
+ @Value("${kurento.turn.user}")
private String turnUser;
+ @Value("${kurento.turn.secret}")
private String turnSecret;
+ @Value("${kurento.turn.mode}")
private String turnMode;
+ @Value("${kurento.turn.ttl}")
private int turnTtl = 60; //minutes
+ @Value("${kurento.check.timeout}")
+ private long checkTimeout = 120000; //ms
+ @Value("${kurento.object.check.timeout}")
+ private long objCheckTimeout = 200; //ms
+ @Value("${kurento.watch.thread.count}")
+ private int watchThreadCount = 10;
+ @Value("${kurento.kuid}")
+ private String kuid;
private KurentoClient client;
private final AtomicBoolean connected = new AtomicBoolean(false);
- private String kuid;
- private final Set<String> ignoredKuids = new HashSet<>();
private final Map<Long, KRoom> rooms = new ConcurrentHashMap<>();
+ private final Set<String> ignoredKuids = new HashSet<>();
private Runnable check;
@Autowired
@@ -379,56 +392,6 @@ public class KurentoHandler {
return kuid;
}
- public void setKuid(String kuid) {
- this.kuid = kuid;
- }
-
- public void setIgnoredKuids(String ignoredKuids) {
- if (!Strings.isEmpty(ignoredKuids)) {
- this.ignoredKuids.addAll(List.of(ignoredKuids.split("[, ]")));
- }
- }
-
- public void setCheckTimeout(long checkTimeout) {
- this.checkTimeout = checkTimeout;
- }
-
- public void setObjCheckTimeout(long objCheckTimeout) {
- this.objCheckTimeout = objCheckTimeout;
- }
-
- public void setWatchThreadCount(int watchThreadCount) {
- this.watchThreadCount = watchThreadCount;
- }
-
- public void setKurentoWsUrl(String kurentoWsUrl) {
- this.kurentoWsUrl = kurentoWsUrl;
- }
-
- public void setTurnUrl(String turnUrl) {
- this.turnUrl = turnUrl;
- }
-
- public void setTurnUser(String turnUser) {
- this.turnUser = turnUser;
- }
-
- public void setTurnSecret(String turnSecret) {
- this.turnSecret = turnSecret;
- }
-
- public void setTurnMode(String turnMode) {
- this.turnMode = turnMode;
- }
-
- public void setTurnTtl(int turnTtl) {
- this.turnTtl = turnTtl;
- }
-
- public void setFlowoutTimeout(int timeout) {
- FLOWOUT_TIMEOUT_SEC = timeout;
- }
-
IApplication getApp() {
return app;
}
@@ -445,6 +408,18 @@ public class KurentoHandler {
return FLOWOUT_TIMEOUT_SEC;
}
+ @Value("${kurento.flowout.timeout}")
+ private void setFlowoutTimeout(int timeout) {
+ FLOWOUT_TIMEOUT_SEC = timeout;
+ }
+
+ @Value("${kurento.ignored.kuids}")
+ private void setIgnoredKuids(String ignoredKuids) {
+ if (!Strings.isEmpty(ignoredKuids)) {
+ this.ignoredKuids.addAll(List.of(ignoredKuids.split("[, ]")));
+ }
+ }
+
private class KWatchDogCreate implements EventListener<ObjectCreatedEvent> {
private ScheduledExecutorService scheduler;
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java
index 7abacce..27fbe41 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/StreamProcessor.java
@@ -306,10 +306,12 @@ public class StreamProcessor implements IStreamProcessor {
}
KRoom room = kHandler.getRoom(roomId);
if (room.isSharing()) {
- List<StreamDesc> streams = cm.listByRoom(roomId).parallelStream()
+ if (cm.streamByRoom(roomId)
.flatMap(c -> c.getStreams().stream())
- .filter(sd -> StreamType.SCREEN == sd.getType()).collect(Collectors.toList());
- if (streams.isEmpty()) {
+ .filter(sd -> StreamType.SCREEN == sd.getType())
+ .findAny()
+ .isEmpty())
+ {
log.info("No more screen streams in the room, stopping sharing");
room.stopSharing();
if (Room.Type.INTERVIEW != room.getType() && room.isRecording()) {
@@ -319,10 +321,11 @@ public class StreamProcessor implements IStreamProcessor {
}
}
if (room.isRecording()) {
- List<StreamDesc> streams = cm.listByRoom(roomId).parallelStream()
+ if (cm.streamByRoom(roomId)
.flatMap(c -> c.getStreams().stream())
- .collect(Collectors.toList());
- if (streams.isEmpty()) {
+ .findAny()
+ .isEmpty())
+ {
log.info("No more streams in the room, stopping recording");
room.stopRecording(null);
}
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipDao.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipManager.java
similarity index 84%
rename from openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipDao.java
rename to openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipManager.java
index 5f8b2f5..5ffa17a 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipDao.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/sip/SipManager.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.openmeetings.db.dao.room;
+package org.apache.openmeetings.core.sip;
import static javax.sip.message.Request.INVITE;
import static javax.sip.message.Request.REGISTER;
@@ -24,6 +24,8 @@ import static javax.sip.message.Response.OK;
import static javax.sip.message.Response.RINGING;
import static javax.sip.message.Response.TRYING;
import static javax.sip.message.Response.UNAUTHORIZED;
+import static org.apache.openmeetings.util.OmFileHelper.SIP_USER_ID;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.isSipEnabled;
import java.text.ParseException;
import java.util.List;
@@ -31,6 +33,7 @@ import java.util.Properties;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
+import java.util.function.Function;
import javax.annotation.PostConstruct;
import javax.sip.ClientTransaction;
@@ -54,6 +57,9 @@ import javax.sip.message.Request;
import javax.sip.message.Response;
import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.db.manager.ISipManager;
+import org.apache.openmeetings.util.OmFileHelper;
import org.asteriskjava.manager.DefaultManagerConnection;
import org.asteriskjava.manager.ManagerConnection;
import org.asteriskjava.manager.ManagerConnectionFactory;
@@ -70,7 +76,7 @@ import org.asteriskjava.manager.response.ManagerError;
import org.asteriskjava.manager.response.ManagerResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import gov.nist.javax.sip.DialogTimeoutEvent;
@@ -82,8 +88,8 @@ import gov.nist.javax.sip.clientauthutils.UserCredentials;
import gov.nist.javax.sip.stack.NioMessageProcessorFactory;
@Service
-public class SipDao implements SipListenerExt {
- private static final Logger log = LoggerFactory.getLogger(SipDao.class);
+public class SipManager implements ISipManager, SipListenerExt {
+ private static final Logger log = LoggerFactory.getLogger(SipManager.class);
public static final String ASTERISK_OM_FAMILY = "openmeetings";
public static final String ASTERISK_OM_KEY = "rooms";
public static final String SIP_FIRST_NAME = "SIP Transport";
@@ -93,6 +99,28 @@ public class SipDao implements SipListenerExt {
return t -> {};
}
+ @Value("${sip.hostname}")
+ private String sipHostname;
+ @Value("${sip.manager.port}")
+ private int managerPort;
+ @Value("${sip.manager.user}")
+ private String managerUser;
+ @Value("${sip.manager.password}")
+ private String managerPass;
+ @Value("${sip.manager.timeout}")
+ private long managerTimeout;
+
+ @Value("${sip.ws.local.port}")
+ private int localWsPort = 6666;
+ @Value("${sip.ws.local.host}")
+ private String localWsHost;
+ @Value("${sip.ws.remote.port}")
+ private int wsPort;
+ @Value("${sip.ws.remote.user}")
+ private String omSipUser;
+ @Value("${sip.ws.remote.password}")
+ private String omSipPasswd;
+
private final AtomicLong cseq = new AtomicLong();
private final Random rnd = new Random();
@@ -106,18 +134,16 @@ public class SipDao implements SipListenerExt {
private AddressFactory addressFactory;
private ContactHeader contactHeader;
private ManagerConnectionFactory factory;
-
- @Autowired
- private SipConfig config;
+ private String sipUserPicture;
@PostConstruct
public void init() throws Exception {
- if (config.getSipHostname() != null) {
+ if (sipHostname != null) {
factory = new ManagerConnectionFactory(
- config.getSipHostname()
- , config.getManagerPort()
- , config.getManagerUser()
- , config.getManagerPass());
+ sipHostname
+ , managerPort
+ , managerUser
+ , managerPass);
final SipFactory sipFactory = SipFactory.getInstance();
sipFactory.setPathName("gov.nist");
@@ -134,14 +160,14 @@ public class SipDao implements SipListenerExt {
headerFactory = sipFactory.createHeaderFactory();
addressFactory = sipFactory.createAddressFactory();
final ListeningPoint listeningPoint = sipStack.createListeningPoint(
- config.getLocalWsHost()
- , config.getLocalWsPort()
+ localWsHost
+ , localWsPort
, SIP_TRANSPORT);
sipProvider = sipStack.createSipProvider(listeningPoint);
sipProvider.addSipListener(this);
- Address contact = createAddr(config.getOmSipUser(), config.getLocalWsHost(), uri -> {
+ Address contact = createAddr(omSipUser, localWsHost, uri -> {
try {
- uri.setPort(config.getLocalWsPort());
+ uri.setPort(localWsPort);
uri.setTransportParam(SIP_TRANSPORT);
} catch (ParseException e) {
log.error("fail to create contact address", e);
@@ -153,10 +179,10 @@ public class SipDao implements SipListenerExt {
private ManagerConnection getConnection() {
DefaultManagerConnection con = (DefaultManagerConnection)factory.createManagerConnection();
- con.setDefaultEventTimeout(config.getManagerTimeout());
- con.setDefaultResponseTimeout(config.getManagerTimeout());
- con.setSocketReadTimeout((int)config.getManagerTimeout());
- con.setSocketTimeout((int)config.getManagerTimeout());
+ con.setDefaultEventTimeout(managerTimeout);
+ con.setDefaultResponseTimeout(managerTimeout);
+ con.setSocketReadTimeout((int)managerTimeout);
+ con.setSocketTimeout((int)managerTimeout);
return con;
}
@@ -228,6 +254,7 @@ public class SipDao implements SipListenerExt {
return pin;
}
+ @Override
public void update(String confno, String pin) {
delete(confno);
DbPutAction da = new DbPutAction(ASTERISK_OM_FAMILY, getKey(confno), pin);
@@ -239,6 +266,7 @@ public class SipDao implements SipListenerExt {
exec(da);
}
+ @Override
public void delete(String confno) {
DbDelAction da = new DbDelAction(ASTERISK_OM_FAMILY, getKey(confno));
exec(da);
@@ -251,7 +279,7 @@ public class SipDao implements SipListenerExt {
ConfbridgeListAction da = new ConfbridgeListAction(confno);
ResponseEvents r = execEvent(da);
if (r != null) {
- log.debug("SipDao::countUsers size == {}", r.getEvents().size());
+ log.debug("SipManager::countUsers size == {}", r.getEvents().size());
// "- 1" here means: ListComplete event
return r.getEvents().size() - 1;
}
@@ -278,11 +306,29 @@ public class SipDao implements SipListenerExt {
oa.setContext("rooms-out");
oa.setExten(number);
oa.setPriority(1);
- oa.setTimeout(config.getManagerTimeout());
+ oa.setTimeout(managerTimeout);
exec(oa);
}
+ public void setUserPicture(Function<User, String> pictureCreator) {
+ User u = new User();
+ u.setId(SIP_USER_ID);
+ sipUserPicture = pictureCreator.apply(u);
+ }
+
+ public User getSipUser(Room r) {
+ if (factory == null || !isSipEnabled() || !r.isSipEnabled()) {
+ return null;
+ }
+ User u = new User();
+ u.setId(OmFileHelper.SIP_USER_ID);
+ u.setFirstname(SIP_FIRST_NAME);
+ u.setLogin(SIP_USER_NAME);
+ u.setPictureUri(sipUserPicture);
+ return u;
+ }
+
@Override
public void processDialogTerminated(DialogTerminatedEvent evt) {
log.error("processDialogTerminated: \n{}", evt);
@@ -355,7 +401,7 @@ public class SipDao implements SipListenerExt {
}
private Address createAddr(String user) {
- return createAddr(user, config.getSipHostname(), noop());
+ return createAddr(user, sipHostname, noop());
}
private Address createAddr(String user, String host, Consumer<SipUri> cons) {
@@ -373,11 +419,11 @@ public class SipDao implements SipListenerExt {
private void sendRequest(String method, String to, Consumer<SipUri> uriCons, Consumer<Request> reqCons) throws Exception {
SipUri uri = new SipUri();
- uri.setHost(config.getSipHostname());
- uri.setPort(config.getWsPort());
+ uri.setHost(sipHostname);
+ uri.setPort(wsPort);
uri.setTransportParam(SIP_TRANSPORT);
uri.setMethodParam("GET");
- uri.setHeader("Host", config.getSipHostname());
+ uri.setHeader("Host", sipHostname);
uri.setHeader("Location", "/ws");
uriCons.accept(uri);
@@ -386,9 +432,9 @@ public class SipDao implements SipListenerExt {
, method
, sipProvider.getNewCallId()
, headerFactory.createCSeqHeader(cseq.incrementAndGet(), method)
- , headerFactory.createFromHeader(createAddr(config.getOmSipUser()), tag)
+ , headerFactory.createFromHeader(createAddr(omSipUser), tag)
, headerFactory.createToHeader(createAddr(to), null)
- , List.of(headerFactory.createViaHeader(config.getLocalWsHost(), config.getLocalWsPort(), SIP_TRANSPORT, branch))
+ , List.of(headerFactory.createViaHeader(localWsHost, localWsPort, SIP_TRANSPORT, branch))
, headerFactory.createMaxForwardsHeader(70));
request.addHeader(contactHeader);
request.addHeader(headerFactory.createExpiresHeader(600));
@@ -407,12 +453,12 @@ public class SipDao implements SipListenerExt {
AuthenticationHelper helper = sipStack.getAuthenticationHelper((trans, s) -> new UserCredentials() {
@Override
public String getUserName() {
- return config.getOmSipUser();
+ return omSipUser;
}
@Override
public String getPassword() {
- return config.getOmSipPasswd();
+ return omSipPasswd;
}
@Override
@@ -435,7 +481,7 @@ public class SipDao implements SipListenerExt {
private void register() throws Exception {
sendRequest(
REGISTER
- , config.getOmSipUser()
+ , omSipUser
, noop()
, req -> {
try {
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/ChatWebSocketHelper.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/ChatWebSocketHelper.java
index 61d480f..9f733f2 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/ChatWebSocketHelper.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/ChatWebSocketHelper.java
@@ -18,6 +18,7 @@
*/
package org.apache.openmeetings.core.util;
+import static org.apache.openmeetings.core.util.WebSocketHelper.alwaysTrue;
import static org.apache.openmeetings.core.util.WebSocketHelper.doSend;
import static org.apache.openmeetings.core.util.WebSocketHelper.publish;
@@ -148,7 +149,7 @@ public class ChatWebSocketHelper {
if (publish) {
publish(new WsMessageChat2All(m, msg));
}
- WebSocketHelper.send(a -> ((IApplication)a).getBean(IClientManager.class).list()
- , (t, c) -> doSend(t, c, msg, (o, cm) -> setDates(o, m, c.getUser(), false), "all"), null);
+ WebSocketHelper.send(a -> ((IApplication)a).getBean(IClientManager.class).stream()
+ , (t, c) -> doSend(t, c, msg, (o, cm) -> setDates(o, m, c.getUser(), false), "all"), alwaysTrue());
}
}
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
index 10a2de7..16c3698 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
@@ -21,12 +21,12 @@ package org.apache.openmeetings.core.util;
import static org.apache.openmeetings.util.OpenmeetingsVariables.getWicketApplicationName;
import java.io.IOException;
-import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
+import java.util.stream.Stream;
import org.apache.openmeetings.IApplication;
import org.apache.openmeetings.core.util.ws.WsMessageAll;
@@ -54,6 +54,9 @@ import com.github.openjson.JSONObject;
public class WebSocketHelper {
private static final Logger log = LoggerFactory.getLogger(WebSocketHelper.class);
+ public static final <T> Predicate<T> alwaysTrue() {
+ return x -> true;
+ }
private WebSocketHelper() {
// denied
@@ -139,7 +142,7 @@ public class WebSocketHelper {
publish(new WsMessageRoomMsg(m));
}
log.trace("Sending WebSocket message to room: {} {}", m.getType(), m instanceof TextRoomMessage ? ((TextRoomMessage)m).getText() : "");
- sendRoom(m.getRoomId(), (t, c) -> t.sendMessage(m), null);
+ sendRoom(m.getRoomId(), (t, c) -> t.sendMessage(m), alwaysTrue());
}
public static void sendServer(final RoomMessage m) {
@@ -161,7 +164,7 @@ public class WebSocketHelper {
if (publish) {
publish(new WsMessageRoom(roomId, m));
}
- sendRoom(roomId, m, null, null);
+ sendRoom(roomId, m, alwaysTrue(), null);
}
public static void sendRoomOthers(final Long roomId, final String uid, final JSONObject m) {
@@ -183,8 +186,8 @@ public class WebSocketHelper {
if (publish) {
publish(new WsMessageUser(userId, m));
}
- send(a -> ((IApplication)a).getBean(IClientManager.class).listByUser(userId)
- , (t, c) -> doSend(t, c, m, func, "user"), null);
+ send(a -> ((IApplication)a).getBean(IClientManager.class).listByUser(userId).stream()
+ , (t, c) -> doSend(t, c, m, func, "user"), alwaysTrue());
}
public static void sendAll(final String m) {
@@ -239,11 +242,11 @@ public class WebSocketHelper {
}
private static void sendRoom(final Long roomId, BiConsumer<IWebSocketConnection, Client> consumer, Predicate<Client> check) {
- send(a -> ((IApplication)a).getBean(IClientManager.class).listByRoom(roomId), consumer, check);
+ send(a -> ((IApplication)a).getBean(IClientManager.class).streamByRoom(roomId), consumer, check);
}
static void send(
- final Function<Application, Collection<Client>> func
+ final Function<Application, Stream<Client>> func
, BiConsumer<IWebSocketConnection, Client> consumer
, Predicate<Client> check)
{
@@ -255,14 +258,14 @@ public class WebSocketHelper {
WebSocketSettings settings = WebSocketSettings.Holder.get(app);
IWebSocketConnectionRegistry reg = settings.getConnectionRegistry();
Executor executor = settings.getWebSocketPushMessageExecutor();
- for (Client c : func.apply(app)) {
- if (check == null || check.test(c)) {
- final IWebSocketConnection wc = reg.getConnection(app, c.getSessionId(), new PageIdKey(c.getPageId()));
- if (wc != null && wc.isOpen()) {
- executor.run(() -> consumer.accept(wc, c));
- }
- }
- }
+ func.apply(app)
+ .filter(check)
+ .forEach(c -> {
+ final IWebSocketConnection wc = reg.getConnection(app, c.getSessionId(), new PageIdKey(c.getPageId()));
+ if (wc != null && wc.isOpen()) {
+ executor.run(() -> consumer.accept(wc, c));
+ }
+ });
}).start();
}
}
diff --git a/openmeetings-db/pom.xml b/openmeetings-db/pom.xml
index cd6d82a..16562ac 100644
--- a/openmeetings-db/pom.xml
+++ b/openmeetings-db/pom.xml
@@ -73,11 +73,6 @@
<version>${spring.version}</version>
</dependency>
<dependency>
- <groupId>org.asteriskjava</groupId>
- <artifactId>asterisk-java</artifactId>
- <version>${asterisk-java.version}</version>
- </dependency>
- <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${commons-dbcp.version}</version>
@@ -109,10 +104,6 @@
<version>${mssql.version}</version>
</dependency>
<dependency>
- <groupId>javax.sip</groupId>
- <artifactId>jain-sip-ri</artifactId>
- </dependency>
- <dependency>
<groupId>org.apache.openmeetings</groupId>
<artifactId>openmeetings-util</artifactId>
<version>${project.version}</version>
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
index 988bc2e..d5b52f8 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/calendar/AppointmentDao.java
@@ -37,13 +37,13 @@ import javax.persistence.TypedQuery;
import org.apache.commons.lang3.StringUtils;
import org.apache.openmeetings.db.dao.IDataProviderDao;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
-import org.apache.openmeetings.db.dao.room.IInvitationManager;
import org.apache.openmeetings.db.dao.room.RoomDao;
import org.apache.openmeetings.db.dto.calendar.AppointmentDTO;
import org.apache.openmeetings.db.entity.calendar.Appointment;
import org.apache.openmeetings.db.entity.calendar.Appointment.Reminder;
import org.apache.openmeetings.db.entity.calendar.MeetingMember;
import org.apache.openmeetings.db.entity.room.Invitation.MessageType;
+import org.apache.openmeetings.db.manager.IInvitationManager;
import org.apache.openmeetings.db.entity.room.Room;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java
index 02b84f5..696959b 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/RoomDao.java
@@ -46,6 +46,7 @@ import org.apache.openmeetings.db.entity.log.ConferenceLog;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.room.Room.RoomElement;
import org.apache.openmeetings.db.entity.room.Room.Type;
+import org.apache.openmeetings.db.manager.ISipManager;
import org.apache.openmeetings.db.entity.room.RoomFile;
import org.apache.openmeetings.db.entity.room.RoomGroup;
import org.apache.openmeetings.db.util.DaoHelper;
@@ -70,7 +71,7 @@ public class RoomDao implements IGroupAdminDataProviderDao<Room> {
@Autowired
private ConfigurationDao cfgDao;
@Autowired
- private SipDao sipDao;
+ private ISipManager sipManager;
@Autowired
private UserDao userDao;
@@ -213,9 +214,9 @@ public class RoomDao implements IGroupAdminDataProviderDao<Room> {
if (sipNumber != null && !sipNumber.equals(entity.getConfno())) {
entity.setConfno(sipNumber);
}
- sipDao.update(sipNumber, entity.getPin());
+ sipManager.update(sipNumber, entity.getPin());
} else {
- sipDao.delete(entity.getConfno());
+ sipManager.delete(entity.getConfno());
entity.setConfno(null);
entity.setPin(null);
}
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipConfig.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipConfig.java
deleted file mode 100644
index e1a5646..0000000
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/SipConfig.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License") + you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.openmeetings.db.dao.room;
-
-public class SipConfig {
- private String sipHostname;
- private int managerPort;
- private String managerUser;
- private String managerPass;
- private long managerTimeout;
-
- private int localWsPort = 6666;
- private String localWsHost;
- private int wsPort;
- private String omSipUser;
- private String omSipPasswd;
-
- private String uid; //FIXME TODO is this still required ?!
-
- public String getSipHostname() {
- return sipHostname;
- }
-
- public void setSipHostname(String sipHostname) {
- this.sipHostname = sipHostname;
- }
-
- public int getManagerPort() {
- return managerPort;
- }
-
- public void setManagerPort(int managerPort) {
- this.managerPort = managerPort;
- }
-
- public String getManagerUser() {
- return managerUser;
- }
-
- public void setManagerUser(String managerUser) {
- this.managerUser = managerUser;
- }
-
- public String getManagerPass() {
- return managerPass;
- }
-
- public void setManagerPass(String managerPass) {
- this.managerPass = managerPass;
- }
-
- public long getManagerTimeout() {
- return managerTimeout;
- }
-
- public void setManagerTimeout(long managerTimeout) {
- this.managerTimeout = managerTimeout;
- }
-
- public int getLocalWsPort() {
- return localWsPort;
- }
-
- public void setLocalWsPort(int localWsPort) {
- this.localWsPort = localWsPort;
- }
-
- public String getLocalWsHost() {
- return localWsHost;
- }
-
- public void setLocalWsHost(String localWsHost) {
- this.localWsHost = localWsHost;
- }
-
- public int getWsPort() {
- return wsPort;
- }
-
- public void setWsPort(int wsPort) {
- this.wsPort = wsPort;
- }
-
- public String getOmSipUser() {
- return omSipUser;
- }
-
- public void setOmSipUser(String omSipUser) {
- this.omSipUser = omSipUser;
- }
-
- public String getOmSipPasswd() {
- return omSipPasswd;
- }
-
- public void setOmSipPasswd(String omSipPasswd) {
- this.omSipPasswd = omSipPasswd;
- }
-
- public String getUid() {
- return uid;
- }
-
- public void setUid(String uid) {
- this.uid = uid;
- }
-}
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
index cdf463b..0304452 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
@@ -19,6 +19,7 @@
package org.apache.openmeetings.db.entity.basic;
import static java.util.UUID.randomUUID;
+import static org.apache.openmeetings.util.OmFileHelper.SIP_USER_ID;
import java.io.Serializable;
import java.util.ArrayList;
@@ -129,6 +130,10 @@ public class Client implements IDataProviderEntity, IWsClient {
return sid;
}
+ public boolean isSip() {
+ return SIP_USER_ID.equals(getUserId());
+ }
+
public void clear() {
activities.clear();
rights.clear();
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IClientManager.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IClientManager.java
index 24a1498..0e894da 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IClientManager.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IClientManager.java
@@ -19,7 +19,7 @@
package org.apache.openmeetings.db.manager;
import java.util.Collection;
-import java.util.List;
+import java.util.stream.Stream;
import org.apache.openmeetings.db.entity.basic.Client;
@@ -27,8 +27,8 @@ public interface IClientManager {
Client get(String uid);
Client getBySid(String sid);
String uidBySid(String sid);
- List<Client> list();
- List<Client> listByRoom(Long roomId);
+ Stream<Client> stream();
+ Stream<Client> streamByRoom(Long roomId);
Collection<Client> listByUser(Long userId);
Client update(Client c);
void exit(Client c);
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/IInvitationManager.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IInvitationManager.java
similarity index 97%
rename from openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/IInvitationManager.java
rename to openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IInvitationManager.java
index 2fd0c34..44f3f65 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/room/IInvitationManager.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IInvitationManager.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.openmeetings.db.dao.room;
+package org.apache.openmeetings.db.manager;
import java.util.Date;
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IClientManager.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/ISipManager.java
similarity index 69%
copy from openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IClientManager.java
copy to openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/ISipManager.java
index 24a1498..b94263a 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/IClientManager.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/manager/ISipManager.java
@@ -18,18 +18,12 @@
*/
package org.apache.openmeetings.db.manager;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.openmeetings.db.entity.basic.Client;
+/**
+ * this interface is required to use SipMagager from openmeetings-core
+ */
+public interface ISipManager {
+ public static final String SIP_FIRST_NAME = "SIP Transport";
-public interface IClientManager {
- Client get(String uid);
- Client getBySid(String sid);
- String uidBySid(String sid);
- List<Client> list();
- List<Client> listByRoom(Long roomId);
- Collection<Client> listByUser(Long userId);
- Client update(Client c);
- void exit(Client c);
+ void update(String confno, String pin);
+ void delete(String confno);
}
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java
index 38ef520..b8d7919 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ApplicationHelper.java
@@ -116,13 +116,17 @@ public class ApplicationHelper {
}
}
- public static IApplication ensureApplication(Long langId) {
- IApplication a = ensureApplication();
+ public static void ensureRequestCycle(IApplication a) {
if (ThreadContext.getRequestCycle() == null) {
ServletWebRequest req = new ServletWebRequest(new MockHttpServletRequest((Application)a, new MockHttpSession(a.getServletContext()), a.getServletContext()), "");
RequestCycleContext rctx = new RequestCycleContext(req, new MockWebResponse(), a.getRootRequestMapper(), a.getExceptionMapperProvider().get());
ThreadContext.setRequestCycle(new RequestCycle(rctx));
}
+ }
+
+ public static IApplication ensureApplication(Long langId) {
+ IApplication a = ensureApplication();
+ ensureRequestCycle(a);
if (ThreadContext.getSession() == null) {
WebSession s = WebSession.get();
if (langId > 0) {
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ws/RoomMessage.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ws/RoomMessage.java
index 85937b7..9864bc2 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ws/RoomMessage.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/ws/RoomMessage.java
@@ -19,7 +19,7 @@
package org.apache.openmeetings.db.util.ws;
import static java.util.UUID.randomUUID;
-import static org.apache.openmeetings.db.dao.room.SipDao.SIP_FIRST_NAME;
+import static org.apache.openmeetings.db.manager.ISipManager.SIP_FIRST_NAME;
import static org.apache.openmeetings.util.OmFileHelper.SIP_USER_ID;
import java.util.Date;
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
index 718078e..f987e1d 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
@@ -125,10 +125,10 @@ import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
+import org.apache.openmeetings.core.sip.SipManager;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.label.LabelDao;
import org.apache.openmeetings.db.dao.room.RoomDao;
-import org.apache.openmeetings.db.dao.room.SipDao;
import org.apache.openmeetings.db.dao.server.OAuth2Dao;
import org.apache.openmeetings.db.dao.user.GroupDao;
import org.apache.openmeetings.db.dao.user.UserDao;
@@ -170,7 +170,7 @@ public class ImportInitvalues {
@Autowired
private UserDao userDao;
@Autowired
- private SipDao sipDao;
+ private SipManager sipDao;
@Autowired
private OAuth2Dao oauthDao;
@Autowired
diff --git a/openmeetings-server/src/site/markdown/AsteriskIntegration.md b/openmeetings-server/src/site/markdown/AsteriskIntegration.md
index 2fd9105..554584f 100644
--- a/openmeetings-server/src/site/markdown/AsteriskIntegration.md
+++ b/openmeetings-server/src/site/markdown/AsteriskIntegration.md
@@ -165,7 +165,7 @@ Modify `/etc/asterisk/extensions.conf`
; If you do not receive an output with that resembles openmeetings/rooms/400## where “##” will equal
; the extension assigned when you created your room
; If you do not receive the above output check your parameters in
-; /opt/om/webapps/openmeetings/WEB-INF/classes/applicationContext.xml
+; /opt/om/webapps/openmeetings/WEB-INF/classes/openmeetings.properties
; Go back into the Administrator Panel and remove the PIN number in each room save the record with
; no PIN number and then re-enter the pin again resave the record.
; *****************************************************
@@ -246,12 +246,9 @@ write = all
```
Update OpenMeetings with credentials for Asterisk manager.
-Modify `/opt/om/webapps/openmeetings/WEB-INF/classes/applicationContext.xml`
+Modify `/opt/om/webapps/openmeetings/WEB-INF/classes/openmeetings.properties`
-find **<bean class="org.apache.openmeetings.db.dao.room.SipConfig">**
-uncomment its properties and set it to your custom values.
-
-set value for `uid` property to unique secret value (can be generated here <a href="https://www.uuidtools.com">https://www.uuidtools.com</a>)
+find all properties start with `sip.` and set it to your custom values.
<p style="font-size: larger; color: blue;">
IMPORTANT: this step should be done <strong>BEFORE</strong> system install/restore
diff --git a/openmeetings-server/src/site/markdown/InstallMediaServer.md b/openmeetings-server/src/site/markdown/InstallMediaServer.md
index 3034ca7..8ffc72e 100644
--- a/openmeetings-server/src/site/markdown/InstallMediaServer.md
+++ b/openmeetings-server/src/site/markdown/InstallMediaServer.md
@@ -13,4 +13,4 @@ Licensed under the Apache License, Version 2.0 (the "License") http://www.apache
## Specify/Install Turn server
-<div class="bd-callout bd-callout-info">Optional step</div>
+<div class="bd-callout bd-callout-warning">Only local installation will work without TURN server</div>
diff --git a/openmeetings-server/src/site/site.xml b/openmeetings-server/src/site/site.xml
index ef599b9..5a27a60 100644
--- a/openmeetings-server/src/site/site.xml
+++ b/openmeetings-server/src/site/site.xml
@@ -47,7 +47,7 @@
<item name="REST API Sample" href="/RestAPISample.html" />
<item name="Ldap and ADS" href="/LdapAndADS.html" />
<item name="OAuth2" href="/oauth2.html" />
- <item name="VoIP and SIP" href="/voip-sip-integration.html" />
+ <item name="VoIP and SIP" href="/AsteriskIntegration.html" />
<item name="Errors table" href="/errorvalues.html" />
<item name="CalDAV and Google Calendar integration" href="/CalDAVandGCal.html" />
<item name="External Video/Camera" href="/ExternalVideo.html" />
diff --git a/openmeetings-server/src/site/xdoc/PrivacyStatement.xml b/openmeetings-server/src/site/xdoc/PrivacyStatement.xml
index ad91620..319f18b 100644
--- a/openmeetings-server/src/site/xdoc/PrivacyStatement.xml
+++ b/openmeetings-server/src/site/xdoc/PrivacyStatement.xml
@@ -24,7 +24,7 @@
<div>
To modify privacy statement do the following:
<ul>
- <li>Open <pp>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage.html</pp></li>
+ <li>Open <tt>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage.html</tt></li>
<li>Perform necessary changes</li>
<li>restart OM</li>
</ul>
@@ -35,11 +35,11 @@
To create privacy statement in your language do the following:
<ul>
<li>
- Create new file <pp>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage_<b>LANG_CODE</b>.html</pp> <br/>
- <pp>LANG_CODE</pp> should be in format [language code]_[country ISO code], <pp>_[country ISO code]</pp> block is optional<br/>
- for ex. <pp>de</pp> can be suffix for German, file name will be <pp>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage_de.html</pp><br/>
- <pp>pt</pp> can be suffix for Portuguese, file name will be <pp>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage_pt.html</pp><br/>
- <pp>pt_BR</pp> can be suffix for Brazilian version of Portuguese, file name will be <pp>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage_pt_BR.html</pp><br/>
+ Create new file <tt>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage_<b>LANG_CODE</b>.html</tt> <br/>
+ <tt>LANG_CODE</tt> should be in format [language code]_[country ISO code], <tt>_[country ISO code]</tt> block is optional<br/>
+ for ex. <tt>de</tt> can be suffix for German, file name will be <tt>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage_de.html</tt><br/>
+ <tt>pt</tt> can be suffix for Portuguese, file name will be <tt>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage_pt.html</tt><br/>
+ <tt>pt_BR</tt> can be suffix for Brazilian version of Portuguese, file name will be <tt>webapps/openmeetings/WEB-INF/classes/org/apache/openmeetings/web/pages/PrivacyPage_pt_BR.html</tt><br/>
</li>
<li>Perform translation</li>
<li>restart OM</li>
diff --git a/openmeetings-server/src/site/xdoc/voip-sip-integration.xml b/openmeetings-server/src/site/xdoc/voip-sip-integration.xml
deleted file mode 100644
index 85bef4b..0000000
--- a/openmeetings-server/src/site/xdoc/voip-sip-integration.xml
+++ /dev/null
@@ -1,360 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Licensed 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.
- -->
-<document xmlns="http://maven.apache.org/XDOC/2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
- <properties>
- <title>VoIP and SIP Integration</title>
- <author email="dev@openmeetings.apache.org">Apache OpenMeetings Team</author>
- </properties>
- <body>
- <section name="Not implemented">
- <div class="bd-callout bd-callout-danger">
- Please NOTE: this functionality is not yet implemented in 5.0.x
- </div>
- </section>
-
- <section name="VoIP and SIP Integration">
- <p>
- There are multiple ways to integrate with VoIP and or SIP.
- OpenMeetings does not provide out of the box a ready to run VoIP
- integration / integration to cell phone or usual land lane.
- The
- nature of such integrations is that it depends heavily on the
- infrastructure that you are using and where you would like to
- integrate OpenMeetings into.
- <br />
- <br />
- It also depends on a number of factors of which OpenMeetings is
- impossible to set up for you, for example setting up your VoIP
- server or provide you with a range of telephone numbers reserved for
- conference calls in your national phone network.
- Such an integration
- project is likely to become a consulting job for a
- telecommunications consultant.
- <br />
- <br />
- To get help on the integration you can contact the
- <a href="mailing-lists.html">mailing lists</a>
- or for example somebody from the list of
- <a href="commercial-support.html">commercial support</a>.
- <br/><br/>
- </p>
- </section>
- <section name="SIP-Transport Integration">
- <p>You need Apache OpenMeetings <strong>version 4.0+</strong> to apply this guide!</p>
- <p>You need Asterisk <strong>version 13+</strong> to apply this guide!</p>
- <p>Here is instruction how-to set up red5sip transport integration with OpenMeetings on Ubuntu 16.04.</p>
- </section>
- <section name="Prerequisites">
- <div>
- Run the commands
- <source>
-<![CDATA[
-sudo apt update && sudo apt upgrade
-]]>
- </source>
- </div>
- </section>
- <section name="Building and setting up Asterisk">
- <div>
- Run the commands
- <source>
-<![CDATA[
-sudo mkdir /usr/src/asterisk && cd /usr/src/asterisk
-sudo wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-13.17.0.tar.gz
-sudo tar -xvzf asterisk-13.17.0.tar.gz
-cd ./asterisk-13.17.0
-sudo make clean
-sudo contrib/scripts/install_prereq install
-sudo ./configure
-sudo make menuconfig
-]]>
- </source>
- Make sure you have selected <tt>Add-ons -> res_config_mysql</tt>, Press F12 to save
- <source>
-<![CDATA[
-sudo make
-sudo make install
-sudo make samples
-sudo make config
-sudo service asterisk start
-]]>
- </source>
- </div>
- </section>
- <section name="Configure Asterisk">
- <div>
- Enable asterisk MySQL module:<br /><br />
- Modify "[modules]" section of <tt>/etc/asterisk/modules.conf</tt> as follows:<br />
- <strong>Add/uncomment the following lines</strong>
- <source>
-<![CDATA[
-preload => res_config_mysql.so
-]]>
- </source>
- </div><br />
- <div>
- Configure MySQL module:<br /><br />
- Set valid data for MySQL in <tt>/etc/asterisk/res_config_mysql.conf</tt> :<br />
- <strong>Example</strong>
- <source>
-<![CDATA[
-[general]
-dbhost = 127.0.0.1
-dbname = openmeetings
-dbuser = root
-dbpass =
-dbport = 3306
-dbsock = /var/lib/mysql/mysql.sock
-dbcharset = utf8
-requirements=warn
-]]>
- </source>
- </div><br />
- <div>
- Modify <tt>/etc/asterisk/sip.conf</tt><br />
- <strong>Add/uncomment the following line</strong>:<br />
- <source>
-<![CDATA[
-videosupport=yes
-rtcachefriends=yes
-]]>
- </source>
- <strong>Increase maxexpiry value to 43200</strong>:<br />
- <source>
-<![CDATA[
-maxexpiry=43200
-]]>
- </source>
- <strong>Add user for the "SIP Transport"</strong>:<br />
- <source>
-<![CDATA[
-[red5sip_user]
-type=friend
-secret=12345
-disallow=all
-allow=ulaw
-allow=h263
-host=dynamic
-nat=force_rport,comedia
-context=rooms-red5sip
-]]>
- </source>
- </div><br />
- <div>
- Add next lines into the <tt>/etc/asterisk/extconfig.conf</tt>:
- <source>
-<![CDATA[
-[settings]
-sippeers => mysql,general,sipusers
-]]>
- </source>
- </div><br />
- <div>
- Modify <tt>/etc/asterisk/extensions.conf</tt><br />
- <strong>Add the following section</strong>:<br />
- <source>
-<![CDATA[
-; *****************************************************
-; The below dial plan is used to dial into a Openmeetings Conference room
-; The first line DB_EXISTS(openmeetings/room/ does not belong to the openmeetings application
-; but is the name of astDB containing the astDB family/key pair and values
-; To Check if your astDB has been created do the following in a terminal window type the following:
-; asterisk –rx “database show”
-; If you do not receive an output with that resembles openmeetings/rooms/400## where “##” will equal
-; the extension assigned when you created your room
-; If you do not receive the above output check your parameters in
-; /opt/om/webapps/openmeetings/WEB-INF/classes/applicationContext.xml
-; Go back into the Administrator Panel and remove the PIN number in each room save the record with
-; no PIN number and then re-enter the pin again resave the record.
-; *****************************************************
-
-[rooms]
-exten => _400X!,1,GotoIf($[${DB_EXISTS(openmeetings/rooms/${EXTEN})}]?ok:notavail)
-exten => _400X!,n(ok),SET(PIN=${DB(openmeetings/rooms/${EXTEN})})
-exten => _400X!,n,Set(CONFBRIDGE(user,template)=sip_user)
-exten => _400X!,n,Set(CONFBRIDGE(user,pin)=${PIN})
-exten => _400X!,n(ok),Confbridge(${EXTEN},default_bridge,)
-exten => _400X!,n,Hangup
-exten => _400X!,n(notavail),Answer()
-exten => _400X!,n,Playback(invalid)
-exten => _400X!,n,Hangup
-
-[rooms-originate]
-exten => _400X!,1,Confbridge(${EXTEN},default_bridge,sip_user)
-exten => _400X!,n,Hangup
-
-[rooms-out]
-; *****************************************************
-; Extensions for outgoing calls from Openmeetings room.
-; *****************************************************
-
-[rooms-red5sip]
-exten => _400X!,1,GotoIf($[${DB_EXISTS(openmeetings/rooms/${EXTEN})}]?ok:notavail)
-exten => _400X!,n(ok),Confbridge(${EXTEN},default_bridge,red5sip_user)
-exten => _400X!,n(notavail),Hangup
-]]>
- </source>
- </div><br />
- <div>
- Modify <tt>/etc/asterisk/confbridge.conf</tt><br />
- <strong>Add/Modify the following secions</strong>:<br />
- <source>
-<![CDATA[
-[general]
-
-[red5sip_user]
-type=user
-marked=yes
-dsp_drop_silence=yes
-denoise=true
-
-[sip_user]
-type=user
-end_marked=yes
-wait_marked=yes
-music_on_hold_when_empty=yes
-dsp_drop_silence=yes
-denoise=true
-
-[default_bridge]
-type=bridge
-video_mode=follow_talker
-]]>
- </source>
- </div><br />
- <div>
- To enable Asterisk Manager API modify <tt>/etc/asterisk/manager.conf</tt><br />
- <strong>Add/Modify the following sections</strong>:<br />
- <source>
-<![CDATA[
-[general]
-enabled = yes
-webenabled = no
-port = 5038
-bindaddr = 127.0.0.1
-
-[openmeetings]
-secret = 12345
-deny=0.0.0.0/0.0.0.0
-permit=127.0.0.1/255.255.255.0
-read = all
-write = all
-]]>
- </source>
- </div><br />
- <div>
- Update OpenMeetings with credentials for Asterisk manager.
- Modify <tt>/opt/om/webapps/openmeetings/WEB-INF/classes/applicationContext.xml</tt><br />
- find <strong><bean id="sipDao" class="org.apache.openmeetings.db.dao.room.SipDao"></strong>
- uncomment its parameters and set it to your custom values.<br/>
- set value for <tt>uid</tt> property to unique secret value (can be generated here <a href="https://www.uuidtools.com">https://www.uuidtools.com</a>)
- and sync it with <tt>settings.properties</tt> of red5sip (see below)
- <p style="font-size: larger; color: blue;">
- IMPORTANT: this step should be done <strong>BEFORE</strong> system install/restore
- otherwise all SIP related room information will be lost
- </p>
- </div><br />
- <div>
- Restart asterisk:
- <source>
-<![CDATA[
-service asterisk restart
-]]>
- </source>
- </div><br />
- </section>
-
- <section name="Setup red5sip transport">
- <ul>
- <li>Download red5sip from <tt>https://github.com/openmeetings/red5sip</tt>
- <source>
-<![CDATA[
-git clone https://github.com/openmeetings/red5sip.git
-]]>
- </source>
- </li>
- <li>Build with Apache Maven
- <source>
-<![CDATA[
-cd red5sip
-mvn clean package
-]]>
- </source>
- </li>
- <li>All necessary files will be available in <tt>target</tt> folder, copy/move it to /opt/red5sip/</li>
- <li>Insert proper values to the <tt>/opt/red5sip/settings.properties</tt>
- <source>
-<![CDATA[
-red5.host=127.0.0.1 # red5 server address
-om.context=openmeetings # Openmeetings context
-red5.codec=asao
-red5.codec.rate=22 # should correlate with mic setting in Admin->Config `flash.mic.rate`
-sip.obproxy=127.0.0.1 # asterisk adderss
-sip.phone=red5sip_user # sip phone number
-sip.authid=red5sip_user # sip auth id
-sip.secret=12345 # sip password
-sip.realm=asterisk # sip realm
-sip.proxy=127.0.0.1 # address of sip proxy
-rooms.forceStart=no # TBD
-uid=87dddad4-9ca5-475b-860f-2e0825d02b76 #can be generated here: https://www.uuidtools.com/
-rooms=1 # TBD (not in use)
-]]>
- </source>
- </li>
- <li>Set correct permissions on red5sip files:
- <source>
-<![CDATA[
-sudo chown -R nobody:nogroup /opt/red5sip
-]]>
- </source>
- </li>
- <li>Add red5sip to autostart:
- <source>
-<![CDATA[
-sudo cp /opt/red5sip/red5sip /etc/init.d/
-sudo chmod a+x /etc/init.d/red5sip
-sudo update-rc.d red5sip defaults
-]]>
- </source>
- </li>
- <li>Start openmeetings
- <source>
-<![CDATA[
-service red5 start
-]]>
- </source>
- </li>
- <li>
- Enable <tt>SIP</tt> in openmeetings: <br/>
- <tt>Administration->Configuration->red5sip.enable == yes</tt>
- </li>
- <li>
- Enable SIP for particular room(s): <br/>
- <tt>Administration->Conference rooms->Room->Enable SIP transport in the room == checked</tt><br/>
- (SIP number will be assigned to room if everything is OK)
- </li>
- <li>Start red5sip
- <source>
-<![CDATA[
-service red5sip start
-]]>
- </source>
- </li>
- </ul>
- </section>
- </body>
-</document>
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java
index 3be75b2..1aa6bed 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/notifier/MailNotifier.java
@@ -26,11 +26,11 @@ import javax.annotation.PostConstruct;
import org.apache.openmeetings.core.notifier.INotifier;
import org.apache.openmeetings.core.notifier.NotifierService;
-import org.apache.openmeetings.db.dao.room.IInvitationManager;
import org.apache.openmeetings.db.entity.calendar.Appointment;
import org.apache.openmeetings.db.entity.room.Invitation;
import org.apache.openmeetings.db.entity.room.Invitation.MessageType;
import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.db.manager.IInvitationManager;
import org.apache.openmeetings.service.mail.template.subject.AppointmentReminderTemplate;
import org.apache.openmeetings.service.mail.template.subject.SubjectEmailTemplate;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
index 34ae0bc..159c6ea 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/room/InvitationManager.java
@@ -28,7 +28,6 @@ import java.util.TimeZone;
import org.apache.openmeetings.IApplication;
import org.apache.openmeetings.core.mail.MailHandler;
-import org.apache.openmeetings.db.dao.room.IInvitationManager;
import org.apache.openmeetings.db.dao.room.InvitationDao;
import org.apache.openmeetings.db.entity.basic.MailMessage;
import org.apache.openmeetings.db.entity.calendar.Appointment;
@@ -40,6 +39,7 @@ import org.apache.openmeetings.db.entity.room.Invitation.Valid;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Type;
+import org.apache.openmeetings.db.manager.IInvitationManager;
import org.apache.openmeetings.service.mail.template.InvitationTemplate;
import org.apache.openmeetings.service.mail.template.subject.CanceledAppointmentTemplate;
import org.apache.openmeetings.service.mail.template.subject.CreatedAppointmentTemplate;
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/AbstractJob.java
similarity index 97%
rename from openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java
rename to openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/AbstractJob.java
index f1b641b..25db755 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/AbstractJob.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.openmeetings.service.quartz.scheduler;
+package org.apache.openmeetings.service.scheduler;
import static org.apache.openmeetings.util.OpenmeetingsVariables.isInitComplete;
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AtomReader.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/AtomReader.java
similarity index 98%
rename from openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AtomReader.java
rename to openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/AtomReader.java
index ca3e46e..580b1ab 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AtomReader.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/AtomReader.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.openmeetings.service.quartz.scheduler;
+package org.apache.openmeetings.service.scheduler;
import static org.apache.openmeetings.core.rss.LoadAtomRssFeed.getFeedConnection;
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/CleanupJob.java
similarity index 90%
rename from openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
rename to openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/CleanupJob.java
index 4ced109..5a8ba8e 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/CleanupJob.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.openmeetings.service.quartz.scheduler;
+package org.apache.openmeetings.service.scheduler;
import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
import static org.apache.openmeetings.util.OmFileHelper.TEST_SETUP_PREFIX;
@@ -33,12 +33,19 @@ import org.apache.openmeetings.db.entity.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+@Component("cleanupJob")
public class CleanupJob extends AbstractJob {
private static Logger log = LoggerFactory.getLogger(CleanupJob.class);
+ @Value("${job.cleanup.session.timeout}")
private long sessionTimeout = 30 * 60 * 1000L;
+ @Value("${job.cleanup.test.setup.timeout}")
private long testSetupTimeout = 60 * 60 * 1000L; // 1 hour
+ @Value("${job.cleanup.reset.hash.ttl}")
private long resetHashTtl = 24 * 60 * 60 * 1000L; // 1 day
+ @Value("${job.cleanup.conf.log.ttl}")
private long confLogTtl = 7 * 24 * 60 * 60 * 1000L; // 7 days
@Autowired
@@ -48,22 +55,6 @@ public class CleanupJob extends AbstractJob {
@Autowired
private ConferenceLogDao confLogDao;
- public void setSessionTimeout(long sessionTimeout) {
- this.sessionTimeout = sessionTimeout;
- }
-
- public void setTestSetupTimeout(long testSetupTimeout) {
- this.testSetupTimeout = testSetupTimeout;
- }
-
- public void setResetHashTtl(long resetHashTtl) {
- this.resetHashTtl = resetHashTtl;
- }
-
- public void setConfLogTtl(long confLogTtl) {
- this.confLogTtl = confLogTtl;
- }
-
public void cleanTestSetup() {
log.trace("CleanupJob.cleanTestSetup");
final long now = System.currentTimeMillis();
diff --git a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java b/openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/ReminderJob.java
similarity index 98%
rename from openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java
rename to openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/ReminderJob.java
index bd1e32a..9fadd6a 100644
--- a/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java
+++ b/openmeetings-service/src/main/java/org/apache/openmeetings/service/scheduler/ReminderJob.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.openmeetings.service.quartz.scheduler;
+package org.apache.openmeetings.service.scheduler;
import static org.apache.openmeetings.core.rss.LoadAtomRssFeed.setRss;
import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_RSS_FEED1;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
index a57b704..f2bad46 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
@@ -24,11 +24,10 @@ import static org.apache.openmeetings.web.common.confirmation.ConfirmationBehavi
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.apache.openmeetings.core.remote.KurentoHandler;
import org.apache.openmeetings.core.remote.StreamProcessor;
@@ -76,14 +75,11 @@ public class ConnectionsPanel extends AdminBasePanel {
private static final long serialVersionUID = 1L;
private List<IDataProviderEntity> getConnections() {
- List<IDataProviderEntity> l = new ArrayList<>();
- l.addAll(cm.list());
- Collection<KStreamDto> streams = streamProcessor.getStreams()
+ return Stream.concat(cm.stream()
+ , streamProcessor.getStreams()
.stream()
.map(KStreamDto::new)
- .collect(Collectors.toList());
- l.addAll(streams);
- return l;
+ ).collect(Collectors.toList());
}
@Override
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
index 128f26f..aa73236 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/rooms/RoomForm.java
@@ -434,8 +434,7 @@ public class RoomForm extends AdminBaseForm<Room> {
void updateClients(AjaxRequestTarget target) {
long roomId = getModelObject().getId() != null ? getModelObject().getId() : 0;
- final List<Client> clientsInRoom = cm.listByRoom(roomId);
- clients.setDefaultModelObject(clientsInRoom);
+ clients.setDefaultModelObject(cm.streamByRoom(roomId).collect(Collectors.toList()));
target.add(clientsContainer);
}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index ac4c389..13e0c97 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -39,10 +39,12 @@ import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import javax.websocket.WebSocketContainer;
import org.apache.openmeetings.IApplication;
+import org.apache.openmeetings.core.sip.SipManager;
import org.apache.openmeetings.core.util.ChatWebSocketHelper;
import org.apache.openmeetings.core.util.WebSocketHelper;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
@@ -60,6 +62,7 @@ import org.apache.openmeetings.db.entity.room.RoomGroup;
import org.apache.openmeetings.db.entity.user.GroupUser;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Type;
+import org.apache.openmeetings.db.util.ApplicationHelper;
import org.apache.openmeetings.db.util.ws.RoomMessage;
import org.apache.openmeetings.db.util.ws.TextRoomMessage;
import org.apache.openmeetings.util.OmFileHelper;
@@ -185,6 +188,8 @@ public class Application extends AuthenticatedWebApplication implements IApplica
private WhiteboardManager wbManager;
@Autowired
private AppointmentDao appointmentDao;
+ @Autowired
+ private SipManager sipManager;
@Override
protected void init() {
@@ -348,6 +353,11 @@ public class Application extends AuthenticatedWebApplication implements IApplica
recordingDao.resetProcessingStatus(); //we are starting so all processing recordings are now errors
userManager.initHttpClient();
setInitComplete(true);
+ CompletableFuture.runAsync(() -> {
+ ThreadContext.setApplication(Application.this);
+ ApplicationHelper.ensureRequestCycle(Application.this);
+ sipManager.setUserPicture(u -> ProfileImageResourceReference.getUrl(RequestCycle.get(), u));
+ });
} catch (Exception err) {
log.error("[appStart]", err);
}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/ClientManager.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/ClientManager.java
index 317f9ee..4dfedcc 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/ClientManager.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/ClientManager.java
@@ -23,21 +23,21 @@ import static org.apache.openmeetings.web.app.WebSession.getUserId;
import static org.apache.openmeetings.web.pages.auth.SignInPage.TOKEN_PARAM;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
-import java.util.function.Predicate;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.apache.openmeetings.core.remote.KurentoHandler;
+import org.apache.openmeetings.core.sip.SipManager;
import org.apache.openmeetings.db.dao.log.ConferenceLogDao;
import org.apache.openmeetings.db.entity.basic.Client;
import org.apache.openmeetings.db.entity.log.ConferenceLog;
@@ -78,6 +78,10 @@ public class ClientManager implements IClientManager {
private Application app;
@Autowired
private KurentoHandler kHandler;
+ @Autowired
+ private SipManager sipManager;
+ @Autowired
+ private TimerService timerService;
private IMap<String, Client> map() {
return app.hazelcast.getMap(ONLINE_USERS_KEY);
@@ -170,14 +174,12 @@ public class ClientManager implements IClientManager {
if (roomId != null) {
IMap<Long, Set<String>> rooms = rooms();
rooms.lock(roomId);
- Set<String> clients = rooms.get(roomId);
- if (clients != null) {
- clients.remove(c.getUid());
- rooms.put(roomId, clients);
- onlineRooms.put(roomId, clients);
- }
+ Set<String> clients = rooms.getOrDefault(roomId, ConcurrentHashMap.newKeySet());
+ clients.remove(c.getUid());
+ rooms.put(roomId, clients);
+ onlineRooms.put(roomId, clients);
rooms.unlock(roomId);
- if (clients == null || clients.isEmpty()) {
+ if (clients.isEmpty()) {
String serverId = c.getServerId();
IMap<String, ServerInfo> servers = servers();
servers.lock(serverId);
@@ -258,8 +260,7 @@ public class ClientManager implements IClientManager {
log.debug("Adding online room client: {}, room: {}", c.getUid(), roomId);
IMap<Long, Set<String>> rooms = rooms();
rooms.lock(roomId);
- rooms.putIfAbsent(roomId, ConcurrentHashMap.newKeySet());
- Set<String> set = rooms.get(roomId);
+ Set<String> set = rooms.getOrDefault(roomId, ConcurrentHashMap.newKeySet());
set.add(c.getUid());
final int count = set.size();
rooms.put(roomId, set);
@@ -268,6 +269,7 @@ public class ClientManager implements IClientManager {
String serverId = c.getServerId();
addRoomToServer(serverId, r);
update(c);
+ timerService.scheduleSipCheck(r);
return count;
}
@@ -296,8 +298,8 @@ public class ClientManager implements IClientManager {
}
@Override
- public List<Client> list() {
- return new ArrayList<>(map().values());
+ public Stream<Client> stream() {
+ return map().values().stream();
}
@Override
@@ -306,50 +308,24 @@ public class ClientManager implements IClientManager {
}
@Override
- public List<Client> listByRoom(Long roomId) {
- return listByRoom(roomId, null);
- }
-
- public List<Client> listByRoom(Long roomId, Predicate<Client> filter) {
- List<Client> clients = new ArrayList<>();
- if (roomId != null) {
- Set<String> uids = onlineRooms.get(roomId);
- if (uids != null) {
- for (String uid : uids) {
- Client c = get(uid);
- if (c != null && (filter == null || filter.test(c))) {
- clients.add(c);
- }
- }
- }
- }
- return clients;
- }
-
- public Set<Long> listRoomIds(Long userId) {
- Set<Long> result = new HashSet<>();
- for (Entry<Long, Set<String>> me : onlineRooms.entrySet()) {
- for (String uid : me.getValue()) {
- Client c = get(uid);
- if (c != null && c.sameUserId(userId)) {
- result.add(me.getKey());
- }
- }
- }
- return result;
+ public Stream<Client> streamByRoom(Long roomId) {
+ return Optional.ofNullable(roomId)
+ .map(id -> onlineRooms.getOrDefault(id, Set.of()))
+ .stream()
+ .flatMap(Set::stream)
+ .map(uid -> get(uid))
+ .filter(Objects::nonNull);
}
public boolean isInRoom(long roomId, long userId) {
- Set<String> clients = onlineRooms.get(roomId);
- if (clients != null) {
- for (String uid : clients) {
- Client c = get(uid);
- if (c != null && c.sameUserId(userId)) {
- return true;
- }
- }
- }
- return false;
+ return Optional.of(roomId)
+ .map(id -> onlineRooms.getOrDefault(id, Set.of()))
+ .stream()
+ .flatMap(Set::stream)
+ .map(uid -> get(uid))
+ .filter(c -> c != null && c.sameUserId(userId))
+ .findAny()
+ .isPresent();
}
private List<Client> getByKeys(Long userId, String sessionId) {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/TimerService.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/TimerService.java
index 906426f..799b5a1 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/TimerService.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/TimerService.java
@@ -21,13 +21,17 @@ package org.apache.openmeetings.web.app;
import static java.util.concurrent.CompletableFuture.delayedExecutor;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
import javax.annotation.PostConstruct;
+import org.apache.openmeetings.core.sip.SipManager;
import org.apache.openmeetings.core.util.WebSocketHelper;
+import org.apache.openmeetings.db.entity.basic.Client;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.room.Room.Right;
import org.apache.openmeetings.db.entity.user.User;
@@ -42,15 +46,19 @@ import org.springframework.stereotype.Service;
public class TimerService {
private static final Logger log = LoggerFactory.getLogger(TimerService.class);
private int modCheckInterval = 5;
+ private int sipCheckInterval = 2;
private final User sysUser = new User();
private final Map<Long, CompletableFuture<Object>> modCheckMap = new ConcurrentHashMap<>();
+ private final Map<Long, CompletableFuture<Object>> sipCheckMap = new ConcurrentHashMap<>();
@Autowired
private ClientManager cm;
+ @Autowired
+ private SipManager sipManager;
@PostConstruct
private void init() {
- sysUser.setId(-1L);
+ sysUser.setId(-5L);
sysUser.setDisplayName("System");
}
@@ -59,19 +67,64 @@ public class TimerService {
roomId
, new CompletableFuture<>().completeAsync(() -> {
log.warn("Moderator room check {}", roomId);
- if (cm.listByRoom(roomId).isEmpty()) {
+ if (cm.streamByRoom(roomId).findAny().isEmpty()) {
modCheckMap.remove(roomId);
} else {
- WebSocketHelper.sendRoom(new TextRoomMessage(roomId, sysUser, RoomMessage.Type.MODERATOR_IN_ROOM, "" + !cm.listByRoom(roomId, c -> c.hasRight(Right.MODERATOR)).isEmpty()));
+ WebSocketHelper.sendRoom(new TextRoomMessage(roomId, sysUser, RoomMessage.Type.MODERATOR_IN_ROOM
+ , "" + !cm.streamByRoom(roomId).filter(c -> c.hasRight(Right.MODERATOR)).findAny().isEmpty()));
doModCheck(roomId);
}
return null;
}, delayedExecutor(modCheckInterval, TimeUnit.SECONDS)));
}
+ private void doSipCheck(Long roomId) {
+ sipCheckMap.put(
+ roomId
+ , new CompletableFuture<>().completeAsync(() -> {
+ log.warn("Sip room check {}", roomId);
+ Optional<Client> sipClient = cm.streamByRoom(roomId).filter(Client::isSip).findAny();
+ cm.streamByRoom(roomId).filter(Predicate.not(Client::isSip)).findAny().ifPresentOrElse(c -> {
+ updateSipLastName(sipClient, c.getRoom());
+ doSipCheck(roomId);
+ }, () -> {
+ log.warn("No more clients in the room {}", roomId);
+ sipCheckMap.remove(roomId);
+ sipClient.ifPresent(cm::exit);
+ });
+ return null;
+ }, delayedExecutor(sipCheckInterval, TimeUnit.SECONDS)));
+ }
+
+ private void updateSipLastName(Optional<Client> sipClient, Room r) {
+ final String newLastName = "(" + sipManager.countUsers(r.getConfno()) + ")";
+ sipClient.ifPresentOrElse(c -> {
+ if (!newLastName.equals(c.getUser().getLastname())) {
+ c.getUser().setLastname(newLastName).resetDisplayName();
+ cm.update(c);
+ WebSocketHelper.sendRoom(new TextRoomMessage(r.getId(), c, RoomMessage.Type.RIGHT_UPDATED, c.getUid()));
+ }
+ }, () -> {
+ User sipUser = sipManager.getSipUser(r);
+ sipUser.setLastname(newLastName).resetDisplayName();
+ Client c = new Client("-- unique - sip - session --", 1, sipUser, sipUser.getPictureUri());
+ cm.add(c);
+ c.setRoom(r);
+ cm.addToRoom(c);
+ WebSocketHelper.sendRoom(new TextRoomMessage(r.getId(), c, RoomMessage.Type.ROOM_ENTER, c.getUid()));
+ });
+ }
+
public void scheduleModCheck(Room r) {
- if (r.isModerated() && r.isWaitModerator() && !cm.listByRoom(r.getId()).isEmpty() && !modCheckMap.containsKey(r.getId())) {
+ if (r.isModerated() && r.isWaitModerator() && !modCheckMap.containsKey(r.getId())) {
doModCheck(r.getId());
}
}
+
+ public void scheduleSipCheck(Room r) {
+ // sip allowed and configured
+ if (sipManager.getSipUser(r) != null && !sipCheckMap.containsKey(r.getId())) {
+ doSipCheck(r.getId());
+ }
+ }
}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/UserManager.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/UserManager.java
index 53265d5..76a8dcf 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/UserManager.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/UserManager.java
@@ -223,9 +223,7 @@ public class UserManager implements IUserManager {
@Override
public boolean kickUsersByRoomId(Long roomId) {
try {
- for (Client c : cm.listByRoom(roomId)) {
- Application.kickUser(c);
- }
+ cm.streamByRoom(roomId).forEach(Application::kickUser);
return true;
} catch (Exception err) {
log.error("[kickUsersByRoomId]", err);
@@ -235,7 +233,7 @@ public class UserManager implements IUserManager {
@Override
public boolean kickExternal(Long roomId, String externalType, String externalId) {
- boolean result = false;
+ Boolean result = false;
try {
if (roomId == null) {
return result;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 73f9049..4a4ae17 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -44,7 +44,6 @@ import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
import org.apache.openmeetings.db.dao.file.FileItemDao;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.basic.Client;
-import org.apache.openmeetings.db.entity.basic.Client.StreamDesc;
import org.apache.openmeetings.db.entity.calendar.Appointment;
import org.apache.openmeetings.db.entity.calendar.MeetingMember;
import org.apache.openmeetings.db.entity.file.BaseFileItem;
@@ -167,9 +166,9 @@ public class RoomPanel extends BasePanel {
sidebar.setFilesActive(target);
}
if (Room.Type.PRESENTATION != r.getType()) {
- List<Client> mods = cm.listByRoom(r.getId(), cl -> cl.hasRight(Room.Right.MODERATOR));
- log.debug("RoomPanel::roomEnter, mods IS EMPTY ? {}, is MOD ? {}", mods.isEmpty(), c.hasRight(Room.Right.MODERATOR));
- if (mods.isEmpty()) {
+ boolean modsEmpty = noModerators();
+ log.debug("RoomPanel::roomEnter, mods IS EMPTY ? {}, is MOD ? {}", modsEmpty, c.hasRight(Room.Right.MODERATOR));
+ if (modsEmpty) {
showIdeaAlert(target, getString(r.isModerated() ? "641" : "498"));
}
}
@@ -182,11 +181,10 @@ public class RoomPanel extends BasePanel {
private void initVideos(AjaxRequestTarget target) {
StringBuilder sb = new StringBuilder();
JSONArray streams = new JSONArray();
- for (Client c : cm.listByRoom(getRoom().getId())) {
- for (StreamDesc sd : c.getStreams()) {
- streams.put(sd.toJson());
- }
- }
+ cm.streamByRoom(getRoom().getId())
+ .map(Client::getStreams)
+ .flatMap(List::stream)
+ .forEach(sd -> streams.put(sd.toJson()));
if (streams.length() > 0) {
sb.append("VideoManager.play(").append(streams).append(", ").append(kHandler.getTurnServers(getClient())).append(");");
}
@@ -312,7 +310,7 @@ public class RoomPanel extends BasePanel {
add(roomClosed = new RedirectMessageDialog("room-closed", "1098", r.isClosed(), r.getRedirectURL()));
if (r.isClosed()) {
room.setVisible(false);
- } else if (cm.listByRoom(r.getId()).size() >= r.getCapacity()) {
+ } else if (cm.streamByRoom(r.getId()).count() >= r.getCapacity()) {
accessDenied = new ExpiredMessageDialog(ACCESS_DENIED_ID, getString("99"), menu);
room.setVisible(false);
} else if (r.getId().equals(WebSession.get().getRoomId())) {
@@ -397,7 +395,7 @@ public class RoomPanel extends BasePanel {
}
if (r.isModerated() && r.isWaitModerator()
&& !c.hasRight(Right.MODERATOR)
- && cm.listByRoom(r.getId(), cl -> cl.hasRight(Right.MODERATOR)).isEmpty())
+ && noModerators())
{
room.setVisible(false);
createWaitModerator(true);
@@ -620,13 +618,9 @@ public class RoomPanel extends BasePanel {
if (streamProcessor.isRecording(r.getId())) {
handler.appendJavaScript("if (typeof(WbArea) === 'object') {WbArea.setRecStarted(true);}");
} else if (streamProcessor.recordingAllowed(getClient())) {
- boolean hasStreams = false;
- for (Client cl : cm.listByRoom(r.getId())) {
- if (!cl.getStreams().isEmpty()) {
- hasStreams = true;
- break;
- }
- }
+ boolean hasStreams = cm.streamByRoom(r.getId())
+ .filter(cl -> !cl.getStreams().isEmpty())
+ .findAny().isPresent();
handler.appendJavaScript(String.format("if (typeof(WbArea) === 'object') {WbArea.setRecStarted(false);WbArea.setRecEnabled(%s);}", hasStreams));
}
}
@@ -641,12 +635,9 @@ public class RoomPanel extends BasePanel {
}
public static boolean hasRight(ClientManager cm, long userId, long roomId, Right r) {
- for (Client c : cm.listByRoom(roomId)) {
- if (c.sameUserId(userId) && c.hasRight(r)) {
- return true;
- }
- }
- return false;
+ return cm.streamByRoom(roomId)
+ .filter(c -> c.sameUserId(userId) && c.hasRight(r))
+ .findAny().isPresent();
}
@Override
@@ -699,8 +690,7 @@ public class RoomPanel extends BasePanel {
public void requestRight(Right right, IPartialPageRequestHandler handler) {
RoomMessage.Type reqType = null;
- List<Client> mods = cm.listByRoom(r.getId(), c -> c.hasRight(Room.Right.MODERATOR));
- if (mods.isEmpty()) {
+ if (noModerators()) {
if (r.isModerated()) {
showIdeaAlert(handler, getString("696"));
return;
@@ -881,7 +871,7 @@ public class RoomPanel extends BasePanel {
private CharSequence createAddClientJs(Client c) {
JSONArray arr = new JSONArray();
- cm.listByRoom(r.getId()).stream().forEach(cl -> arr.put(cl.toJson(c.getUid().equals(cl.getUid()))));
+ cm.streamByRoom(r.getId()).forEach(cl -> arr.put(cl.toJson(c.getUid().equals(cl.getUid()))));
return new StringBuilder()
.append("Room.addClient(")
.append(arr.toString(new NullStringer()))
@@ -909,4 +899,11 @@ public class RoomPanel extends BasePanel {
}
return res;
}
+
+ private boolean noModerators() {
+ return cm.streamByRoom(r.getId())
+ .filter(cl -> cl.hasRight(Room.Right.MODERATOR))
+ .findAny()
+ .isEmpty();
+ }
}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/SipDialerDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/SipDialerDialog.java
index eb31b18..e54a13a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/SipDialerDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/SipDialerDialog.java
@@ -18,7 +18,7 @@
*/
package org.apache.openmeetings.web.room.menu;
-import org.apache.openmeetings.db.dao.room.SipDao;
+import org.apache.openmeetings.core.sip.SipManager;
import org.apache.openmeetings.web.common.OmModalCloseButton;
import org.apache.openmeetings.web.room.RoomPanel;
import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -41,7 +41,7 @@ public class SipDialerDialog extends Modal<String> {
private final TextField<String> number = new TextField<>("number", Model.of(""));
private final RoomPanel room;
@SpringBean
- private SipDao sipDao;
+ private SipManager sipDao;
public SipDialerDialog(String id, RoomPanel room) {
super(id);
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbWebSocketHelper.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbWebSocketHelper.java
index c7b8232..df58970 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbWebSocketHelper.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/wb/WbWebSocketHelper.java
@@ -18,6 +18,7 @@
*/
package org.apache.openmeetings.web.room.wb;
+import static org.apache.openmeetings.core.util.WebSocketHelper.alwaysTrue;
import static org.apache.openmeetings.core.util.WebSocketHelper.publish;
import static org.apache.openmeetings.core.util.WebSocketHelper.sendRoom;
import static org.apache.openmeetings.util.OpenmeetingsVariables.PARAM_SRC;
@@ -74,7 +75,7 @@ public class WbWebSocketHelper {
if (publish) {
publish(new WsMessageWb(roomId, meth, obj, null));
}
- sendWb(roomId, meth, obj, null);
+ sendWb(roomId, meth, obj, alwaysTrue());
}
public static void sendWbOthers(Long roomId, WbAction meth, JSONObject obj, final String uid) {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
index 9aca029..9791449 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/MessageDialog.java
@@ -38,7 +38,6 @@ import java.util.List;
import org.apache.openmeetings.core.mail.MailHandler;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
-import org.apache.openmeetings.db.dao.room.IInvitationManager;
import org.apache.openmeetings.db.dao.room.RoomDao;
import org.apache.openmeetings.db.dao.user.PrivateMessageDao;
import org.apache.openmeetings.db.dao.user.UserDao;
@@ -50,6 +49,7 @@ import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.user.PrivateMessage;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Type;
+import org.apache.openmeetings.db.manager.IInvitationManager;
import org.apache.openmeetings.util.CalendarHelper;
import org.apache.openmeetings.web.app.Application;
import org.apache.openmeetings.web.app.WebSession;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomListPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomListPanel.java
index cd4dfd4..3576fc8 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomListPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomListPanel.java
@@ -70,7 +70,7 @@ public class RoomListPanel extends Panel {
final WebMarkupContainer info = new WebMarkupContainer("info");
roomContainer.add(info.setOutputMarkupId(true)
.add(AttributeModifier.append(ATTR_TITLE, getString(String.format("room.type.%s.desc", r.getType().name())))));
- final Label curUsers = new Label("curUsers", new Model<>(cm.listByRoom(r.getId()).size()));
+ final Label curUsers = new Label("curUsers", new Model<>(cm.streamByRoom(r.getId()).count()));
roomContainer.add(curUsers.setOutputMarkupId(true));
roomContainer.add(new Label("totalUsers", r.getCapacity()));
item.add(new WebMarkupContainer("btn").add(new Label("label", label)).add(new RoomEnterBehavior(r.getId()) {
@@ -95,7 +95,7 @@ public class RoomListPanel extends Panel {
@Override
public void onClick(AjaxRequestTarget target) {
- target.add(curUsers.setDefaultModelObject(cm.listByRoom(r.getId()).size()));
+ target.add(curUsers.setDefaultModelObject(cm.streamByRoom(r.getId()).count()));
onRefreshClick(target, r);
}
}.add(AttributeModifier.append(ATTR_TITLE, new ResourceModel("lbl.refresh"))));
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomsPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomsPanel.java
index f110da7..4760969 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomsPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomsPanel.java
@@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
+import java.util.stream.Collectors;
import org.apache.openmeetings.db.dao.room.RoomDao;
import org.apache.openmeetings.db.dao.user.UserDao;
@@ -128,7 +129,7 @@ public class RoomsPanel extends UserPanel {
}
void updateRoomDetails(AjaxRequestTarget target) {
- clients.setDefaultModelObject(cm.listByRoom(roomId));
+ clients.setDefaultModelObject(cm.streamByRoom(roomId).collect(Collectors.toList()));
Room room = roomDao.get(roomId);
roomIdLbl.setDefaultModelObject(room.getId());
roomNameLbl.setDefaultModelObject(room.getName());
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
index 0edbe2b..e8391ad 100644
--- a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml
@@ -40,18 +40,9 @@
<context:annotation-config />
<context:component-scan base-package="org.apache.openmeetings" />
- <!--
- 5000 == 5 sec
- 300000 == 5 min
- 900000 == 15 min
- 1800000 == 30 min
- 3600000 == 1 hour
- 86400000 == 1 day
- 604800000 == 7 days
- -->
- <bean id="cleanupJob" class="org.apache.openmeetings.service.quartz.scheduler.CleanupJob"
- p:sessionTimeout="1800000" p:testSetupTimeout="3600000" p:resetHashTtl="86400000"
- p:confLogTtl="604800000" />
+ <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
+ p:location="classpath:openmeetings.properties" />
+
<!-- sessions clean-up -->
<bean id="cleanSessionsJobDetails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
p:targetObject-ref="cleanupJob" p:targetMethod="cleanSessions" p:concurrent="false" />
@@ -124,46 +115,10 @@
</bean>
<!-- End of Services -->
- <bean class="org.apache.openmeetings.db.dao.room.SipConfig">
- <!-- Should be uncommented and updated with real values for Asterisk-
- <property name="sipHostname" value="192.168.1.102"/>
- <property name="managerPort" value="5038"/>
- <property name="managerUser" value="openmeetings"/>
- <property name="managerPass" value="12345"/>
- <property name="managerTimeout" value="10000"/>
-
- <property name="localWsPort" value="6666"/>
- <property name="localWsHost" value="192.168.1.211"/>
- <property name="wsPort" value="8088"/>
- <property name="omSipUser" value="omsip_user"/>
- <property name="omSipPasswd" value="12345"/>
-
- <property name="uid" value="87dddad4-9ca5-475b-860f-2e0825d02b76"/>
- - -->
- </bean>
-
<!-- Thread Executor -->
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
-
- <!-- Kurento -->
- <!-- please ensure `p:kuid` below is unique, better to regenerate it from time to time -->
- <!-- `p:ignoredKuids` can be space and/or comma separated -->
- <bean id="kurentoHandler" class="org.apache.openmeetings.core.remote.KurentoHandler"
- p:kurentoWsUrl="ws://127.0.0.1:8888/kurento"
- p:checkTimeout="10000"
- p:watchThreadCount="10"
- p:turnUrl=""
- p:turnUser=""
- p:turnSecret=""
- p:turnMode="rest"
- p:turnTtl="60"
- p:objCheckTimeout="200"
- p:flowoutTimeout="5"
- p:kuid="df992960-e7b0-11ea-9acd-337fb30dd93d"
- p:ignoredKuids=""
- />
</beans>
diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings.properties b/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings.properties
new file mode 100644
index 0000000..5f566d8
--- /dev/null
+++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings.properties
@@ -0,0 +1,65 @@
+#
+# 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.
+#
+################## Timeouts ##################
+# 5000 == 5 sec
+# 300000 == 5 min
+# 900000 == 15 min
+# 1800000 == 30 min
+# 3600000 == 1 hour
+# 86400000 == 1 day
+# 604800000 == 7 days
+job.cleanup.session.timeout=1800000
+job.cleanup.test.setup.timeout=3600000
+job.cleanup.reset.hash.ttl=86400000
+job.cleanup.conf.log.ttl=604800000
+
+################## Kurento ##################
+kurento.ws.url=ws://127.0.0.1:8888/kurento
+kurento.turn.url=
+kurento.turn.user=
+kurento.turn.secret=
+kurento.turn.mode=rest
+## minutes
+kurento.turn.ttl=60
+## milliseconds
+kurento.check.timeout=10000
+## milliseconds
+kurento.object.check.timeout=200
+kurento.watch.thread.count=10
+kurento.flowout.timeout=5
+## please ensure this one is unique, better to regenerate it from time to time
+## can be generated for ex. here https://www.uuidtools.com
+kurento.kuid=df992960-e7b0-11ea-9acd-337fb30dd93d
+## this list can be space and/or comma separated
+kurento.ignored.kuids=
+
+################## SIP ##################
+### Should be uncommented and updated with real values for Asterisk ###
+#sip.hostname=192.168.1.102
+#sip.manager.port=5038
+#sip.manager.user=openmeetings
+#sip.manager.password=12345
+#sip.manager.timeout=10000
+
+#sip.ws.local.port=6666
+## 127.0.0.1 is NOT working here
+#sip.ws.local.host=192.168.1.211
+#sip.ws.remote.port=8088
+#sip.ws.remote.user=omsip_user
+#sip.ws.remote.password=12345
diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/service/quartz/TestJob.java b/openmeetings-web/src/test/java/org/apache/openmeetings/service/quartz/TestJob.java
index 01be361..58edf05 100644
--- a/openmeetings-web/src/test/java/org/apache/openmeetings/service/quartz/TestJob.java
+++ b/openmeetings-web/src/test/java/org/apache/openmeetings/service/quartz/TestJob.java
@@ -23,8 +23,8 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.setInitComplete
import org.apache.openmeetings.AbstractWicketTester;
import org.apache.openmeetings.db.entity.basic.Configuration;
-import org.apache.openmeetings.service.quartz.scheduler.CleanupJob;
-import org.apache.openmeetings.service.quartz.scheduler.ReminderJob;
+import org.apache.openmeetings.service.scheduler.CleanupJob;
+import org.apache.openmeetings.service.scheduler.ReminderJob;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
index dd4a83c..d704577 100644
--- a/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
+++ b/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
@@ -22,6 +22,7 @@ import static org.apache.openmeetings.webservice.Constants.TNS;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
import javax.jws.WebMethod;
import javax.jws.WebParam;
@@ -46,7 +47,6 @@ import org.apache.openmeetings.db.dto.basic.ServiceResult.Type;
import org.apache.openmeetings.db.dto.room.InvitationDTO;
import org.apache.openmeetings.db.dto.room.RoomDTO;
import org.apache.openmeetings.db.dto.user.UserDTO;
-import org.apache.openmeetings.db.entity.basic.Client;
import org.apache.openmeetings.db.entity.room.Invitation;
import org.apache.openmeetings.db.entity.room.Invitation.MessageType;
import org.apache.openmeetings.db.entity.room.Room;
@@ -349,7 +349,7 @@ public class RoomWebService extends BaseWebService {
@GET
@Path("/count/{roomid}")
public ServiceResult count(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="roomid") @PathParam("roomid") Long roomId) {
- return performCall(sid, User.Right.SOAP, sd -> new ServiceResult(String.valueOf(clientManager.listByRoom(roomId).size()), Type.SUCCESS));
+ return performCall(sid, User.Right.SOAP, sd -> new ServiceResult(String.valueOf(clientManager.streamByRoom(roomId).count()), Type.SUCCESS));
}
/**
@@ -364,11 +364,9 @@ public class RoomWebService extends BaseWebService {
@Path("/users/{roomid}")
public List<UserDTO> users(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="roomid") @PathParam("roomid") Long roomId) {
return performCall(sid, User.Right.SOAP, sd -> {
- List<UserDTO> result = new ArrayList<>();
- for (Client c : clientManager.listByRoom(roomId)) {
- result.add(new UserDTO(c.getUser()));
- }
- return result;
+ return clientManager.streamByRoom(roomId)
+ .map(c -> new UserDTO(c.getUser()))
+ .collect(Collectors.toList());
});
}
diff --git a/pom.xml b/pom.xml
index 60b4cf4..959ee7e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -616,18 +616,6 @@
</exclusions>
</dependency>
<dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-inline</artifactId>
- <version>${mockito.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-junit-jupiter</artifactId>
- <version>${mockito.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
@@ -644,16 +632,33 @@
<version>4.3.0</version>
</dependency>
<dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-params</artifactId>
- <version>${junit.version}</version>
- <scope>test</scope>
+ <groupId>org.asteriskjava</groupId>
+ <artifactId>asterisk-java</artifactId>
+ <version>${asterisk-java.version}</version>
</dependency>
<dependency>
<groupId>javax.sip</groupId>
<artifactId>jain-sip-ri</artifactId>
<version>${jain-sip.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-inline</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
<dependencies>