blob: 1e94ec5f284a59ef783011a2f26d14ea906f60f3 [file] [log] [blame]
/*
* 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.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;
import org.apache.openmeetings.db.util.ws.RoomMessage;
import org.apache.openmeetings.db.util.ws.TextRoomMessage;
import org.apache.wicket.ThreadContext;
import org.apache.openmeetings.mediaserver.remote.KurentoHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@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;
@Autowired
private KurentoHandler kHandler;
@Autowired
private Application app;
@PostConstruct
private void init() {
sysUser.setId(-5L);
sysUser.setDisplayName("System");
}
private void doModCheck(Long roomId) {
modCheckMap.put(
roomId
, new CompletableFuture<>().completeAsync(() -> {
ThreadContext.setApplication(app);
log.warn("Moderator room check {}", roomId);
if (cm.streamByRoom(roomId).findAny().isEmpty()) {
modCheckMap.remove(roomId);
} else {
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(() -> {
ThreadContext.setApplication(app);
log.trace("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) {
long count = sipManager.countUsers(r.getConfno());
final String newLastName = "(" + count + ")";
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());
c.allow(Right.VIDEO, Right.AUDIO);
cm.add(c);
c.setRoom(r);
cm.addToRoom(c);
WebSocketHelper.sendRoom(new TextRoomMessage(r.getId(), c, RoomMessage.Type.ROOM_ENTER, c.getUid()));
});
kHandler.updateSipCount(r, count);
}
public void scheduleModCheck(Room r) {
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 && r.isSipEnabled() && !sipCheckMap.containsKey(r.getId())) {
doSipCheck(r.getId());
}
}
}