From bf01133a1ab89fa0c45bbd293d6e41eb86ac901f Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 3 Jan 2025 13:18:28 +0100 Subject: [PATCH] OF-2918: Expose numeric MUC room ID in events A MUC room of the same name (JID) can be created, destroyed and recreated again. The two rooms should be seen as two different rooms. When using the JID of the rooms, there's no way to distinghuish between them. For that, Openfire's numeric ID can be used. In this commit, the numeric ID is added to selected MUC events. --- .../openfire/muc/MUCEventDispatcher.java | 20 +++++++++---------- .../openfire/muc/MUCEventListener.java | 10 ++++++---- .../jivesoftware/openfire/muc/MUCRoom.java | 8 ++++---- .../openfire/muc/spi/LocalMUCRoomManager.java | 8 +++++--- .../muc/spi/MultiUserChatServiceImpl.java | 7 ++++--- .../openfire/muc/spi/OccupantManager.java | 9 +++++---- 6 files changed, 34 insertions(+), 28 deletions(-) diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCEventDispatcher.java b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCEventDispatcher.java index ec2ea1c8fd..79fff04de4 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCEventDispatcher.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCEventDispatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Jive Software, 2017-2024 Ignite Realtime Foundation. All rights reserved. + * Copyright (C) 2005-2008 Jive Software, 2017-2025 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,32 +102,32 @@ public static void privateMessageRecieved(JID toJID, JID fromJID, Message messag } } - public static void roomCreated(JID roomJID) { + public static void roomCreated(long roomID, JID roomJID) { for (MUCEventListener listener : listeners) { try { - listener.roomCreated(roomJID); + listener.roomCreated(roomID, roomJID); } catch (Exception e) { - Log.warn("An exception occurred while dispatching a 'roomCreated' event!", e); + Log.warn("An exception occurred while dispatching a 'roomCreated' event for room {} ({})!", roomJID, roomID, e); } } } - public static void roomDestroyed(JID roomJID) { + public static void roomDestroyed(long roomID, JID roomJID) { for (MUCEventListener listener : listeners) { try { - listener.roomDestroyed(roomJID); + listener.roomDestroyed(roomID, roomJID); } catch (Exception e) { - Log.warn("An exception occurred while dispatching a 'roomDestroyed' event!", e); + Log.warn("An exception occurred while dispatching a 'roomDestroyed' event for room {} ({})!", roomJID, roomID, e); } } } - public static void roomClearChatHistory(JID roomJID) { + public static void roomClearChatHistory(long roomID, JID roomJID) { for (MUCEventListener listener : listeners) { try { - listener.roomClearChatHistory(roomJID); + listener.roomClearChatHistory(roomID, roomJID); } catch (Exception e) { - Log.warn("An exception occurred while dispatching a 'roomClearChatHistory' event for room {}!", roomJID, e); + Log.warn("An exception occurred while dispatching a 'roomClearChatHistory' event for room {} ({})!", roomJID, roomID, e); } } } diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCEventListener.java b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCEventListener.java index 21e8e3d180..86d8fdd92b 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCEventListener.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCEventListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Jive Software, 2017-2024 Ignite Realtime Foundation. All rights reserved. + * Copyright (C) 2005-2008 Jive Software, 2017-2025 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,8 @@ import org.xmpp.packet.JID; import org.xmpp.packet.Message; +import javax.annotation.Nonnull; + /** * Interface to listen for MUC events. Use the {@link MUCEventDispatcher#addListener(MUCEventListener)} * method to register for events. @@ -32,21 +34,21 @@ public interface MUCEventListener { * * @param roomJID JID of the room that was created. */ - void roomCreated(JID roomJID); + void roomCreated(final long roomID, final @Nonnull JID roomJID); /** * Event triggered when a room was destroyed. * * @param roomJID JID of the room that was destroyed. */ - void roomDestroyed(JID roomJID); + void roomDestroyed(final long roomID, final @Nonnull JID roomJID); /** * Event triggered when a clear chat history command was issued. * * @param roomJID JID of the room to clear chat history. */ - void roomClearChatHistory(JID roomJID); + void roomClearChatHistory(final long roomID, final @Nonnull JID roomJID); /** * Event triggered when a new occupant joins a room. diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoom.java b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoom.java index fbe71799e8..23c7a66318 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoom.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/MUCRoom.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Jive Software, 2016-2024 Ignite Realtime Foundation. All rights reserved. + * Copyright (C) 2004-2008 Jive Software, 2016-2025 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1364,7 +1364,7 @@ public CompletableFuture clearChatHistory() { // Remove the history of the room from memory (preventing it to pop up in a new room by the same name). roomHistory.purge(); // Fire event to clear chat room history - MUCEventDispatcher.roomClearChatHistory(getJID()); + MUCEventDispatcher.roomClearChatHistory(getID(), getJID()); }); } @@ -1446,10 +1446,10 @@ public void destroyRoom(JID alternateJID, String password, String reason) { roomHistory.purge(); // If we are not preserving room history on deletion, fire event to clear chat room history if(!preserveHistOnRoomDeletion) { - MUCEventDispatcher.roomClearChatHistory(getJID()); + MUCEventDispatcher.roomClearChatHistory(getID(), getJID()); } // Fire event that the room has been destroyed - MUCEventDispatcher.roomDestroyed(getJID()); + MUCEventDispatcher.roomDestroyed(getID(), getJID()); } /** diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/LocalMUCRoomManager.java b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/LocalMUCRoomManager.java index 549b0894d8..ae1e389382 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/LocalMUCRoomManager.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/LocalMUCRoomManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2024 Ignite Realtime Foundation. All rights reserved. + * Copyright (C) 2016-2025 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -402,7 +402,8 @@ public void entryRemoved(@Nonnull String key, @Nullable MUCRoom oldValue, @Nonnu localRooms.remove(key); final MultiUserChatService service = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName); if (service != null) { - service.getOccupantManager().roomDestroyed(new JID(key, service.getServiceDomain(), null)); + final long roomID = -1; // Unused by OccupantManager. + service.getOccupantManager().roomDestroyed(roomID, new JID(key, service.getServiceDomain(), null)); } } @@ -415,7 +416,8 @@ public void entryEvicted(@Nonnull String key, @Nullable MUCRoom oldValue, @Nonnu localRooms.remove(key); final MultiUserChatService service = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceName); if (service != null) { - service.getOccupantManager().roomDestroyed(new JID(key, service.getServiceDomain(), null)); + final long roomID = -1; // Unused by OccupantManager. + service.getOccupantManager().roomDestroyed(roomID, new JID(key, service.getServiceDomain(), null)); } } diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java index d096e86c15..89207eece8 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/MultiUserChatServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008 Jive Software, 2016-2024 Ignite Realtime Foundation. All rights reserved. + * Copyright (C) 2004-2008 Jive Software, 2016-2025 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1963,7 +1963,7 @@ public MUCRoom getChatRoom(@Nonnull final String roomName, @Nonnull final JID us } if (created) { // Fire event that a new room has been created - MUCEventDispatcher.roomCreated(room.getSelfRepresentation().getOccupantJID()); + MUCEventDispatcher.roomCreated(room.getID(), room.getSelfRepresentation().getOccupantJID()); } if (loaded || created) { // Initiate FMUC, when enabled. @@ -3325,6 +3325,7 @@ public void leftCluster(byte[] nodeID) Log.info("Room '{}' was lost from the data structure that's shared in the cluster (the cache). This room is now considered 'gone' for this cluster node. Occupants will be informed.", lostRoomName); final Set occupants = occupantManager.occupantsForRoomByNode(lostRoomName, XMPPServer.getInstance().getNodeID(), true); final JID roomJID = new JID(lostRoomName, fullServiceName, null); + final long roomID = -1; // As this value is currently not used by OccupantManager, we can avoid the complexity in having it looked up. for (final OccupantManager.Occupant occupant : occupants) { try { // Send a presence stanza of type "unavailable" to the occupant @@ -3349,7 +3350,7 @@ public void leftCluster(byte[] nodeID) } } // Clean up the locally maintained bookkeeping. - occupantManager.roomDestroyed(roomJID); + occupantManager.roomDestroyed(roomID, roomJID); removeChatRoom(lostRoomName); } catch (Exception e) { Log.warn("Unable to inform occupants on local cluster node that they are being removed from room '{}' because of a (cluster) error.", lostRoomName, e); diff --git a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/OccupantManager.java b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/OccupantManager.java index 971f0fb49b..ed936ba518 100644 --- a/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/OccupantManager.java +++ b/xmppserver/src/main/java/org/jivesoftware/openfire/muc/spi/OccupantManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Ignite Realtime Foundation. All rights reserved. + * Copyright (C) 2021-2025 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -937,12 +937,13 @@ public Map getNodeByLocalOccupant() } @Override - public void roomCreated(JID roomJID) { + public void roomCreated(final long roomID, @Nonnull final JID roomJID) { // Not used. } @Override - public void roomDestroyed(@Nonnull final JID roomJID) + // Beware that the invocation does not properly initialize the first argument! Do not use it without fixing that! + public void roomDestroyed(final long unused, @Nonnull final JID roomJID) { // When a room is destroyed, remove all registered occupants for that room. mutex.writeLock().lock(); @@ -961,7 +962,7 @@ public void roomDestroyed(@Nonnull final JID roomJID) } @Override - public void roomClearChatHistory(JID roomJID) { + public void roomClearChatHistory(final long roomID, final @Nonnull JID roomJID) { // Not used. }