Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ class ChatRoomImpl(
}
synchronized(this) {
lastPresenceSent = null
logger.addContext("meeting_id", "")
logger.removeContext("meeting_id")
avModerationByMediaType.values.forEach { it.reset() }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import org.jxmpp.jid.*;

import java.time.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
Expand All @@ -58,6 +57,7 @@

import static org.jitsi.jicofo.conference.ConferenceUtilKt.getVisitorMucJid;
import static org.jitsi.jicofo.xmpp.IqProcessingResult.*;
import static org.apache.commons.lang3.StringUtils.isBlank;

/**
* Represents a Jitsi Meet conference. Manages the Jingle sessions with the
Expand Down Expand Up @@ -257,7 +257,7 @@ public class JitsiMeetConferenceImpl
* Whether broadcasting to visitors is currently enabled.
* TODO: support changing it.
*/
private boolean visitorsBroadcastEnabled = VisitorsConfig.config.getAutoEnableBroadcast();
private final boolean visitorsBroadcastEnabled = VisitorsConfig.config.getAutoEnableBroadcast();

@NotNull private final Instant createdInstant = Instant.now();

Expand Down Expand Up @@ -506,6 +506,40 @@ public boolean isStarted()
return started.get();
}

/**
* Initialize {@link #meetingId}, given an optional value coming from the chat room configuration. If no valid
* meeting ID is provided, a random UUID will be generated.
* @param chatRoomMeetingId the meeting ID that was set in the chat room configuration.
* @throws RuntimeException if the meeting ID is already in use by another conference.
*/
private void setMeetingId(String chatRoomMeetingId)
{
if (meetingId != null)
{
logger.error("Meeting ID is already set: " + meetingId + ", will not replace.");
return;
}

String meetingId;
if (isBlank(chatRoomMeetingId))
{
meetingId = UUID.randomUUID().toString();
logger.warn("No meetingId set for the MUC. Generating one locally.");
}
else
{
meetingId = chatRoomMeetingId;
}

if (!listener.meetingIdSet(this, meetingId))
{
logger.error("Failed to set a unique meeting ID.");
throw new RuntimeException("Failed to set a unique meeting ID.");
}

this.meetingId = meetingId;
logger.addContext("meeting_id", meetingId);
}
/**
* Joins the conference room.
*
Expand All @@ -521,16 +555,7 @@ private void joinTheRoom()
chatRoom.addListener(chatRoomListener);

ChatRoomInfo chatRoomInfo = chatRoom.join();
if (chatRoomInfo.getMeetingId() == null)
{
meetingId = UUID.randomUUID().toString();
logger.warn("No meetingId set for the MUC. Generating one locally.");
}
else
{
this.meetingId = chatRoomInfo.getMeetingId();
}
logger.addContext("meeting_id", meetingId);
setMeetingId(chatRoomInfo.getMeetingId());

mainRoomJid = chatRoomInfo.getMainRoomJid();

Expand Down Expand Up @@ -998,7 +1023,7 @@ private void onMemberLeft(ChatRoomMember chatRoomMember)
{
rescheduleSingleParticipantTimeout();
}
else if (participants.size() == 0)
else if (participants.isEmpty())
{
expireBridgeSessions();
}
Expand Down Expand Up @@ -1098,7 +1123,7 @@ else if (removed.getChatMember().getRole() == MemberRole.VISITOR)
}

@Override
public void componentsChanged(Set<XmppProvider.Component> components)
public void componentsChanged(@NotNull Set<XmppProvider.Component> components)
{
}

Expand Down Expand Up @@ -1903,9 +1928,10 @@ private long getUserParticipantCount()

/**
* Selects a visitor node for a new participant, and joins the associated chat room if not already joined
* @return
* @return the ID of the selected node, or null if the endpoint is to be sent to the main room.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotate return type with @Nullable?

* @throws Exception if joining the chat room failed.
*/
@Nullable
private String selectVisitorNode()
throws Exception
{
Expand Down Expand Up @@ -2334,7 +2360,16 @@ public interface ConferenceListener
* Event fired when conference has ended.
* @param conference the conference instance that has ended.
*/
void conferenceEnded(JitsiMeetConferenceImpl conference);
void conferenceEnded(@NotNull JitsiMeetConferenceImpl conference);

/**
* Fire an event attempting to set the meeting ID for the conference. The implementation should return `false`
* in case another meeting with the same ID already exists, which will result in an exception.
* @param conference the conference.
* @param meetingId the meetingId to attempt.
* @return true if the given meetingId was free and was associated with the conference, false otherwise.
*/
boolean meetingIdSet(@NotNull JitsiMeetConferenceImpl conference, @NotNull String meetingId);
}

/**
Expand Down
15 changes: 15 additions & 0 deletions jicofo/src/main/kotlin/org/jitsi/jicofo/FocusManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class FocusManager(
*/
private val conferences: MutableMap<EntityBareJid, JitsiMeetConferenceImpl> = ConcurrentHashMap()
private val conferencesCache: MutableList<JitsiMeetConference> = CopyOnWriteArrayList()
private val conferencesByMeetingId: MutableMap<String, JitsiMeetConferenceImpl> = ConcurrentHashMap()

/** The object used to synchronize access to [.conferences]. */
private val conferencesSyncRoot = Any()
Expand Down Expand Up @@ -149,6 +150,7 @@ class FocusManager(
synchronized(conferencesSyncRoot) {
conferences.remove(roomName)
conferencesCache.remove(conference)
conferencesByMeetingId.remove(conference.meetingId)
if (conference.includeInStatistics()) {
ConferenceMetrics.conferenceCount.dec()
}
Expand All @@ -171,6 +173,19 @@ class FocusManager(
}
}

override fun meetingIdSet(conference: JitsiMeetConferenceImpl, meetingId: String): Boolean =
synchronized(conferencesSyncRoot) {
conferencesByMeetingId[meetingId]?.let {
// If there is already a conference with this meeting ID, we don't allow setting it.
logger.warn("Meeting ID $meetingId already exists for ${it.roomName}.")
false
} ?: run {
// Otherwise, we set the meeting ID and register the conference.
conferencesByMeetingId[meetingId] = conference
true
}
}

/** {@inheritDoc} */
override fun getConference(jid: EntityBareJid): JitsiMeetConferenceImpl? = synchronized(conferencesSyncRoot) {
return conferences[jid]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class ConferenceTest : ShouldSpec() {
roomName,
mockk {
every { conferenceEnded(any()) } answers { ended = true }
every { meetingIdSet(any(), any()) } returns true
},
HashMap(),
Level.INFO,
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<kotest.version>5.7.2</kotest.version>
<slf4j.version>1.7.32</slf4j.version>
<jackson.version>2.19.0</jackson.version>
<jitsi.utils.version>1.0-140-g16ddce7</jitsi.utils.version>
<jitsi.utils.version>1.0-141-g3b92141</jitsi.utils.version>
<jicoco.version>1.1-160-g4ad2288</jicoco.version>
<ktlint-maven-plugin.version>3.0.0</ktlint-maven-plugin.version>
<spotbugs.version>4.8.6</spotbugs.version>
Expand Down Expand Up @@ -176,7 +176,7 @@
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jitsi-xmpp-extensions</artifactId>
<version>1.0-96-gb0509fc</version>
<version>1.0-97-g6f2f8f9</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand Down