processone / ejabberd

Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
https://www.process-one.net/en/ejabberd/
Other
6.06k stars 1.51k forks source link

[QUESTION] muc_room not getting saved in mysql via API create_room_with_opts #4263

Open vietnguyen87 opened 1 month ago

vietnguyen87 commented 1 month ago

Environment

ejabberd version: 24.2.40 Using the ejabberd/ecs docker container

Configuration

 hosts:
  - localhost
  - chat-ejabberd
acme:
  auto: false
#ca_file: /opt/ejabberd/cacert/cacert.pem
certfiles:
  - /opt/ejabberd/certs/veep-me-tls/*.pem
loglevel: debug

define_macro:
  TLS_CIPHERS: ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256
  TLS_OPTIONS:
  - no_sslv3
  - no_tlsv1
  - no_tlsv1_1
  - cipher_server_preference
  - no_compression
c2s_ciphers: TLS_CIPHERS
c2s_protocol_options: TLS_OPTIONS
s2s_ciphers: TLS_CIPHERS
s2s_protocol_options: TLS_OPTIONS

listen:
  -
    port: 5281
    transport: "tcp"
    ip: 0.0.0.0
    module: ejabberd_http
    request_handlers:
      /admin: ejabberd_web_admin
      /api: mod_http_api
    tls: false
  -
    port: 5222
    transport: "tcp"
    ip: '::'
    module: ejabberd_c2s
  -
    port: 5280
    transport: "tcp"
    ip: '::'
    module: ejabberd_http
    request_handlers:
      /admin: ejabberd_web_admin
  -
    port: 5443
    transport: "tcp"
    ip: '::'
    module: ejabberd_http
    request_handlers:
      /admin: ejabberd_web_admin
      /api: mod_http_api
    tls: true
  -
    port: 5269
    transport: "tcp"
    ip: '::'
    module: ejabberd_s2s_in
  -
    port: 3478
    transport: "udp"
    ip: '::'
    module: ejabberd_stun
    use_turn: false
acl:
  admin:
    user:
    - admin@localhost
  local:
    user_regexp: ""
  loopback:
    ip:
    - 127.0.0.0/8
    - ::1/128
include_config_file:
  - /opt/ejabberd/conf/access-rules.yml
include_config_file:
  - /opt/ejabberd/conf/api-permissions.yml
include_config_file:
  - /opt/ejabberd/conf/shaper.yml
include_config_file:
  - /opt/ejabberd/conf/shaper-rules.yml
default_db: "sql"
new_sql_schema: "false"
update_sql_schema: "true"
sql_database: ejabberd
sql_password: 123456
sql_port: 3306
sql_server: mysql
sql_ssl: false
sql_type: mysql
sql_username: admin
default_ram_db: "redis"
redis_db: 10
redis_password: ""
redis_pool_size: 50
redis_port: 6379
redis_queue_type: ram
redis_server: redis-master
modules:
  mod_adhoc: {}
  mod_admin_extra: {}
  mod_announce:
    access: announce
  mod_avatar: {}
  mod_blocking: {}
  mod_bosh: {}
  mod_caps: {}
  mod_carboncopy: {}
  mod_client_state: {}
  mod_configure: {}
  mod_disco: {}
  mod_fail2ban: {}
  mod_http_api: {}
  mod_http_upload:
    custom_headers:
      Access-Control-Allow-Headers: Content-Type
      Access-Control-Allow-Methods: GET,HEAD,PUT,OPTIONS
      Access-Control-Allow-Origin: https://@HOST@
    put_url: https://@HOST@:5443/upload
  mod_last: {}
  mod_mam:
    assume_mam_usage: true
    db_type: sql
    default: always
  mod_muc:
    access:
    - allow
    access_admin:
    - allow: admin
    access_create: muc_create
    access_mam:
    - allow
    access_persistent: muc_create
    default_room_options:
      allow_subscription: true
      allow_user_invites: true
      anonymous: false
      mam: true
      max_users: 100
      members_by_default: true
      members_only: false
      moderated: false
      password_protected: false
      persistent: true
      public: true
  mod_muc_admin: {}
  mod_ping: {}
  mod_privacy: {}
  mod_private: {}
  mod_proxy65:
    access: local
    max_connections: 5
  mod_pubsub:
    access_createnode: pubsub_createnode
    force_node_config:
      storage:bookmarks:
        access_model: whitelist
    plugins:
    - flat
    - pep
  mod_push: {}
  mod_push_keepalive: {}
  mod_register:
    ip_access: trusted_network
  mod_roster:
    versioning: true
  mod_s2s_dialback: {}
  mod_shared_roster: {}
  mod_stream_mgmt:
    resend_on_timeout: if_offline
  mod_stun_disco: {}
  mod_vcard: {}
  mod_vcard_xupdate: {}
  mod_version:
    show_os: false

Bug Description

I call Admin Api: https://docs.ejabberd.im/developer/ejabberd-api/admin-api/#create_room_with_opts

[::ffff:192.168.171.1]:45590 -> [::ffff:192.168.171.5]:5281
2024-07-23 16:39:15.739959+00:00 [info] API call create_room_with_opts [{<<"host">>,<<"localhost">>},
                                {<<"name">>,<<"order_26178447">>},
                                {<<"options">>,
                                 [{[{<<"name">>,<<"members_only">>},
                                    {<<"value">>,<<"true">>}]},
                                  {[{<<"name">>,<<"persistent">>},
                                    {<<"value">>,<<"true">>}]},
                                  {[{<<"name">>,<<"subscribers">>},
                                    {<<"value">>,
                                     <<"admin@localhost:admin:messages:presence:subscribers:affiliations,25864@localhost:25864:messages:presence:subscribers:affiliations,25865@localhost:25865:messages:presence:subscribers:affiliations,25866@localhost:25866:messages:presence:subscribers:affiliations">>}]},
                                  {[{<<"name">>,<<"title">>},
                                    {<<"value">>,<<"order_26178447">>}]}]},
                                {<<"service">>,<<"conference.localhost">>}] from ::ffff:192.168.171.1:45590

Sometime i get an error "Room already exists"

I can see it created by command ejabberdctl get_room_options order_53772 conference.localhost

image

but it not getting saved in muc_room and muc_room_subscribers tables in mysql.

Please help. Thanks.!

badlop commented 1 month ago

First of all, you didn't show your full configuration file, maybe some other parts of it are relevant. For example, remember that ejabberd by default stores persistent data in its internal Mnesia database

Did you setup db_type mod_muc option ?

modules:
  mod_muc:
    db_type: sql

Or did you setup the toplevel default_db option ?

default_db: sql

Sometime i get an error "Room already exists"

Sometimes you get that error, the room exists, but the room is not stored in MySQL database?

Maybe the room existed before you create it?

And what happens other times? Other times the room didn't exist first, you run the API and you don't get that error, the room is created correctly, and the room is stored correctly in the MySQL database?

I tried ejabberd 24.02 with your configuration, tried your query, and it works correctly. Of course, I only tried a few times, maybe the problem appears with many many requests...

ejabberd version: 24.2.40

Please try with ejabberd 24.7, as it includes some fixes in the create_room_with_opts API: https://github.com/processone/ejabberd/commit/06675e4fb2b05a6d2d2b63ae26492b60286dc80e

vietnguyen87 commented 1 month ago

Thanks @badlop,

sorry, let me update ejabberd version: 24.2.0

I has updated full configuration.

Or did you setup the toplevel default_db option ?

I has configured default_db: "sql" already. And not configured yet.

modules:
  mod_muc:
    db_type: sql

And what happens other times? Other times the room didn't exist first, you run the API and you don't get that error, the room is created correctly, and the room is stored correctly in the MySQL database?

Yes, the room is created correctly and saved to MySQL. Sometime i get an error "Room already exists" although it was not existed before.
It's not too much request. I just work on my testing environment with fews request / second.

By the way I have a question. I don't have mod_offline configured at the moment. However, users still receive the messages when they are back to online.

badlop commented 1 month ago

let me update ejabberd version: 24.2.0

Once you update to ejabberd 24.7, let's see if the problem gets solved.

I has configured default_db: "sql" already.

Aha, then all modules will try to use sql for their persistent storage, including mod_muc. No need to configure db_type.

I just work on my testing environment with fews request / second.

Maybe you accidentally call the API two times to create the same room? Or maybe the API client fails and sends again the same query? Check the ejabberd logs for recent API calls...

I don't have mod_offline configured at the moment. However, users still receive the messages when they are back to online.

That is rare. Maybe the module is enabled in some of the included config files?

Or maybe the module is not really enabled, and users just get some other messages from MAM storage (which is different to Offline storage). When a user sends a message to an offline user, in what SQL table is the message stored: in spool (using mod_offline) or in archive (using mod_mam)?

vietnguyen87 commented 1 month ago

Hi @badlop,

. That is rare. Maybe the module is enabled in some of the included config files?

How can i check it?

. Or maybe the module is not really enabled, and users just get some other messages from MAM storage (which is different to Offline storage). When a user sends a message to an offline user, in what SQL table is the message stored: in spool (using mod_offline) or in archive (using mod_mam)?

both of them (spool and archive tables) are storing the messages.

badlop commented 1 month ago

ejabberd first reads its configuration file ejabberd.yml.

If that file contains the option include_config_file, then those additional files are read.

Additionally, if there are contribution modules installed, it reads their configuration files, see step 5. of Basic Usage

The question now is, how to know in your specific server what are the options being used, and what files are being read by ejabberd?


View options with dump_config command

This commands dumps the consolidated options that are really being used by ejabberd:

$ ejabberdctl dump_config /tmp/ejabberd.yml

Now view /tmp/ejabberd.yml, is mod_offline enabled?

You said that you don't have mod_offline enabled in your configuration file, then... why is mod_offline enabled in ejabberd? Maybe ejabberd reads other configuration file, or some additional files that enabled it.


Config file paths

Let's see what configuration files are read by ejabberd. Open an interactive erlang shell attached to your ejabberd node, so you can execute erlang functions and get their result. This is an example in my test server:

$ ejabberdctl debug
...

(ejabberd@localhost)1> ejabberd_config:path().
<<"_build/relive/conf/ejabberd.yml">>

(ejabberd@localhost)2> ext_mod:config_dir().
"/home/badlop/.ejabberd-modules/conf"

(ejabberd@localhost)3> ext_mod:modules_configs().
[<<"/home/badlop/.ejabberd-modules/mod_webadmin_config/conf/mod_webadmin_config.yml">>]

Now check all those files. Does any of those files enable mod_offline?


Install mod_webadmin_config

Alternatively to the previous methods, you can install mod_webadmin_config. That module adds a page to ejabberd's WebAdmin that shows the configuration files that are read and also shows the options being used.