mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-05-06 10:05:58 +08:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6eb6ac1c57 | |||
| 2804d90020 | |||
| 4ca3f2dc0c | |||
| b92c5ab821 | |||
| 9c4b6e50ef | |||
| 54e189d80f | |||
| 1b6d70e4a7 | |||
| 4c9cf55867 | |||
| 9be25ab041 | |||
| 8a5f8a10ba | |||
| 1f3b41e379 | |||
| 1684c82458 | |||
| bc326704f1 | |||
| e254bbf1fc | |||
| 54309b83a2 | |||
| d55cb0fa8b | |||
| 2e58a5cc82 | |||
| cc957886b1 | |||
| 78c82e08b8 | |||
| 09cb8336ad | |||
| 9a436087cf | |||
| 6c7c268b1f | |||
| 04b7e6b75e | |||
| 916d074cf9 | |||
| 61b968fbf2 | |||
| efed369c0c | |||
| aaf898567f | |||
| 62583b32a7 | |||
| 4890487429 | |||
| 744f481b9c | |||
| f242066f30 | |||
| 57710bb9e3 | |||
| 0006bce0a2 | |||
| 0bb6f610ef | |||
| 82d133588e | |||
| d70dc7b16b | |||
| 9f796e78c1 | |||
| efcd76318e | |||
| d7af353e42 | |||
| ab1691865f |
@@ -17,6 +17,8 @@ OPENIM_ADMIN_FRONT_IMAGE=openim/openim-admin-front:release-v1.8.4
|
|||||||
|
|
||||||
DATA_DIR=./
|
DATA_DIR=./
|
||||||
|
|
||||||
|
MONGO_BACKUP_DIR=${DATA_DIR}components/backup/mongo/
|
||||||
|
|
||||||
PROMETHEUS_PORT=19091
|
PROMETHEUS_PORT=19091
|
||||||
ALERTMANAGER_PORT=19093
|
ALERTMANAGER_PORT=19093
|
||||||
GRAFANA_PORT=13000
|
GRAFANA_PORT=13000
|
||||||
|
|||||||
@@ -8,19 +8,40 @@ jobs:
|
|||||||
update-version:
|
update-version:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
TAG_VERSION: ${{ github.event.release.tag_name }}
|
TAG_VERSION: ${{ github.event.release.tag_name }}
|
||||||
steps:
|
steps:
|
||||||
# Step 1: Checkout the original repository's code
|
# Step 1: Checkout the original repository's code
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
# submodules: "recursive"
|
||||||
|
|
||||||
|
- name: Safe submodule initialization
|
||||||
|
run: |
|
||||||
|
echo "Checking for submodules..."
|
||||||
|
if [ -f .gitmodules ]; then
|
||||||
|
if [ -s .gitmodules ]; then
|
||||||
|
echo "Initializing submodules..."
|
||||||
|
if git submodule sync --recursive 2>/dev/null; then
|
||||||
|
git submodule update --init --force --recursive || {
|
||||||
|
echo "Warning: Some submodules failed to initialize, continuing anyway..."
|
||||||
|
}
|
||||||
|
else
|
||||||
|
echo "Warning: Submodule sync failed, continuing without submodules..."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo ".gitmodules exists but is empty, skipping submodule initialization"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No .gitmodules file found, no submodules to initialize"
|
||||||
|
fi
|
||||||
|
|
||||||
# Step 2: Set up Git with official account
|
# Step 2: Set up Git with official account
|
||||||
- name: Set up Git
|
- name: Set up Git
|
||||||
run: |
|
run: |
|
||||||
git config user.name "github-actions[bot]"
|
git config --global user.name "github-actions[bot]"
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
# Step 3: Check and delete existing tag
|
# Step 3: Check and delete existing tag
|
||||||
- name: Check and delete existing tag
|
- name: Check and delete existing tag
|
||||||
@@ -33,7 +54,8 @@ jobs:
|
|||||||
# Step 4: Update version file
|
# Step 4: Update version file
|
||||||
- name: Update version file
|
- name: Update version file
|
||||||
run: |
|
run: |
|
||||||
echo "${{ env.TAG_VERSION }}" > version/version
|
mkdir -p version
|
||||||
|
echo -n "${{ env.TAG_VERSION }}" > version/version
|
||||||
|
|
||||||
# Step 5: Commit and push changes
|
# Step 5: Commit and push changes
|
||||||
- name: Commit and push changes
|
- name: Commit and push changes
|
||||||
@@ -42,43 +64,56 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git add version/version
|
git add version/version
|
||||||
git commit -m "Update version to ${{ env.TAG_VERSION }}"
|
git commit -m "Update version to ${{ env.TAG_VERSION }}"
|
||||||
git push origin HEAD:${{ github.ref }}
|
|
||||||
|
|
||||||
# Step 6: Create and push tag
|
# Step 6: Update tag
|
||||||
- name: Create and push tag
|
- name: Update tag
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
run: |
|
run: |
|
||||||
git tag ${{ env.TAG_VERSION }}
|
git tag -fa ${{ env.TAG_VERSION }} -m "Update version to ${{ env.TAG_VERSION }}"
|
||||||
git push origin ${{ env.TAG_VERSION }}
|
git push origin ${{ env.TAG_VERSION }} --force
|
||||||
|
|
||||||
# Step 7: Find and Publish Draft Release
|
# Step 7: Find and Publish Draft Release
|
||||||
- name: Find and Publish Draft Release
|
- name: Find and Publish Draft Release
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
script: |
|
script: |
|
||||||
// Get the list of releases
|
const { owner, repo } = context.repo;
|
||||||
const releases = await github.rest.repos.listReleases({
|
const tagName = process.env.TAG_VERSION;
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo
|
|
||||||
});
|
|
||||||
|
|
||||||
// Find the draft release where the title and tag_name are the same
|
try {
|
||||||
const draftRelease = releases.data.find(release =>
|
let release;
|
||||||
release.draft && release.name === release.tag_name
|
try {
|
||||||
);
|
const response = await github.rest.repos.getReleaseByTag({
|
||||||
|
owner,
|
||||||
if (draftRelease) {
|
repo,
|
||||||
// Publish the draft release using the release_id
|
tag: tagName
|
||||||
|
});
|
||||||
|
release = response.data;
|
||||||
|
} catch (tagError) {
|
||||||
|
core.info(`Release not found by tag, searching all releases...`);
|
||||||
|
const releases = await github.rest.repos.listReleases({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
per_page: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
release = releases.data.find(r => r.draft && r.tag_name === tagName);
|
||||||
|
if (!release) {
|
||||||
|
throw new Error(`No release found with tag ${tagName}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await github.rest.repos.updateRelease({
|
await github.rest.repos.updateRelease({
|
||||||
owner: context.repo.owner,
|
owner,
|
||||||
repo: context.repo.repo,
|
repo,
|
||||||
release_id: draftRelease.id, // Use release_id
|
release_id: release.id,
|
||||||
draft: false
|
draft: false,
|
||||||
|
prerelease: release.prerelease
|
||||||
});
|
});
|
||||||
|
|
||||||
core.info(`Draft Release ${draftRelease.tag_name} published successfully.`);
|
const status = release.draft ? "was draft" : "was already published";
|
||||||
} else {
|
core.info(`Release ${tagName} ensured to be published (${status}).`);
|
||||||
core.info("No matching draft release found.");
|
|
||||||
}
|
} catch (error) {
|
||||||
|
core.warning(`Could not find or update release for tag ${tagName}: ${error.message}`);
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ COPY --from=builder $SERVER_DIR/start-config.yml $SERVER_DIR/
|
|||||||
COPY --from=builder $SERVER_DIR/go.mod $SERVER_DIR/
|
COPY --from=builder $SERVER_DIR/go.mod $SERVER_DIR/
|
||||||
COPY --from=builder $SERVER_DIR/go.sum $SERVER_DIR/
|
COPY --from=builder $SERVER_DIR/go.sum $SERVER_DIR/
|
||||||
|
|
||||||
RUN go get github.com/openimsdk/gomake@v0.0.14-alpha.5
|
RUN go get github.com/openimsdk/gomake@v0.0.15-alpha.5
|
||||||
|
|
||||||
# Set the command to run when the container starts
|
# Set the command to run when the container starts
|
||||||
ENTRYPOINT ["sh", "-c", "mage start && tail -f /dev/null"]
|
ENTRYPOINT ["sh", "-c", "mage start && tail -f /dev/null"]
|
||||||
|
|||||||
+13
-13
@@ -33,7 +33,7 @@ joinGroupApplication:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: false
|
enable: true
|
||||||
title: joinGroupApplication title
|
title: joinGroupApplication title
|
||||||
desc: joinGroupApplication desc
|
desc: joinGroupApplication desc
|
||||||
ext: joinGroupApplication ext
|
ext: joinGroupApplication ext
|
||||||
@@ -53,7 +53,7 @@ groupApplicationAccepted:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: false
|
enable: true
|
||||||
title: groupApplicationAccepted title
|
title: groupApplicationAccepted title
|
||||||
desc: groupApplicationAccepted desc
|
desc: groupApplicationAccepted desc
|
||||||
ext: groupApplicationAccepted ext
|
ext: groupApplicationAccepted ext
|
||||||
@@ -63,7 +63,7 @@ groupApplicationRejected:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: false
|
enable: true
|
||||||
title: groupApplicationRejected title
|
title: groupApplicationRejected title
|
||||||
desc: groupApplicationRejected desc
|
desc: groupApplicationRejected desc
|
||||||
ext: groupApplicationRejected ext
|
ext: groupApplicationRejected ext
|
||||||
@@ -200,7 +200,7 @@ friendApplicationAdded:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: false
|
enable: true
|
||||||
title: Somebody applies to add you as a friend
|
title: Somebody applies to add you as a friend
|
||||||
desc: Somebody applies to add you as a friend
|
desc: Somebody applies to add you as a friend
|
||||||
ext: Somebody applies to add you as a friend
|
ext: Somebody applies to add you as a friend
|
||||||
@@ -230,7 +230,7 @@ friendAdded:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: We have become friends
|
title: We have become friends
|
||||||
desc: We have become friends
|
desc: We have become friends
|
||||||
ext: We have become friends
|
ext: We have become friends
|
||||||
@@ -240,7 +240,7 @@ friendDeleted:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: deleted a friend
|
title: deleted a friend
|
||||||
desc: deleted a friend
|
desc: deleted a friend
|
||||||
ext: deleted a friend
|
ext: deleted a friend
|
||||||
@@ -250,7 +250,7 @@ friendRemarkSet:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: Your friend's profile has been changed
|
title: Your friend's profile has been changed
|
||||||
desc: Your friend's profile has been changed
|
desc: Your friend's profile has been changed
|
||||||
ext: Your friend's profile has been changed
|
ext: Your friend's profile has been changed
|
||||||
@@ -260,7 +260,7 @@ blackAdded:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: blocked a user
|
title: blocked a user
|
||||||
desc: blocked a user
|
desc: blocked a user
|
||||||
ext: blocked a user
|
ext: blocked a user
|
||||||
@@ -270,7 +270,7 @@ blackDeleted:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: Remove a blocked user
|
title: Remove a blocked user
|
||||||
desc: Remove a blocked user
|
desc: Remove a blocked user
|
||||||
ext: Remove a blocked user
|
ext: Remove a blocked user
|
||||||
@@ -280,7 +280,7 @@ friendInfoUpdated:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: friend info updated
|
title: friend info updated
|
||||||
desc: friend info updated
|
desc: friend info updated
|
||||||
ext: friend info updated
|
ext: friend info updated
|
||||||
@@ -291,7 +291,7 @@ userInfoUpdated:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: userInfo updated
|
title: userInfo updated
|
||||||
desc: userInfo updated
|
desc: userInfo updated
|
||||||
ext: userInfo updated
|
ext: userInfo updated
|
||||||
@@ -312,7 +312,7 @@ conversationChanged:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: conversation changed
|
title: conversation changed
|
||||||
desc: conversation changed
|
desc: conversation changed
|
||||||
ext: conversation changed
|
ext: conversation changed
|
||||||
@@ -322,7 +322,7 @@ conversationSetPrivate:
|
|||||||
reliabilityLevel: 1
|
reliabilityLevel: 1
|
||||||
unreadCount: false
|
unreadCount: false
|
||||||
offlinePush:
|
offlinePush:
|
||||||
enable: true
|
enable: false
|
||||||
title: burn after reading
|
title: burn after reading
|
||||||
desc: burn after reading
|
desc: burn after reading
|
||||||
ext: burn after reading
|
ext: burn after reading
|
||||||
|
|||||||
+5
-1
@@ -15,4 +15,8 @@ imAdminUserID: [ imAdmin ]
|
|||||||
# 1: For Android, iOS, Windows, Mac, and web platforms, only one instance can be online at a time
|
# 1: For Android, iOS, Windows, Mac, and web platforms, only one instance can be online at a time
|
||||||
multiLogin:
|
multiLogin:
|
||||||
policy: 1
|
policy: 1
|
||||||
maxNumOneEnd: 30
|
maxNumOneEnd: 30
|
||||||
|
|
||||||
|
rpcMaxBodySize:
|
||||||
|
requestMaxBodySize: 8388608
|
||||||
|
responseMaxBodySize: 8388608
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ services:
|
|||||||
- "${DATA_DIR}/components/mongodb/data/db:/data/db"
|
- "${DATA_DIR}/components/mongodb/data/db:/data/db"
|
||||||
- "${DATA_DIR}/components/mongodb/data/logs:/data/logs"
|
- "${DATA_DIR}/components/mongodb/data/logs:/data/logs"
|
||||||
- "${DATA_DIR}/components/mongodb/data/conf:/etc/mongo"
|
- "${DATA_DIR}/components/mongodb/data/conf:/etc/mongo"
|
||||||
|
- "${MONGO_BACKUP_DIR}:/data/backup"
|
||||||
environment:
|
environment:
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
- wiredTigerCacheSizeGB=1
|
- wiredTigerCacheSizeGB=1
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ require (
|
|||||||
github.com/gorilla/websocket v1.5.1
|
github.com/gorilla/websocket v1.5.1
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/openimsdk/protocol v0.0.72-alpha.71
|
github.com/openimsdk/protocol v0.0.73-alpha.12
|
||||||
github.com/openimsdk/tools v0.0.50-alpha.67
|
github.com/openimsdk/tools v0.0.50-alpha.84
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/prometheus/client_golang v1.18.0
|
github.com/prometheus/client_golang v1.18.0
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
@@ -35,12 +35,11 @@ require (
|
|||||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||||
github.com/kelindar/bitmap v1.5.2
|
github.com/kelindar/bitmap v1.5.2
|
||||||
github.com/likexian/gokit v0.25.13
|
github.com/likexian/gokit v0.25.13
|
||||||
github.com/openimsdk/gomake v0.0.14-alpha.5
|
github.com/openimsdk/gomake v0.0.15-alpha.5
|
||||||
github.com/redis/go-redis/v9 v9.4.0
|
github.com/redis/go-redis/v9 v9.4.0
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||||
github.com/spf13/viper v1.18.2
|
github.com/spf13/viper v1.18.2
|
||||||
github.com/stathat/consistent v1.0.0
|
|
||||||
go.etcd.io/etcd/client/v3 v3.5.13
|
go.etcd.io/etcd/client/v3 v3.5.13
|
||||||
go.uber.org/automaxprocs v1.5.3
|
go.uber.org/automaxprocs v1.5.3
|
||||||
golang.org/x/sync v0.8.0
|
golang.org/x/sync v0.8.0
|
||||||
@@ -88,19 +87,27 @@ require (
|
|||||||
github.com/eapache/go-resiliency v1.6.0 // indirect
|
github.com/eapache/go-resiliency v1.6.0 // indirect
|
||||||
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
|
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect
|
||||||
github.com/eapache/queue v1.1.0 // indirect
|
github.com/eapache/queue v1.1.0 // indirect
|
||||||
|
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
|
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-logr/logr v1.4.2 // indirect
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||||
|
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||||
|
github.com/go-openapi/swag v0.22.4 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-zookeeper/zk v1.0.3 // indirect
|
github.com/go-zookeeper/zk v1.0.3 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/protobuf v1.5.4 // indirect
|
github.com/golang/protobuf v1.5.4 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/gnostic-models v0.6.8 // indirect
|
||||||
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
github.com/google/s2a-go v0.1.7 // indirect
|
github.com/google/s2a-go v0.1.7 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
|
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
|
||||||
@@ -117,6 +124,7 @@ require (
|
|||||||
github.com/jinzhu/copier v0.4.0 // indirect
|
github.com/jinzhu/copier v0.4.0 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/kelindar/simd v1.1.2 // indirect
|
github.com/kelindar/simd v1.1.2 // indirect
|
||||||
github.com/klauspost/compress v1.17.7 // indirect
|
github.com/klauspost/compress v1.17.7 // indirect
|
||||||
@@ -126,6 +134,7 @@ require (
|
|||||||
github.com/lithammer/shortuuid v3.0.0+incompatible // indirect
|
github.com/lithammer/shortuuid v3.0.0+incompatible // indirect
|
||||||
github.com/magefile/mage v1.15.0 // indirect
|
github.com/magefile/mage v1.15.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||||
github.com/minio/md5-simd v1.1.2 // indirect
|
github.com/minio/md5-simd v1.1.2 // indirect
|
||||||
@@ -135,6 +144,7 @@ require (
|
|||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||||
github.com/mozillazg/go-httpheader v0.4.0 // indirect
|
github.com/mozillazg/go-httpheader v0.4.0 // indirect
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
@@ -156,6 +166,7 @@ require (
|
|||||||
github.com/tklauser/go-sysconf v0.3.13 // indirect
|
github.com/tklauser/go-sysconf v0.3.13 // indirect
|
||||||
github.com/tklauser/numcpus v0.7.0 // indirect
|
github.com/tklauser/numcpus v0.7.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||||
github.com/xdg-go/scram v1.1.2 // indirect
|
github.com/xdg-go/scram v1.1.2 // indirect
|
||||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||||
@@ -177,14 +188,25 @@ require (
|
|||||||
golang.org/x/net v0.29.0 // indirect
|
golang.org/x/net v0.29.0 // indirect
|
||||||
golang.org/x/oauth2 v0.23.0 // indirect
|
golang.org/x/oauth2 v0.23.0 // indirect
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
|
golang.org/x/term v0.24.0 // indirect
|
||||||
golang.org/x/text v0.18.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
google.golang.org/appengine/v2 v2.0.2 // indirect
|
google.golang.org/appengine/v2 v2.0.2 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
|
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||||
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gorm.io/gorm v1.25.8 // indirect
|
gorm.io/gorm v1.25.8 // indirect
|
||||||
stathat.com/c/consistent v1.0.0 // indirect
|
k8s.io/api v0.31.2 // indirect
|
||||||
|
k8s.io/apimachinery v0.31.2 // indirect
|
||||||
|
k8s.io/client-go v0.31.2 // indirect
|
||||||
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
|
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
|
||||||
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||||
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4A
|
|||||||
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
|
github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0=
|
||||||
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
|
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||||
|
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
@@ -117,6 +119,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk
|
|||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
|
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||||
|
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
github.com/gin-contrib/gzip v1.0.1 h1:HQ8ENHODeLY7a4g1Au/46Z92bdGFl74OhxcZble9WJE=
|
github.com/gin-contrib/gzip v1.0.1 h1:HQ8ENHODeLY7a4g1Au/46Z92bdGFl74OhxcZble9WJE=
|
||||||
@@ -132,6 +136,13 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
|||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||||
|
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||||
|
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||||
|
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||||
|
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||||
|
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
@@ -150,6 +161,8 @@ github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGK
|
|||||||
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw=
|
github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw=
|
||||||
github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0=
|
github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0=
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
|
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
|
||||||
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
@@ -179,6 +192,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
|
|||||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||||
|
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
@@ -186,14 +201,19 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||||
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||||
|
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
|
||||||
|
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
||||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
||||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
@@ -244,6 +264,8 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
|||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||||
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
|
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
|
||||||
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/kelindar/bitmap v1.5.2 h1:XwX7CTvJtetQZ64zrOkApoZZHBJRkjE23NfqUALA/HE=
|
github.com/kelindar/bitmap v1.5.2 h1:XwX7CTvJtetQZ64zrOkApoZZHBJRkjE23NfqUALA/HE=
|
||||||
@@ -285,6 +307,8 @@ github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
|
|||||||
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
@@ -311,18 +335,22 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ
|
|||||||
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
|
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
|
||||||
github.com/mozillazg/go-httpheader v0.4.0 h1:aBn6aRXtFzyDLZ4VIRLsZbbJloagQfMnCiYgOq6hK4w=
|
github.com/mozillazg/go-httpheader v0.4.0 h1:aBn6aRXtFzyDLZ4VIRLsZbbJloagQfMnCiYgOq6hK4w=
|
||||||
github.com/mozillazg/go-httpheader v0.4.0/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA=
|
github.com/mozillazg/go-httpheader v0.4.0/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||||
github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y=
|
github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y=
|
||||||
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
|
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
|
||||||
github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y=
|
github.com/openimsdk/gomake v0.0.15-alpha.5 h1:eEZCEHm+NsmcO3onXZPIUbGFCYPYbsX5beV3ZyOsGhY=
|
||||||
github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
|
github.com/openimsdk/gomake v0.0.15-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
|
||||||
github.com/openimsdk/protocol v0.0.72-alpha.71 h1:R3utzOlqepaJWTAmnfJi4ccUM/XIoFasSyjQMOipM70=
|
github.com/openimsdk/protocol v0.0.73-alpha.12 h1:2NYawXeHChYUeSme6QJ9pOLh+Empce2WmwEtbP4JvKk=
|
||||||
github.com/openimsdk/protocol v0.0.72-alpha.71/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw=
|
github.com/openimsdk/protocol v0.0.73-alpha.12/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw=
|
||||||
github.com/openimsdk/tools v0.0.50-alpha.67 h1:K7kguqvPbjldHAi7pGhcG2ERkctCqG9ZFlteT7UKaxM=
|
github.com/openimsdk/tools v0.0.50-alpha.84 h1:jN60Ys/0edZjL/TDmm/5VSJFP4pGYRipkWqhILJbq/8=
|
||||||
github.com/openimsdk/tools v0.0.50-alpha.67/go.mod h1:B+oqV0zdewN7OiEHYJm+hW+8/Te7B8tHHgD8rK5ZLZk=
|
github.com/openimsdk/tools v0.0.50-alpha.84/go.mod h1:n2poR3asX1e1XZce4O+MOWAp+X02QJRFvhcLCXZdzRo=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||||
@@ -356,8 +384,8 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
|||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
@@ -379,8 +407,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
|
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
|
||||||
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
|
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
|
||||||
github.com/stathat/consistent v1.0.0 h1:ZFJ1QTRn8npNBKW065raSZ8xfOqhpb8vLOkfp4CcL/U=
|
|
||||||
github.com/stathat/consistent v1.0.0/go.mod h1:uajTPbgSygZBJ+V+0mY7meZ8i0XAcZs7AQ6V121XSxw=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
@@ -410,6 +436,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
|||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||||
@@ -449,8 +477,8 @@ go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
|||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
||||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||||
@@ -527,6 +555,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
|
|||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
||||||
|
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
@@ -548,6 +578,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||||
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -592,11 +624,14 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
@@ -607,7 +642,23 @@ gorm.io/gorm v1.25.8 h1:WAGEZ/aEcznN4D03laj8DKnehe1e9gYQAjW8xyPRdeo=
|
|||||||
gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0=
|
||||||
|
k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk=
|
||||||
|
k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
|
||||||
|
k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||||
|
k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc=
|
||||||
|
k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs=
|
||||||
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
|
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||||
|
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
||||||
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||||
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
stathat.com/c/consistent v1.0.0 h1:ezyc51EGcRPJUxfHGSgJjWzJdj3NiMU9pNfLNGiXV0c=
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||||
stathat.com/c/consistent v1.0.0/go.mod h1:QkzMWzcbB+yQBL2AttO6sgsQS/JSTapcDISJalmCDS0=
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||||
|
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||||
|
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||||
|
|||||||
@@ -114,3 +114,7 @@ func (o *FriendApi) GetIncrementalBlacks(c *gin.Context) {
|
|||||||
func (o *FriendApi) GetFullFriendUserIDs(c *gin.Context) {
|
func (o *FriendApi) GetFullFriendUserIDs(c *gin.Context) {
|
||||||
a2r.Call(c, relation.FriendClient.GetFullFriendUserIDs, o.Client)
|
a2r.Call(c, relation.FriendClient.GetFullFriendUserIDs, o.Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *FriendApi) GetSelfUnhandledApplyCount(c *gin.Context) {
|
||||||
|
a2r.Call(c, relation.FriendClient.GetSelfUnhandledApplyCount, o.Client)
|
||||||
|
}
|
||||||
|
|||||||
@@ -165,3 +165,7 @@ func (o *GroupApi) GetFullGroupMemberUserIDs(c *gin.Context) {
|
|||||||
func (o *GroupApi) GetFullJoinGroupIDs(c *gin.Context) {
|
func (o *GroupApi) GetFullJoinGroupIDs(c *gin.Context) {
|
||||||
a2r.Call(c, group.GroupClient.GetFullJoinGroupIDs, o.Client)
|
a2r.Call(c, group.GroupClient.GetFullJoinGroupIDs, o.Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o *GroupApi) GetGroupApplicationUnhandledCount(c *gin.Context) {
|
||||||
|
a2r.Call(c, group.GroupClient.GetGroupApplicationUnhandledCount, o.Client)
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -281,7 +281,7 @@ func (m *MessageApi) SendBusinessNotification(c *gin.Context) {
|
|||||||
IsSendMsg: false,
|
IsSendMsg: false,
|
||||||
ReliabilityLevel: 1,
|
ReliabilityLevel: 1,
|
||||||
UnreadCount: false,
|
UnreadCount: false,
|
||||||
}),
|
}, nil),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
respPb, err := m.Client.SendMsg(c, &sendMsgReq)
|
respPb, err := m.Client.SendMsg(c, &sendMsgReq)
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
|
|||||||
friendRouterGroup.POST("/update_friends", f.UpdateFriends)
|
friendRouterGroup.POST("/update_friends", f.UpdateFriends)
|
||||||
friendRouterGroup.POST("/get_incremental_friends", f.GetIncrementalFriends)
|
friendRouterGroup.POST("/get_incremental_friends", f.GetIncrementalFriends)
|
||||||
friendRouterGroup.POST("/get_full_friend_user_ids", f.GetFullFriendUserIDs)
|
friendRouterGroup.POST("/get_full_friend_user_ids", f.GetFullFriendUserIDs)
|
||||||
|
friendRouterGroup.POST("/get_self_unhandled_apply_count", f.GetSelfUnhandledApplyCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGroupApi(group.NewGroupClient(groupConn))
|
g := NewGroupApi(group.NewGroupClient(groupConn))
|
||||||
@@ -185,6 +186,7 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
|
|||||||
groupRouterGroup.POST("/get_incremental_group_members_batch", g.GetIncrementalGroupMemberBatch)
|
groupRouterGroup.POST("/get_incremental_group_members_batch", g.GetIncrementalGroupMemberBatch)
|
||||||
groupRouterGroup.POST("/get_full_group_member_user_ids", g.GetFullGroupMemberUserIDs)
|
groupRouterGroup.POST("/get_full_group_member_user_ids", g.GetFullGroupMemberUserIDs)
|
||||||
groupRouterGroup.POST("/get_full_join_group_ids", g.GetFullJoinGroupIDs)
|
groupRouterGroup.POST("/get_full_join_group_ids", g.GetFullJoinGroupIDs)
|
||||||
|
groupRouterGroup.POST("/get_group_application_unhandled_count", g.GetGroupApplicationUnhandledCount)
|
||||||
}
|
}
|
||||||
// certificate
|
// certificate
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ package msggateway
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
||||||
@@ -212,15 +213,19 @@ func (ws *WsServer) sendUserOnlineInfoToOtherNode(ctx context.Context, client *C
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if len(conns) == 0 || (len(conns) == 1 && ws.disCov.IsSelfNode(conns[0])) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
wg := errgroup.Group{}
|
wg := errgroup.Group{}
|
||||||
wg.SetLimit(concurrentRequest)
|
wg.SetLimit(concurrentRequest)
|
||||||
|
|
||||||
// Online push user online message to other node
|
// Online push user online message to other node
|
||||||
for _, v := range conns {
|
for _, v := range conns {
|
||||||
v := v
|
v := v
|
||||||
log.ZDebug(ctx, " sendUserOnlineInfoToOtherNode conn ", "target", v.Target())
|
log.ZDebug(ctx, "sendUserOnlineInfoToOtherNode conn")
|
||||||
if v.Target() == ws.disCov.GetSelfConnTarget() {
|
if ws.disCov.IsSelfNode(v) {
|
||||||
log.ZDebug(ctx, "Filter out this node", "node", v.Target())
|
log.ZDebug(ctx, "Filter out this node")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +236,7 @@ func (ws *WsServer) sendUserOnlineInfoToOtherNode(ctx context.Context, client *C
|
|||||||
PlatformID: int32(client.PlatformID), Token: client.token,
|
PlatformID: int32(client.PlatformID), Token: client.token,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "MultiTerminalLoginCheck err", err, "node", v.Target())
|
log.ZWarn(ctx, "MultiTerminalLoginCheck err", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -18,18 +18,20 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
|
||||||
"github.com/openimsdk/tools/discovery"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
"github.com/openimsdk/tools/discovery"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"github.com/go-redis/redis"
|
"github.com/go-redis/redis"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/tools/batcher"
|
"github.com/openimsdk/open-im-server/v3/pkg/tools/batcher"
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
@@ -38,7 +40,6 @@ import (
|
|||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/mcontext"
|
"github.com/openimsdk/tools/mcontext"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
"github.com/openimsdk/tools/utils/stringutil"
|
"github.com/openimsdk/tools/utils/stringutil"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
@@ -289,6 +290,7 @@ func (och *OnlineHistoryRedisConsumerHandler) handleMsg(ctx context.Context, key
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isNewConversation {
|
if isNewConversation {
|
||||||
|
ctx := storageList[0].ctx
|
||||||
switch msg.SessionType {
|
switch msg.SessionType {
|
||||||
case constant.ReadGroupChatType:
|
case constant.ReadGroupChatType:
|
||||||
log.ZDebug(ctx, "group chat first create conversation", "conversationID",
|
log.ZDebug(ctx, "group chat first create conversation", "conversationID",
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
pbmsg "github.com/openimsdk/protocol/msg"
|
pbmsg "github.com/openimsdk/protocol/msg"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -73,10 +73,14 @@ func (mc *OnlineHistoryMongoConsumerHandler) handleChatWs2Mongo(ctx context.Cont
|
|||||||
} else {
|
} else {
|
||||||
prommetrics.MsgInsertMongoSuccessCounter.Inc()
|
prommetrics.MsgInsertMongoSuccessCounter.Inc()
|
||||||
}
|
}
|
||||||
var seqs []int64
|
//var seqs []int64
|
||||||
for _, msg := range msgFromMQ.MsgData {
|
//for _, msg := range msgFromMQ.MsgData {
|
||||||
seqs = append(seqs, msg.Seq)
|
// seqs = append(seqs, msg.Seq)
|
||||||
}
|
//}
|
||||||
|
//if err := mc.msgTransferDatabase.DeleteMessagesFromCache(ctx, msgFromMQ.ConversationID, seqs); err != nil {
|
||||||
|
// log.ZError(ctx, "remove cache msg from redis err", err, "msg",
|
||||||
|
// msgFromMQ.MsgData, "conversationID", msgFromMQ.ConversationID)
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*OnlineHistoryMongoConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
func (*OnlineHistoryMongoConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/options"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/options"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
pbpush "github.com/openimsdk/protocol/push"
|
pbpush "github.com/openimsdk/protocol/push"
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
"github.com/openimsdk/tools/utils/jsonutil"
|
"github.com/openimsdk/tools/utils/jsonutil"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package push
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/openimsdk/protocol/msggateway"
|
"github.com/openimsdk/protocol/msggateway"
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/discovery"
|
"github.com/openimsdk/tools/discovery"
|
||||||
@@ -9,7 +11,6 @@ import (
|
|||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type OnlinePusher interface {
|
type OnlinePusher interface {
|
||||||
@@ -160,7 +161,7 @@ func (k *K8sStaticConsistentHash) GetConnsAndOnlinePush(ctx context.Context, msg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.ZDebug(ctx, "genUsers send hosts struct:", "usersHost", usersHost)
|
log.ZDebug(ctx, "genUsers send hosts struct:", "usersHost", usersHost)
|
||||||
var usersConns = make(map[*grpc.ClientConn][]string)
|
var usersConns = make(map[grpc.ClientConnInterface][]string)
|
||||||
for host, userIds := range usersHost {
|
for host, userIds := range usersHost {
|
||||||
tconn, _ := k.disCov.GetConn(ctx, host)
|
tconn, _ := k.disCov.GetConn(ctx, host)
|
||||||
usersConns[tconn] = userIds
|
usersConns[tconn] = userIds
|
||||||
|
|||||||
@@ -3,16 +3,18 @@ package push
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/options"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/options"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/webhook"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/webhook"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpccache"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpccache"
|
||||||
@@ -24,7 +26,6 @@ import (
|
|||||||
"github.com/openimsdk/tools/discovery"
|
"github.com/openimsdk/tools/discovery"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/mcontext"
|
"github.com/openimsdk/tools/mcontext"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
"github.com/openimsdk/tools/utils/jsonutil"
|
"github.com/openimsdk/tools/utils/jsonutil"
|
||||||
"github.com/openimsdk/tools/utils/timeutil"
|
"github.com/openimsdk/tools/utils/timeutil"
|
||||||
@@ -141,6 +142,7 @@ func (c *ConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession, claim s
|
|||||||
|
|
||||||
for msg := range claim.Messages() {
|
for msg := range claim.Messages() {
|
||||||
ctx := c.pushConsumerGroup.GetContextFromMsg(msg)
|
ctx := c.pushConsumerGroup.GetContextFromMsg(msg)
|
||||||
|
ctx = mcontext.WithOpUserIDContext(ctx, c.config.Share.IMAdminUserID[0])
|
||||||
c.handleMs2PsChat(ctx, msg.Value)
|
c.handleMs2PsChat(ctx, msg.Value)
|
||||||
sess.MarkMessage(msg, "")
|
sess.MarkMessage(msg, "")
|
||||||
}
|
}
|
||||||
@@ -152,24 +154,24 @@ func (c *ConsumerHandler) Push2User(ctx context.Context, userIDs []string, msg *
|
|||||||
log.ZInfo(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
|
log.ZInfo(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
|
||||||
defer func(duration time.Time) {
|
defer func(duration time.Time) {
|
||||||
t := time.Since(duration)
|
t := time.Since(duration)
|
||||||
log.ZInfo(ctx, "Get msg from msg_transfer And push msg", "msg", msg.String(), "time cost", t)
|
log.ZInfo(ctx, "Get msg from msg_transfer And push msg end", "msg", msg.String(), "time cost", t)
|
||||||
}(time.Now())
|
}(time.Now())
|
||||||
if err := c.webhookBeforeOnlinePush(ctx, &c.config.WebhooksConfig.BeforeOnlinePush, userIDs, msg); err != nil {
|
if err := c.webhookBeforeOnlinePush(ctx, &c.config.WebhooksConfig.BeforeOnlinePush, userIDs, msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "webhookBeforeOnlinePush end")
|
|
||||||
|
|
||||||
wsResults, err := c.GetConnsAndOnlinePush(ctx, msg, userIDs)
|
wsResults, err := c.GetConnsAndOnlinePush(ctx, msg, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.ZInfo(ctx, "single and notification push result", "result", wsResults, "msg", msg, "push_to_userID", userIDs)
|
log.ZDebug(ctx, "single and notification push result", "result", wsResults, "msg", msg, "push_to_userID", userIDs)
|
||||||
|
log.ZInfo(ctx, "single and notification push end")
|
||||||
|
|
||||||
if !c.shouldPushOffline(ctx, msg) {
|
if !c.shouldPushOffline(ctx, msg) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "shouldPushOffline end")
|
log.ZInfo(ctx, "pushOffline start")
|
||||||
|
|
||||||
for _, v := range wsResults {
|
for _, v := range wsResults {
|
||||||
//message sender do not need offline push
|
//message sender do not need offline push
|
||||||
@@ -188,14 +190,14 @@ func (c *ConsumerHandler) Push2User(ctx context.Context, userIDs []string, msg *
|
|||||||
if err = c.webhookBeforeOfflinePush(ctx, &c.config.WebhooksConfig.BeforeOfflinePush, needOfflinePushUserID, msg, &offlinePushUserID); err != nil {
|
if err = c.webhookBeforeOfflinePush(ctx, &c.config.WebhooksConfig.BeforeOfflinePush, needOfflinePushUserID, msg, &offlinePushUserID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "webhookBeforeOfflinePush end")
|
|
||||||
|
|
||||||
if len(offlinePushUserID) > 0 {
|
if len(offlinePushUserID) > 0 {
|
||||||
needOfflinePushUserID = offlinePushUserID
|
needOfflinePushUserID = offlinePushUserID
|
||||||
}
|
}
|
||||||
err = c.offlinePushMsg(ctx, msg, needOfflinePushUserID)
|
err = c.offlinePushMsg(ctx, msg, needOfflinePushUserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "offlinePushMsg failed", err, "needOfflinePushUserID", needOfflinePushUserID, "msg", msg)
|
log.ZDebug(ctx, "offlinePushMsg failed", err, "needOfflinePushUserID", needOfflinePushUserID, "msg", msg)
|
||||||
|
log.ZWarn(ctx, "offlinePushMsg failed", err, "needOfflinePushUserID length", len(needOfflinePushUserID), "msg", msg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +209,10 @@ func (c *ConsumerHandler) shouldPushOffline(_ context.Context, msg *sdkws.MsgDat
|
|||||||
if !isOfflinePush {
|
if !isOfflinePush {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if msg.ContentType == constant.SignalingNotification {
|
switch msg.ContentType {
|
||||||
|
case constant.RoomParticipantsConnectedNotification:
|
||||||
|
return false
|
||||||
|
case constant.RoomParticipantsDisconnectedNotification:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -250,26 +255,24 @@ func (c *ConsumerHandler) Push2Group(ctx context.Context, groupID string, msg *s
|
|||||||
&pushToUserIDs); err != nil {
|
&pushToUserIDs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "webhookBeforeGroupOnlinePush end")
|
|
||||||
|
|
||||||
err = c.groupMessagesHandler(ctx, groupID, &pushToUserIDs, msg)
|
err = c.groupMessagesHandler(ctx, groupID, &pushToUserIDs, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "groupMessagesHandler end")
|
|
||||||
|
|
||||||
wsResults, err := c.GetConnsAndOnlinePush(ctx, msg, pushToUserIDs)
|
wsResults, err := c.GetConnsAndOnlinePush(ctx, msg, pushToUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.ZInfo(ctx, "group push result", "result", wsResults, "msg", msg)
|
log.ZDebug(ctx, "group push result", "result", wsResults, "msg", msg)
|
||||||
|
log.ZInfo(ctx, "online group push end")
|
||||||
|
|
||||||
if !c.shouldPushOffline(ctx, msg) {
|
if !c.shouldPushOffline(ctx, msg) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
needOfflinePushUserIDs := c.onlinePusher.GetOnlinePushFailedUserIDs(ctx, msg, wsResults, &pushToUserIDs)
|
needOfflinePushUserIDs := c.onlinePusher.GetOnlinePushFailedUserIDs(ctx, msg, wsResults, &pushToUserIDs)
|
||||||
log.ZInfo(ctx, "GetOnlinePushFailedUserIDs end")
|
|
||||||
//filter some user, like don not disturb or don't need offline push etc.
|
//filter some user, like don not disturb or don't need offline push etc.
|
||||||
needOfflinePushUserIDs, err = c.filterGroupMessageOfflinePush(ctx, groupID, msg, needOfflinePushUserIDs)
|
needOfflinePushUserIDs, err = c.filterGroupMessageOfflinePush(ctx, groupID, msg, needOfflinePushUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -297,9 +300,11 @@ func (c *ConsumerHandler) asyncOfflinePush(ctx context.Context, needOfflinePushU
|
|||||||
needOfflinePushUserIDs = offlinePushUserIDs
|
needOfflinePushUserIDs = offlinePushUserIDs
|
||||||
}
|
}
|
||||||
if err := c.pushDatabase.MsgToOfflinePushMQ(ctx, conversationutil.GenConversationUniqueKeyForSingle(msg.SendID, msg.RecvID), needOfflinePushUserIDs, msg); err != nil {
|
if err := c.pushDatabase.MsgToOfflinePushMQ(ctx, conversationutil.GenConversationUniqueKeyForSingle(msg.SendID, msg.RecvID), needOfflinePushUserIDs, msg); err != nil {
|
||||||
log.ZError(ctx, "Msg To OfflinePush MQ error", err, "needOfflinePushUserIDs",
|
log.ZDebug(ctx, "Msg To OfflinePush MQ error", err, "needOfflinePushUserIDs",
|
||||||
needOfflinePushUserIDs, "msg", msg)
|
needOfflinePushUserIDs, "msg", msg)
|
||||||
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
log.ZWarn(ctx, "Msg To OfflinePush MQ error", err, "needOfflinePushUserIDs length",
|
||||||
|
len(needOfflinePushUserIDs), "msg", msg)
|
||||||
|
prommetrics.GroupChatMsgProcessFailedCounter.Inc()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, v := range conns {
|
for _, v := range conns {
|
||||||
log.ZDebug(ctx, "forceKickOff", "conn", v.Target())
|
log.ZDebug(ctx, "forceKickOff", "userID", userID, "platformID", platformID)
|
||||||
client := msggateway.NewMsgGatewayClient(v)
|
client := msggateway.NewMsgGatewayClient(v)
|
||||||
kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID}
|
kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID}
|
||||||
_, err := client.KickUserOffline(ctx, kickReq)
|
_, err := client.KickUserOffline(ctx, kickReq)
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ package conversation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
|
||||||
@@ -771,7 +772,7 @@ func (c *conversationServer) ClearUserConversationMsg(ctx context.Context, req *
|
|||||||
if conversation.IsMsgDestruct == false || conversation.MsgDestructTime == 0 {
|
if conversation.IsMsgDestruct == false || conversation.MsgDestructTime == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
seq, err := c.msgClient.GetLastMessageSeqByTime(ctx, conversation.ConversationID, req.Timestamp-conversation.MsgDestructTime)
|
seq, err := c.msgClient.GetLastMessageSeqByTime(ctx, conversation.ConversationID, req.Timestamp-(conversation.MsgDestructTime*1000))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,21 +16,22 @@ package conversation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/notification"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
"github.com/openimsdk/protocol/msg"
|
"github.com/openimsdk/protocol/msg"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/notification"
|
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConversationNotificationSender struct {
|
type ConversationNotificationSender struct {
|
||||||
*rpcclient.NotificationSender
|
*notification.NotificationSender
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConversationNotificationSender(conf *config.Notification, msgClient *rpcli.MsgClient) *ConversationNotificationSender {
|
func NewConversationNotificationSender(conf *config.Notification, msgClient *rpcli.MsgClient) *ConversationNotificationSender {
|
||||||
return &ConversationNotificationSender{rpcclient.NewNotificationSender(conf, rpcclient.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
return &ConversationNotificationSender{notification.NewNotificationSender(conf, notification.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
||||||
return msgClient.SendMsg(ctx, req)
|
return msgClient.SendMsg(ctx, req)
|
||||||
}))}
|
}))}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ func (s *groupServer) GetGroupInfoCache(ctx context.Context, req *pbgroup.GetGro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) GetGroupMemberCache(ctx context.Context, req *pbgroup.GetGroupMemberCacheReq) (*pbgroup.GetGroupMemberCacheResp, error) {
|
func (s *groupServer) GetGroupMemberCache(ctx context.Context, req *pbgroup.GetGroupMemberCacheReq) (*pbgroup.GetGroupMemberCacheResp, error) {
|
||||||
|
if err := s.checkAdminOrInGroup(ctx, req.GroupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
members, err := s.db.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID)
|
members, err := s.db.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package group
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
pbgroup "github.com/openimsdk/protocol/group"
|
pbgroup "github.com/openimsdk/protocol/group"
|
||||||
@@ -55,41 +56,52 @@ func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[s
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateGroupInfoExMap(ctx context.Context, group *pbgroup.SetGroupInfoExReq) (map[string]any, error) {
|
func UpdateGroupInfoExMap(ctx context.Context, group *pbgroup.SetGroupInfoExReq) (m map[string]any, normalFlag, groupNameFlag, notificationFlag bool, err error) {
|
||||||
m := make(map[string]any)
|
m = make(map[string]any)
|
||||||
|
|
||||||
if group.GroupName != nil {
|
if group.GroupName != nil {
|
||||||
if group.GroupName.Value != "" {
|
if strings.TrimSpace(group.GroupName.Value) != "" {
|
||||||
m["group_name"] = group.GroupName.Value
|
m["group_name"] = group.GroupName.Value
|
||||||
|
groupNameFlag = true
|
||||||
} else {
|
} else {
|
||||||
return nil, errs.ErrArgs.WrapMsg("group name is empty")
|
return nil, normalFlag, notificationFlag, groupNameFlag, errs.ErrArgs.WrapMsg("group name is empty")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if group.Notification != nil {
|
if group.Notification != nil {
|
||||||
|
notificationFlag = true
|
||||||
|
group.Notification.Value = strings.TrimSpace(group.Notification.Value) // if Notification only contains spaces, set it to empty string
|
||||||
|
|
||||||
m["notification"] = group.Notification.Value
|
m["notification"] = group.Notification.Value
|
||||||
m["notification_update_time"] = time.Now()
|
|
||||||
m["notification_user_id"] = mcontext.GetOpUserID(ctx)
|
m["notification_user_id"] = mcontext.GetOpUserID(ctx)
|
||||||
|
m["notification_update_time"] = time.Now()
|
||||||
}
|
}
|
||||||
if group.Introduction != nil {
|
if group.Introduction != nil {
|
||||||
m["introduction"] = group.Introduction.Value
|
m["introduction"] = group.Introduction.Value
|
||||||
|
normalFlag = true
|
||||||
}
|
}
|
||||||
if group.FaceURL != nil {
|
if group.FaceURL != nil {
|
||||||
m["face_url"] = group.FaceURL.Value
|
m["face_url"] = group.FaceURL.Value
|
||||||
|
normalFlag = true
|
||||||
}
|
}
|
||||||
if group.NeedVerification != nil {
|
if group.NeedVerification != nil {
|
||||||
m["need_verification"] = group.NeedVerification.Value
|
m["need_verification"] = group.NeedVerification.Value
|
||||||
|
normalFlag = true
|
||||||
}
|
}
|
||||||
if group.LookMemberInfo != nil {
|
if group.LookMemberInfo != nil {
|
||||||
m["look_member_info"] = group.LookMemberInfo.Value
|
m["look_member_info"] = group.LookMemberInfo.Value
|
||||||
|
normalFlag = true
|
||||||
}
|
}
|
||||||
if group.ApplyMemberFriend != nil {
|
if group.ApplyMemberFriend != nil {
|
||||||
m["apply_member_friend"] = group.ApplyMemberFriend.Value
|
m["apply_member_friend"] = group.ApplyMemberFriend.Value
|
||||||
|
normalFlag = true
|
||||||
}
|
}
|
||||||
if group.Ex != nil {
|
if group.Ex != nil {
|
||||||
m["ex"] = group.Ex.Value
|
m["ex"] = group.Ex.Value
|
||||||
|
normalFlag = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return m, nil
|
return m, normalFlag, groupNameFlag, notificationFlag, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateGroupStatusMap(status int) map[string]any {
|
func UpdateGroupStatusMap(status int) map[string]any {
|
||||||
|
|||||||
+148
-68
@@ -17,13 +17,14 @@ package group
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/common"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/common"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
|
||||||
@@ -289,13 +290,14 @@ func (g *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.notification.GroupCreatedNotification(ctx, tips)
|
g.notification.GroupCreatedNotification(ctx, tips, req.SendMessage)
|
||||||
|
|
||||||
if req.GroupInfo.Notification != "" {
|
if req.GroupInfo.Notification != "" {
|
||||||
|
notificationFlag := true
|
||||||
g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{
|
g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{
|
||||||
Group: tips.Group,
|
Group: tips.Group,
|
||||||
OpUser: tips.OpUser,
|
OpUser: tips.OpUser,
|
||||||
})
|
}, ¬ificationFlag)
|
||||||
}
|
}
|
||||||
|
|
||||||
reqCallBackAfter := &pbgroup.CreateGroupReq{
|
reqCallBackAfter := &pbgroup.CreateGroupReq{
|
||||||
@@ -393,6 +395,8 @@ func (g *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
if err := g.PopulateGroupMember(ctx, groupMember); err != nil {
|
if err := g.PopulateGroupMember(ctx, groupMember); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
opUserID = mcontext.GetOpUserID(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := g.webhookBeforeInviteUserToGroup(ctx, &g.config.WebhooksConfig.BeforeInviteUserToGroup, req); err != nil && err != servererrs.ErrCallbackContinue {
|
if err := g.webhookBeforeInviteUserToGroup(ctx, &g.config.WebhooksConfig.BeforeInviteUserToGroup, req); err != nil && err != servererrs.ErrCallbackContinue {
|
||||||
@@ -422,12 +426,13 @@ func (g *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
ReqMessage: request.ReqMsg,
|
ReqMessage: request.ReqMsg,
|
||||||
JoinSource: request.JoinSource,
|
JoinSource: request.JoinSource,
|
||||||
InviterUserID: request.InviterUserID,
|
InviterUserID: request.InviterUserID,
|
||||||
})
|
}, request)
|
||||||
}
|
}
|
||||||
return &pbgroup.InviteUserToGroupResp{}, nil
|
return &pbgroup.InviteUserToGroupResp{}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var groupMembers []*model.GroupMember
|
var groupMembers []*model.GroupMember
|
||||||
for _, userID := range req.InvitedUserIDs {
|
for _, userID := range req.InvitedUserIDs {
|
||||||
member := &model.GroupMember{
|
member := &model.GroupMember{
|
||||||
@@ -448,12 +453,25 @@ func (g *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := g.db.CreateGroup(ctx, nil, groupMembers); err != nil {
|
const singleQuantity = 50
|
||||||
return nil, err
|
for start := 0; start < len(groupMembers); start += singleQuantity {
|
||||||
}
|
end := start + singleQuantity
|
||||||
|
if end > len(groupMembers) {
|
||||||
|
end = len(groupMembers)
|
||||||
|
}
|
||||||
|
currentMembers := groupMembers[start:end]
|
||||||
|
|
||||||
if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, opUserID, req.InvitedUserIDs...); err != nil {
|
if err := g.db.CreateGroup(ctx, nil, currentMembers); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
userIDs := datautil.Slice(currentMembers, func(e *model.GroupMember) string {
|
||||||
|
return e.UserID
|
||||||
|
})
|
||||||
|
|
||||||
|
if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, req.SendMessage, opUserID, userIDs...); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &pbgroup.InviteUserToGroupResp{}, nil
|
return &pbgroup.InviteUserToGroupResp{}, nil
|
||||||
}
|
}
|
||||||
@@ -473,7 +491,25 @@ func (g *groupServer) GetGroupAllMember(ctx context.Context, req *pbgroup.GetGro
|
|||||||
return &resp, nil
|
return &resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *groupServer) checkAdminOrInGroup(ctx context.Context, groupID string) error {
|
||||||
|
if authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
opUserID := mcontext.GetOpUserID(ctx)
|
||||||
|
members, err := g.db.FindGroupMembers(ctx, groupID, []string{opUserID})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(members) == 0 {
|
||||||
|
return errs.ErrNoPermission.WrapMsg("op user not in group")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (g *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGroupMemberListReq) (*pbgroup.GetGroupMemberListResp, error) {
|
func (g *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGroupMemberListReq) (*pbgroup.GetGroupMemberListResp, error) {
|
||||||
|
if err := g.checkAdminOrInGroup(ctx, req.GroupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
total int64
|
total int64
|
||||||
members []*model.GroupMember
|
members []*model.GroupMember
|
||||||
@@ -482,7 +518,7 @@ func (g *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGr
|
|||||||
if req.Keyword == "" {
|
if req.Keyword == "" {
|
||||||
total, members, err = g.db.PageGetGroupMember(ctx, req.GroupID, req.Pagination)
|
total, members, err = g.db.PageGetGroupMember(ctx, req.GroupID, req.Pagination)
|
||||||
} else {
|
} else {
|
||||||
members, err = g.db.FindGroupMemberAll(ctx, req.GroupID)
|
total, members, err = g.db.SearchGroupMember(ctx, req.GroupID, req.Keyword, req.Pagination)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -490,27 +526,6 @@ func (g *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGr
|
|||||||
if err := g.PopulateGroupMember(ctx, members...); err != nil {
|
if err := g.PopulateGroupMember(ctx, members...); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if req.Keyword != "" {
|
|
||||||
groupMembers := make([]*model.GroupMember, 0)
|
|
||||||
for _, member := range members {
|
|
||||||
if member.UserID == req.Keyword {
|
|
||||||
groupMembers = append(groupMembers, member)
|
|
||||||
total++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if member.Nickname == req.Keyword {
|
|
||||||
groupMembers = append(groupMembers, member)
|
|
||||||
total++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
members := datautil.Paginate(groupMembers, int(req.Pagination.GetPageNumber()), int(req.Pagination.GetShowNumber()))
|
|
||||||
return &pbgroup.GetGroupMemberListResp{
|
|
||||||
Total: uint32(total),
|
|
||||||
Members: datautil.Batch(convert.Db2PbGroupMember, members),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
return &pbgroup.GetGroupMemberListResp{
|
return &pbgroup.GetGroupMemberListResp{
|
||||||
Total: uint32(total),
|
Total: uint32(total),
|
||||||
Members: datautil.Batch(convert.Db2PbGroupMember, members),
|
Members: datautil.Batch(convert.Db2PbGroupMember, members),
|
||||||
@@ -618,7 +633,7 @@ func (g *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGrou
|
|||||||
for _, userID := range req.KickedUserIDs {
|
for _, userID := range req.KickedUserIDs {
|
||||||
tips.KickedUserList = append(tips.KickedUserList, convert.Db2PbGroupMember(memberMap[userID]))
|
tips.KickedUserList = append(tips.KickedUserList, convert.Db2PbGroupMember(memberMap[userID]))
|
||||||
}
|
}
|
||||||
g.notification.MemberKickedNotification(ctx, tips)
|
g.notification.MemberKickedNotification(ctx, tips, req.SendMessage)
|
||||||
if err := g.deleteMemberAndSetConversationSeq(ctx, req.GroupID, req.KickedUserIDs); err != nil {
|
if err := g.deleteMemberAndSetConversationSeq(ctx, req.GroupID, req.KickedUserIDs); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -634,6 +649,9 @@ func (g *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbgroup.GetG
|
|||||||
if req.GroupID == "" {
|
if req.GroupID == "" {
|
||||||
return nil, errs.ErrArgs.WrapMsg("groupID empty")
|
return nil, errs.ErrArgs.WrapMsg("groupID empty")
|
||||||
}
|
}
|
||||||
|
if err := g.checkAdminOrInGroup(ctx, req.GroupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
members, err := g.getGroupMembersInfo(ctx, req.GroupID, req.UserIDs)
|
members, err := g.getGroupMembersInfo(ctx, req.GroupID, req.UserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -661,15 +679,34 @@ func (g *groupServer) getGroupMembersInfo(ctx context.Context, groupID string, u
|
|||||||
|
|
||||||
// GetGroupApplicationList handles functions that get a list of group requests.
|
// GetGroupApplicationList handles functions that get a list of group requests.
|
||||||
func (g *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup.GetGroupApplicationListReq) (*pbgroup.GetGroupApplicationListResp, error) {
|
func (g *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup.GetGroupApplicationListReq) (*pbgroup.GetGroupApplicationListResp, error) {
|
||||||
groupIDs, err := g.db.FindUserManagedGroupID(ctx, req.FromUserID)
|
var (
|
||||||
if err != nil {
|
groupIDs []string
|
||||||
return nil, err
|
err error
|
||||||
|
)
|
||||||
|
if len(req.GroupIDs) == 0 {
|
||||||
|
groupIDs, err = g.db.FindUserManagedGroupID(ctx, req.FromUserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
req.GroupIDs = datautil.Distinct(req.GroupIDs)
|
||||||
|
if !authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) {
|
||||||
|
for _, groupID := range req.GroupIDs {
|
||||||
|
if err := g.CheckGroupAdmin(ctx, groupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groupIDs = req.GroupIDs
|
||||||
}
|
}
|
||||||
resp := &pbgroup.GetGroupApplicationListResp{}
|
resp := &pbgroup.GetGroupApplicationListResp{}
|
||||||
if len(groupIDs) == 0 {
|
if len(groupIDs) == 0 {
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
total, groupRequests, err := g.db.PageGroupRequest(ctx, groupIDs, req.Pagination)
|
handleResults := datautil.Slice(req.HandleResults, func(e int32) int {
|
||||||
|
return int(e)
|
||||||
|
})
|
||||||
|
total, groupRequests, err := g.db.PageGroupRequest(ctx, groupIDs, handleResults, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -734,6 +771,23 @@ func (g *groupServer) GetGroupsInfo(ctx context.Context, req *pbgroup.GetGroupsI
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *groupServer) GetGroupApplicationUnhandledCount(ctx context.Context, req *pbgroup.GetGroupApplicationUnhandledCountReq) (*pbgroup.GetGroupApplicationUnhandledCountResp, error) {
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.UserID, g.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
groupIDs, err := g.db.FindUserManagedGroupID(ctx, req.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
count, err := g.db.GetGroupApplicationUnhandledCount(ctx, groupIDs, req.Time)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pbgroup.GetGroupApplicationUnhandledCountResp{
|
||||||
|
Count: count,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (g *groupServer) getGroupsInfo(ctx context.Context, groupIDs []string) ([]*sdkws.GroupInfo, error) {
|
func (g *groupServer) getGroupsInfo(ctx context.Context, groupIDs []string) ([]*sdkws.GroupInfo, error) {
|
||||||
if len(groupIDs) == 0 {
|
if len(groupIDs) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -827,8 +881,14 @@ func (g *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup
|
|||||||
if member == nil {
|
if member == nil {
|
||||||
log.ZDebug(ctx, "GroupApplicationResponse", "member is nil")
|
log.ZDebug(ctx, "GroupApplicationResponse", "member is nil")
|
||||||
} else {
|
} else {
|
||||||
if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, groupRequest.InviterUserID, req.FromUserID); err != nil {
|
if groupRequest.InviterUserID == "" {
|
||||||
return nil, err
|
if err = g.notification.MemberEnterNotification(ctx, req.GroupID, req.FromUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, nil, groupRequest.InviterUserID, req.FromUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case constant.GroupResponseRefuse:
|
case constant.GroupResponseRefuse:
|
||||||
@@ -909,7 +969,7 @@ func (g *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
if err = g.db.CreateGroupRequest(ctx, []*model.GroupRequest{&groupRequest}); err != nil {
|
if err = g.db.CreateGroupRequest(ctx, []*model.GroupRequest{&groupRequest}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
g.notification.JoinGroupApplicationNotification(ctx, req)
|
g.notification.JoinGroupApplicationNotification(ctx, req, &groupRequest)
|
||||||
return &pbgroup.JoinGroupResp{}, nil
|
return &pbgroup.JoinGroupResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1030,7 +1090,8 @@ func (g *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf
|
|||||||
log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation)
|
log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser})
|
notficationFlag := true
|
||||||
|
g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}, ¬ficationFlag)
|
||||||
}
|
}
|
||||||
if req.GroupInfoForSet.GroupName != "" {
|
if req.GroupInfoForSet.GroupName != "" {
|
||||||
num--
|
num--
|
||||||
@@ -1091,7 +1152,7 @@ func (g *groupServer) SetGroupInfoEx(ctx context.Context, req *pbgroup.SetGroupI
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedData, err := UpdateGroupInfoExMap(ctx, req)
|
updatedData, normalFlag, groupNameFlag, notificationFlag, err := UpdateGroupInfoExMap(ctx, req)
|
||||||
if len(updatedData) == 0 {
|
if len(updatedData) == 0 {
|
||||||
return &pbgroup.SetGroupInfoExResp{}, nil
|
return &pbgroup.SetGroupInfoExResp{}, nil
|
||||||
}
|
}
|
||||||
@@ -1119,41 +1180,38 @@ func (g *groupServer) SetGroupInfoEx(ctx context.Context, req *pbgroup.SetGroupI
|
|||||||
tips.OpUser = g.groupMemberDB2PB(opMember, 0)
|
tips.OpUser = g.groupMemberDB2PB(opMember, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
num := len(updatedData)
|
if notificationFlag {
|
||||||
|
|
||||||
if req.Notification != nil {
|
|
||||||
num -= 3
|
|
||||||
|
|
||||||
if req.Notification.Value != "" {
|
if req.Notification.Value != "" {
|
||||||
func() {
|
conversation := &pbconversation.ConversationReq{
|
||||||
conversation := &pbconversation.ConversationReq{
|
ConversationID: msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, req.GroupID),
|
||||||
ConversationID: msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, req.GroupID),
|
ConversationType: constant.ReadGroupChatType,
|
||||||
ConversationType: constant.ReadGroupChatType,
|
GroupID: req.GroupID,
|
||||||
GroupID: req.GroupID,
|
}
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := g.GetGroupMemberUserIDs(ctx, &pbgroup.GetGroupMemberUserIDsReq{GroupID: req.GroupID})
|
resp, err := g.GetGroupMemberUserIDs(ctx, &pbgroup.GetGroupMemberUserIDsReq{GroupID: req.GroupID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "GetGroupMemberIDs is failed.", err)
|
log.ZWarn(ctx, "GetGroupMemberIDs is failed.", err)
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification}
|
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.GroupNotification}
|
||||||
if err := g.conversationClient.SetConversations(ctx, resp.UserIDs, conversation); err != nil {
|
if err := g.conversationClient.SetConversations(ctx, resp.UserIDs, conversation); err != nil {
|
||||||
log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation)
|
log.ZWarn(ctx, "SetConversations", err, "UserIDs", resp.UserIDs, "conversation", conversation)
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
|
|
||||||
g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser})
|
g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}, ¬ificationFlag)
|
||||||
|
} else {
|
||||||
|
notificationFlag = false
|
||||||
|
g.notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser}, ¬ificationFlag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.GroupName != nil {
|
if groupNameFlag {
|
||||||
num--
|
|
||||||
g.notification.GroupInfoSetNameNotification(ctx, &sdkws.GroupInfoSetNameTips{Group: tips.Group, OpUser: tips.OpUser})
|
g.notification.GroupInfoSetNameNotification(ctx, &sdkws.GroupInfoSetNameTips{Group: tips.Group, OpUser: tips.OpUser})
|
||||||
}
|
}
|
||||||
|
|
||||||
if num > 0 {
|
// if updatedData > 0, send the normal notification
|
||||||
|
if normalFlag {
|
||||||
g.notification.GroupInfoSetNotification(ctx, tips)
|
g.notification.GroupInfoSetNotification(ctx, tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1275,6 +1333,9 @@ func (g *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbgroup.GetGroupMembersCMSReq) (*pbgroup.GetGroupMembersCMSResp, error) {
|
func (g *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbgroup.GetGroupMembersCMSReq) (*pbgroup.GetGroupMembersCMSResp, error) {
|
||||||
|
if err := g.checkAdminOrInGroup(ctx, req.GroupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
total, members, err := g.db.SearchGroupMember(ctx, req.UserName, req.GroupID, req.Pagination)
|
total, members, err := g.db.SearchGroupMember(ctx, req.UserName, req.GroupID, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1295,7 +1356,10 @@ func (g *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbgrou
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
total, requests, err := g.db.PageGroupRequestUser(ctx, req.UserID, req.Pagination)
|
handleResults := datautil.Slice(req.HandleResults, func(e int32) int {
|
||||||
|
return int(e)
|
||||||
|
})
|
||||||
|
total, requests, err := g.db.PageGroupRequestUser(ctx, req.UserID, req.GroupIDs, handleResults, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1373,7 +1437,7 @@ func (g *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGrou
|
|||||||
if mcontext.GetOpUserID(ctx) == owner.UserID {
|
if mcontext.GetOpUserID(ctx) == owner.UserID {
|
||||||
tips.OpUser = g.groupMemberDB2PB(owner, 0)
|
tips.OpUser = g.groupMemberDB2PB(owner, 0)
|
||||||
}
|
}
|
||||||
g.notification.GroupDismissedNotification(ctx, tips)
|
g.notification.GroupDismissedNotification(ctx, tips, req.SendMessage)
|
||||||
}
|
}
|
||||||
membersID, err := g.db.FindGroupMemberUserID(ctx, group.GroupID)
|
membersID, err := g.db.FindGroupMemberUserID(ctx, group.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1650,6 +1714,11 @@ func (g *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbgroup.Get
|
|||||||
if datautil.Duplicate(req.GroupIDs) {
|
if datautil.Duplicate(req.GroupIDs) {
|
||||||
return nil, errs.ErrArgs.WrapMsg("groupIDs duplicate")
|
return nil, errs.ErrArgs.WrapMsg("groupIDs duplicate")
|
||||||
}
|
}
|
||||||
|
for _, groupID := range req.GroupIDs {
|
||||||
|
if err := g.checkAdminOrInGroup(ctx, groupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
groups, err := g.db.FindGroup(ctx, req.GroupIDs)
|
groups, err := g.db.FindGroup(ctx, req.GroupIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1678,6 +1747,9 @@ func (g *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbgroup.Ge
|
|||||||
if len(req.GroupIDs) == 0 {
|
if len(req.GroupIDs) == 0 {
|
||||||
return nil, errs.ErrArgs.WrapMsg("groupIDs empty")
|
return nil, errs.ErrArgs.WrapMsg("groupIDs empty")
|
||||||
}
|
}
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.UserID, g.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
members, err := g.db.FindGroupMemberUser(ctx, req.GroupIDs, req.UserID)
|
members, err := g.db.FindGroupMemberUser(ctx, req.GroupIDs, req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1697,6 +1769,11 @@ func (g *groupServer) GetGroupMemberUserIDs(ctx context.Context, req *pbgroup.Ge
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if !authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) {
|
||||||
|
if !datautil.Contain(mcontext.GetOpUserID(ctx), userIDs...) {
|
||||||
|
return nil, errs.ErrNoPermission.WrapMsg("opUser no permission")
|
||||||
|
}
|
||||||
|
}
|
||||||
return &pbgroup.GetGroupMemberUserIDsResp{
|
return &pbgroup.GetGroupMemberUserIDsResp{
|
||||||
UserIDs: userIDs,
|
UserIDs: userIDs,
|
||||||
}, nil
|
}, nil
|
||||||
@@ -1706,6 +1783,9 @@ func (g *groupServer) GetGroupMemberRoleLevel(ctx context.Context, req *pbgroup.
|
|||||||
if len(req.RoleLevels) == 0 {
|
if len(req.RoleLevels) == 0 {
|
||||||
return nil, errs.ErrArgs.WrapMsg("RoleLevels empty")
|
return nil, errs.ErrArgs.WrapMsg("RoleLevels empty")
|
||||||
}
|
}
|
||||||
|
if err := g.checkAdminOrInGroup(ctx, req.GroupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
members, err := g.db.FindGroupMemberRoleLevels(ctx, req.GroupID, req.RoleLevels)
|
members, err := g.db.FindGroupMemberRoleLevels(ctx, req.GroupID, req.RoleLevels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
@@ -52,11 +53,11 @@ const (
|
|||||||
|
|
||||||
func NewNotificationSender(db controller.GroupDatabase, config *Config, userClient *rpcli.UserClient, msgClient *rpcli.MsgClient, conversationClient *rpcli.ConversationClient) *NotificationSender {
|
func NewNotificationSender(db controller.GroupDatabase, config *Config, userClient *rpcli.UserClient, msgClient *rpcli.MsgClient, conversationClient *rpcli.ConversationClient) *NotificationSender {
|
||||||
return &NotificationSender{
|
return &NotificationSender{
|
||||||
NotificationSender: rpcclient.NewNotificationSender(&config.NotificationConfig,
|
NotificationSender: notification.NewNotificationSender(&config.NotificationConfig,
|
||||||
rpcclient.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
notification.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
||||||
return msgClient.SendMsg(ctx, req)
|
return msgClient.SendMsg(ctx, req)
|
||||||
}),
|
}),
|
||||||
rpcclient.WithUserRpcClient(userClient.GetUserInfo),
|
notification.WithUserRpcClient(userClient.GetUserInfo),
|
||||||
),
|
),
|
||||||
getUsersInfo: func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error) {
|
getUsersInfo: func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error) {
|
||||||
users, err := userClient.GetUsersInfo(ctx, userIDs)
|
users, err := userClient.GetUsersInfo(ctx, userIDs)
|
||||||
@@ -73,7 +74,7 @@ func NewNotificationSender(db controller.GroupDatabase, config *Config, userClie
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NotificationSender struct {
|
type NotificationSender struct {
|
||||||
*rpcclient.NotificationSender
|
*notification.NotificationSender
|
||||||
getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error)
|
getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error)
|
||||||
db controller.GroupDatabase
|
db controller.GroupDatabase
|
||||||
config *Config
|
config *Config
|
||||||
@@ -233,17 +234,17 @@ func (g *NotificationSender) groupMemberDB2PB(member *model.GroupMember, appMang
|
|||||||
return result, nil
|
return result, nil
|
||||||
} */
|
} */
|
||||||
|
|
||||||
func (g *NotificationSender) fillOpUser(ctx context.Context, opUser **sdkws.GroupMemberFullInfo, groupID string) (err error) {
|
func (g *NotificationSender) fillOpUser(ctx context.Context, targetUser **sdkws.GroupMemberFullInfo, groupID string) (err error) {
|
||||||
return g.fillOpUserByUserID(ctx, mcontext.GetOpUserID(ctx), opUser, groupID)
|
return g.fillUserByUserID(ctx, mcontext.GetOpUserID(ctx), targetUser, groupID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID string, opUser **sdkws.GroupMemberFullInfo, groupID string) error {
|
func (g *NotificationSender) fillUserByUserID(ctx context.Context, userID string, targetUser **sdkws.GroupMemberFullInfo, groupID string) error {
|
||||||
if opUser == nil {
|
if targetUser == nil {
|
||||||
return errs.ErrInternalServer.WrapMsg("**sdkws.GroupMemberFullInfo is nil")
|
return errs.ErrInternalServer.WrapMsg("**sdkws.GroupMemberFullInfo is nil")
|
||||||
}
|
}
|
||||||
if groupID != "" {
|
if groupID != "" {
|
||||||
if authverify.IsManagerUserID(userID, g.config.Share.IMAdminUserID) {
|
if authverify.IsManagerUserID(userID, g.config.Share.IMAdminUserID) {
|
||||||
*opUser = &sdkws.GroupMemberFullInfo{
|
*targetUser = &sdkws.GroupMemberFullInfo{
|
||||||
GroupID: groupID,
|
GroupID: groupID,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
RoleLevel: constant.GroupAdmin,
|
RoleLevel: constant.GroupAdmin,
|
||||||
@@ -252,7 +253,7 @@ func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID stri
|
|||||||
} else {
|
} else {
|
||||||
member, err := g.db.TakeGroupMember(ctx, groupID, userID)
|
member, err := g.db.TakeGroupMember(ctx, groupID, userID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
*opUser = g.groupMemberDB2PB(member, 0)
|
*targetUser = g.groupMemberDB2PB(member, 0)
|
||||||
} else if !(errors.Is(err, mongo.ErrNoDocuments) || errs.ErrRecordNotFound.Is(err)) {
|
} else if !(errors.Is(err, mongo.ErrNoDocuments) || errs.ErrRecordNotFound.Is(err)) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -262,8 +263,8 @@ func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if *opUser == nil {
|
if *targetUser == nil {
|
||||||
*opUser = &sdkws.GroupMemberFullInfo{
|
*targetUser = &sdkws.GroupMemberFullInfo{
|
||||||
GroupID: groupID,
|
GroupID: groupID,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
Nickname: user.Nickname,
|
Nickname: user.Nickname,
|
||||||
@@ -271,11 +272,11 @@ func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID stri
|
|||||||
OperatorUserID: userID,
|
OperatorUserID: userID,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (*opUser).Nickname == "" {
|
if (*targetUser).Nickname == "" {
|
||||||
(*opUser).Nickname = user.Nickname
|
(*targetUser).Nickname = user.Nickname
|
||||||
}
|
}
|
||||||
if (*opUser).FaceURL == "" {
|
if (*targetUser).FaceURL == "" {
|
||||||
(*opUser).FaceURL = user.FaceURL
|
(*targetUser).FaceURL = user.FaceURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -283,7 +284,8 @@ func (g *NotificationSender) fillOpUserByUserID(ctx context.Context, userID stri
|
|||||||
|
|
||||||
func (g *NotificationSender) setVersion(ctx context.Context, version *uint64, versionID *string, collName string, id string) {
|
func (g *NotificationSender) setVersion(ctx context.Context, version *uint64, versionID *string, collName string, id string) {
|
||||||
versions := versionctx.GetVersionLog(ctx).Get()
|
versions := versionctx.GetVersionLog(ctx).Get()
|
||||||
for _, coll := range versions {
|
for i := len(versions) - 1; i >= 0; i-- {
|
||||||
|
coll := versions[i]
|
||||||
if coll.Name == collName && coll.Doc.DID == id {
|
if coll.Name == collName && coll.Doc.DID == id {
|
||||||
*version = uint64(coll.Doc.Version)
|
*version = uint64(coll.Doc.Version)
|
||||||
*versionID = coll.Doc.ID.Hex()
|
*versionID = coll.Doc.ID.Hex()
|
||||||
@@ -307,7 +309,7 @@ func (g *NotificationSender) setSortVersion(ctx context.Context, version *uint64
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips) {
|
func (g *NotificationSender) GroupCreatedNotification(ctx context.Context, tips *sdkws.GroupCreatedTips, SendMessage *bool) {
|
||||||
var err error
|
var err error
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -318,7 +320,7 @@ func (g *NotificationSender) GroupCreatedNotification(ctx context.Context, tips
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupCreatedNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupCreatedNotification, tips, notification.WithSendMessage(SendMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) {
|
func (g *NotificationSender) GroupInfoSetNotification(ctx context.Context, tips *sdkws.GroupInfoSetTips) {
|
||||||
@@ -332,7 +334,7 @@ func (g *NotificationSender) GroupInfoSetNotification(ctx context.Context, tips
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNotification, tips, rpcclient.WithRpcGetUserName())
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNotification, tips, notification.WithRpcGetUserName())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) GroupInfoSetNameNotification(ctx context.Context, tips *sdkws.GroupInfoSetNameTips) {
|
func (g *NotificationSender) GroupInfoSetNameNotification(ctx context.Context, tips *sdkws.GroupInfoSetNameTips) {
|
||||||
@@ -349,7 +351,7 @@ func (g *NotificationSender) GroupInfoSetNameNotification(ctx context.Context, t
|
|||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNameNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetNameNotification, tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips) {
|
func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Context, tips *sdkws.GroupInfoSetAnnouncementTips, sendMessage *bool) {
|
||||||
var err error
|
var err error
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -360,16 +362,49 @@ func (g *NotificationSender) GroupInfoSetAnnouncementNotification(ctx context.Co
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetAnnouncementNotification, tips, rpcclient.WithRpcGetUserName())
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupInfoSetAnnouncementNotification, tips, notification.WithRpcGetUserName(), notification.WithSendMessage(sendMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbgroup.JoinGroupReq) {
|
func (g *NotificationSender) uuid() string {
|
||||||
|
return uuid.New().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *NotificationSender) getGroupRequest(ctx context.Context, groupID string, userID string) (*sdkws.GroupRequest, error) {
|
||||||
|
request, err := g.db.TakeGroupRequest(ctx, groupID, userID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
users, err := g.getUsersInfo(ctx, []string{userID})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(users) == 0 {
|
||||||
|
return nil, servererrs.ErrUserIDNotFound.WrapMsg(fmt.Sprintf("user %s not found", userID))
|
||||||
|
}
|
||||||
|
info, ok := users[0].(*sdkws.UserInfo)
|
||||||
|
if !ok {
|
||||||
|
info = &sdkws.UserInfo{
|
||||||
|
UserID: users[0].GetUserID(),
|
||||||
|
Nickname: users[0].GetNickname(),
|
||||||
|
FaceURL: users[0].GetFaceURL(),
|
||||||
|
Ex: users[0].GetEx(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return convert.Db2PbGroupRequest(request, info, nil), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *NotificationSender) JoinGroupApplicationNotification(ctx context.Context, req *pbgroup.JoinGroupReq, dbReq *model.GroupRequest) {
|
||||||
var err error
|
var err error
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZError(ctx, stringutil.GetFuncName(1)+" failed", err)
|
log.ZError(ctx, stringutil.GetFuncName(1)+" failed", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
request, err := g.getGroupRequest(ctx, dbReq.GroupID, dbReq.UserID)
|
||||||
|
if err != nil {
|
||||||
|
log.ZError(ctx, "JoinGroupApplicationNotification getGroupRequest", err, "dbReq", dbReq)
|
||||||
|
return
|
||||||
|
}
|
||||||
var group *sdkws.GroupInfo
|
var group *sdkws.GroupInfo
|
||||||
group, err = g.getGroupInfo(ctx, req.GroupID)
|
group, err = g.getGroupInfo(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -385,7 +420,13 @@ func (g *NotificationSender) JoinGroupApplicationNotification(ctx context.Contex
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
userIDs = append(userIDs, req.InviterUserID, mcontext.GetOpUserID(ctx))
|
userIDs = append(userIDs, req.InviterUserID, mcontext.GetOpUserID(ctx))
|
||||||
tips := &sdkws.JoinGroupApplicationTips{Group: group, Applicant: user, ReqMsg: req.ReqMessage}
|
tips := &sdkws.JoinGroupApplicationTips{
|
||||||
|
Group: group,
|
||||||
|
Applicant: user,
|
||||||
|
ReqMsg: req.ReqMessage,
|
||||||
|
Uuid: g.uuid(),
|
||||||
|
Request: request,
|
||||||
|
}
|
||||||
for _, userID := range datautil.Distinct(userIDs) {
|
for _, userID := range datautil.Distinct(userIDs) {
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), userID, constant.JoinGroupApplicationNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), userID, constant.JoinGroupApplicationNotification, tips)
|
||||||
}
|
}
|
||||||
@@ -415,6 +456,11 @@ func (g *NotificationSender) GroupApplicationAcceptedNotification(ctx context.Co
|
|||||||
log.ZError(ctx, stringutil.GetFuncName(1)+" failed", err)
|
log.ZError(ctx, stringutil.GetFuncName(1)+" failed", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
request, err := g.getGroupRequest(ctx, req.GroupID, req.FromUserID)
|
||||||
|
if err != nil {
|
||||||
|
log.ZError(ctx, "GroupApplicationAcceptedNotification getGroupRequest", err, "req", req)
|
||||||
|
return
|
||||||
|
}
|
||||||
var group *sdkws.GroupInfo
|
var group *sdkws.GroupInfo
|
||||||
group, err = g.getGroupInfo(ctx, req.GroupID)
|
group, err = g.getGroupInfo(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -430,8 +476,14 @@ func (g *NotificationSender) GroupApplicationAcceptedNotification(ctx context.Co
|
|||||||
if err = g.fillOpUser(ctx, &opUser, group.GroupID); err != nil {
|
if err = g.fillOpUser(ctx, &opUser, group.GroupID); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
tips := &sdkws.GroupApplicationAcceptedTips{
|
||||||
|
Group: group,
|
||||||
|
OpUser: opUser,
|
||||||
|
HandleMsg: req.HandledMsg,
|
||||||
|
Uuid: g.uuid(),
|
||||||
|
Request: request,
|
||||||
|
}
|
||||||
for _, userID := range append(userIDs, req.FromUserID) {
|
for _, userID := range append(userIDs, req.FromUserID) {
|
||||||
tips := &sdkws.GroupApplicationAcceptedTips{Group: group, OpUser: opUser, HandleMsg: req.HandledMsg}
|
|
||||||
if userID == req.FromUserID {
|
if userID == req.FromUserID {
|
||||||
tips.ReceiverAs = applicantReceiver
|
tips.ReceiverAs = applicantReceiver
|
||||||
} else {
|
} else {
|
||||||
@@ -448,6 +500,11 @@ func (g *NotificationSender) GroupApplicationRejectedNotification(ctx context.Co
|
|||||||
log.ZError(ctx, stringutil.GetFuncName(1)+" failed", err)
|
log.ZError(ctx, stringutil.GetFuncName(1)+" failed", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
request, err := g.getGroupRequest(ctx, req.GroupID, req.FromUserID)
|
||||||
|
if err != nil {
|
||||||
|
log.ZError(ctx, "GroupApplicationAcceptedNotification getGroupRequest", err, "req", req)
|
||||||
|
return
|
||||||
|
}
|
||||||
var group *sdkws.GroupInfo
|
var group *sdkws.GroupInfo
|
||||||
group, err = g.getGroupInfo(ctx, req.GroupID)
|
group, err = g.getGroupInfo(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -463,8 +520,14 @@ func (g *NotificationSender) GroupApplicationRejectedNotification(ctx context.Co
|
|||||||
if err = g.fillOpUser(ctx, &opUser, group.GroupID); err != nil {
|
if err = g.fillOpUser(ctx, &opUser, group.GroupID); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
tips := &sdkws.GroupApplicationRejectedTips{
|
||||||
|
Group: group,
|
||||||
|
OpUser: opUser,
|
||||||
|
HandleMsg: req.HandledMsg,
|
||||||
|
Uuid: g.uuid(),
|
||||||
|
Request: request,
|
||||||
|
}
|
||||||
for _, userID := range append(userIDs, req.FromUserID) {
|
for _, userID := range append(userIDs, req.FromUserID) {
|
||||||
tips := &sdkws.GroupApplicationAcceptedTips{Group: group, OpUser: opUser, HandleMsg: req.HandledMsg}
|
|
||||||
if userID == req.FromUserID {
|
if userID == req.FromUserID {
|
||||||
tips.ReceiverAs = applicantReceiver
|
tips.ReceiverAs = applicantReceiver
|
||||||
} else {
|
} else {
|
||||||
@@ -505,7 +568,7 @@ func (g *NotificationSender) GroupOwnerTransferredNotification(ctx context.Conte
|
|||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupOwnerTransferredNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupOwnerTransferredNotification, tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips) {
|
func (g *NotificationSender) MemberKickedNotification(ctx context.Context, tips *sdkws.MemberKickedTips, SendMessage *bool) {
|
||||||
var err error
|
var err error
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -516,10 +579,14 @@ func (g *NotificationSender) MemberKickedNotification(ctx context.Context, tips
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.MemberKickedNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.MemberKickedNotification, tips, notification.WithSendMessage(SendMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx context.Context, groupID string, invitedOpUserID string, entrantUserID ...string) error {
|
func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx context.Context, groupID string, SendMessage *bool, invitedOpUserID string, entrantUserID ...string) error {
|
||||||
|
return g.groupApplicationAgreeMemberEnterNotification(ctx, groupID, SendMessage, invitedOpUserID, entrantUserID...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *NotificationSender) groupApplicationAgreeMemberEnterNotification(ctx context.Context, groupID string, SendMessage *bool, invitedOpUserID string, entrantUserID ...string) error {
|
||||||
var err error
|
var err error
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -556,20 +623,18 @@ func (g *NotificationSender) GroupApplicationAgreeMemberEnterNotification(ctx co
|
|||||||
InvitedUserList: users,
|
InvitedUserList: users,
|
||||||
}
|
}
|
||||||
opUserID := mcontext.GetOpUserID(ctx)
|
opUserID := mcontext.GetOpUserID(ctx)
|
||||||
if err = g.fillOpUserByUserID(ctx, opUserID, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err = g.fillUserByUserID(ctx, opUserID, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
switch {
|
if invitedOpUserID == opUserID {
|
||||||
case invitedOpUserID == "":
|
|
||||||
case invitedOpUserID == opUserID:
|
|
||||||
tips.InviterUser = tips.OpUser
|
tips.InviterUser = tips.OpUser
|
||||||
default:
|
} else {
|
||||||
if err = g.fillOpUserByUserID(ctx, invitedOpUserID, &tips.InviterUser, tips.Group.GroupID); err != nil {
|
if err = g.fillUserByUserID(ctx, invitedOpUserID, &tips.InviterUser, tips.Group.GroupID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberInvitedNotification, tips, notification.WithSendMessage(SendMessage))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,7 +679,7 @@ func (g *NotificationSender) MemberEnterNotification(ctx context.Context, groupI
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips) {
|
func (g *NotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips, SendMessage *bool) {
|
||||||
var err error
|
var err error
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -624,7 +689,7 @@ func (g *NotificationSender) GroupDismissedNotification(ctx context.Context, tip
|
|||||||
if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupDismissedNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), tips.Group.GroupID, constant.GroupDismissedNotification, tips, notification.WithSendMessage(SendMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *NotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) {
|
func (g *NotificationSender) GroupMemberMutedNotification(ctx context.Context, groupID, groupMemberUserID string, mutedSeconds uint32) {
|
||||||
@@ -781,7 +846,7 @@ func (g *NotificationSender) GroupMemberSetToAdminNotification(ctx context.Conte
|
|||||||
if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
g.setSortVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID, &tips.GroupSortVersion)
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToAdminNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToAdminNotification, tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,6 +871,6 @@ func (g *NotificationSender) GroupMemberSetToOrdinaryUserNotification(ctx contex
|
|||||||
if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
if err = g.fillOpUser(ctx, &tips.OpUser, tips.Group.GroupID); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
g.setSortVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID, &tips.GroupSortVersion)
|
||||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips)
|
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.GroupMemberSetToOrdinaryUserNotification, tips)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/protocol/group"
|
"github.com/openimsdk/protocol/group"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
)
|
)
|
||||||
@@ -26,6 +27,9 @@ func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCrea
|
|||||||
if req.Start > req.End {
|
if req.Start > req.End {
|
||||||
return nil, errs.ErrArgs.WrapMsg("start > end: %d > %d", req.Start, req.End)
|
return nil, errs.ErrArgs.WrapMsg("start > end: %d > %d", req.Start, req.End)
|
||||||
}
|
}
|
||||||
|
if err := authverify.CheckAdmin(ctx, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
total, err := s.db.CountTotal(ctx, nil)
|
total, err := s.db.CountTotal(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
+43
-153
@@ -12,15 +12,23 @@ import (
|
|||||||
pbgroup "github.com/openimsdk/protocol/group"
|
pbgroup "github.com/openimsdk/protocol/group"
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/mcontext"
|
||||||
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *groupServer) GetFullGroupMemberUserIDs(ctx context.Context, req *pbgroup.GetFullGroupMemberUserIDsReq) (*pbgroup.GetFullGroupMemberUserIDsResp, error) {
|
const versionSyncLimit = 500
|
||||||
vl, err := s.db.FindMaxGroupMemberVersionCache(ctx, req.GroupID)
|
|
||||||
|
func (g *groupServer) GetFullGroupMemberUserIDs(ctx context.Context, req *pbgroup.GetFullGroupMemberUserIDsReq) (*pbgroup.GetFullGroupMemberUserIDsResp, error) {
|
||||||
|
userIDs, err := g.db.FindGroupMemberUserID(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userIDs, err := s.db.FindGroupMemberUserID(ctx, req.GroupID)
|
if !authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) {
|
||||||
|
if !datautil.Contain(mcontext.GetOpUserID(ctx), userIDs...) {
|
||||||
|
return nil, errs.ErrNoPermission.WrapMsg("op user not in group")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vl, err := g.db.FindMaxGroupMemberVersionCache(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -37,6 +45,9 @@ func (s *groupServer) GetFullGroupMemberUserIDs(ctx context.Context, req *pbgrou
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) GetFullJoinGroupIDs(ctx context.Context, req *pbgroup.GetFullJoinGroupIDsReq) (*pbgroup.GetFullJoinGroupIDsResp, error) {
|
func (s *groupServer) GetFullJoinGroupIDs(ctx context.Context, req *pbgroup.GetFullJoinGroupIDsReq) (*pbgroup.GetFullJoinGroupIDsResp, error) {
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
vl, err := s.db.FindMaxJoinGroupVersionCache(ctx, req.UserID)
|
vl, err := s.db.FindMaxJoinGroupVersionCache(ctx, req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -58,6 +69,9 @@ func (s *groupServer) GetFullJoinGroupIDs(ctx context.Context, req *pbgroup.GetF
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) GetIncrementalGroupMember(ctx context.Context, req *pbgroup.GetIncrementalGroupMemberReq) (*pbgroup.GetIncrementalGroupMemberResp, error) {
|
func (s *groupServer) GetIncrementalGroupMember(ctx context.Context, req *pbgroup.GetIncrementalGroupMemberReq) (*pbgroup.GetIncrementalGroupMemberResp, error) {
|
||||||
|
if err := s.checkAdminOrInGroup(ctx, req.GroupID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
group, err := s.db.TakeGroup(ctx, req.GroupID)
|
group, err := s.db.TakeGroup(ctx, req.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -132,152 +146,8 @@ func (s *groupServer) GetIncrementalGroupMember(ctx context.Context, req *pbgrou
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) BatchGetIncrementalGroupMember(ctx context.Context, req *pbgroup.BatchGetIncrementalGroupMemberReq) (resp *pbgroup.BatchGetIncrementalGroupMemberResp, err error) {
|
func (g *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *pbgroup.GetIncrementalJoinGroupReq) (*pbgroup.GetIncrementalJoinGroupResp, error) {
|
||||||
type VersionInfo struct {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, g.config.Share.IMAdminUserID); err != nil {
|
||||||
GroupID string
|
|
||||||
VersionID string
|
|
||||||
VersionNumber uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
var groupIDs []string
|
|
||||||
|
|
||||||
groupsVersionMap := make(map[string]*VersionInfo)
|
|
||||||
groupsMap := make(map[string]*model.Group)
|
|
||||||
hasGroupUpdateMap := make(map[string]bool)
|
|
||||||
sortVersionMap := make(map[string]uint64)
|
|
||||||
|
|
||||||
var targetKeys, versionIDs []string
|
|
||||||
var versionNumbers []uint64
|
|
||||||
|
|
||||||
var requestBodyLen int
|
|
||||||
|
|
||||||
for _, group := range req.ReqList {
|
|
||||||
groupsVersionMap[group.GroupID] = &VersionInfo{
|
|
||||||
GroupID: group.GroupID,
|
|
||||||
VersionID: group.VersionID,
|
|
||||||
VersionNumber: group.Version,
|
|
||||||
}
|
|
||||||
|
|
||||||
groupIDs = append(groupIDs, group.GroupID)
|
|
||||||
}
|
|
||||||
|
|
||||||
groups, err := s.db.FindGroup(ctx, groupIDs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errs.Wrap(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, group := range groups {
|
|
||||||
if group.Status == constant.GroupStatusDismissed {
|
|
||||||
err = servererrs.ErrDismissedAlready.Wrap()
|
|
||||||
log.ZError(ctx, "This group is Dismissed Already", err, "group is", group.GroupID)
|
|
||||||
|
|
||||||
delete(groupsVersionMap, group.GroupID)
|
|
||||||
} else {
|
|
||||||
groupsMap[group.GroupID] = group
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for groupID, vInfo := range groupsVersionMap {
|
|
||||||
targetKeys = append(targetKeys, groupID)
|
|
||||||
versionIDs = append(versionIDs, vInfo.VersionID)
|
|
||||||
versionNumbers = append(versionNumbers, vInfo.VersionNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
opt := incrversion.BatchOption[[]*sdkws.GroupMemberFullInfo, pbgroup.BatchGetIncrementalGroupMemberResp]{
|
|
||||||
Ctx: ctx,
|
|
||||||
TargetKeys: targetKeys,
|
|
||||||
VersionIDs: versionIDs,
|
|
||||||
VersionNumbers: versionNumbers,
|
|
||||||
Versions: func(ctx context.Context, groupIDs []string, versions []uint64, limits []int) (map[string]*model.VersionLog, error) {
|
|
||||||
vLogs, err := s.db.BatchFindMemberIncrVersion(ctx, groupIDs, versions, limits)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errs.Wrap(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for groupID, vlog := range vLogs {
|
|
||||||
vlogElems := make([]model.VersionLogElem, 0, len(vlog.Logs))
|
|
||||||
for i, log := range vlog.Logs {
|
|
||||||
switch log.EID {
|
|
||||||
case model.VersionGroupChangeID:
|
|
||||||
vlog.LogLen--
|
|
||||||
hasGroupUpdateMap[groupID] = true
|
|
||||||
case model.VersionSortChangeID:
|
|
||||||
vlog.LogLen--
|
|
||||||
sortVersionMap[groupID] = uint64(log.Version)
|
|
||||||
default:
|
|
||||||
vlogElems = append(vlogElems, vlog.Logs[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vlog.Logs = vlogElems
|
|
||||||
if vlog.LogLen > 0 {
|
|
||||||
hasGroupUpdateMap[groupID] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vLogs, nil
|
|
||||||
},
|
|
||||||
CacheMaxVersions: s.db.BatchFindMaxGroupMemberVersionCache,
|
|
||||||
Find: func(ctx context.Context, groupID string, ids []string) ([]*sdkws.GroupMemberFullInfo, error) {
|
|
||||||
memberInfo, err := s.getGroupMembersInfo(ctx, groupID, ids)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return memberInfo, err
|
|
||||||
},
|
|
||||||
Resp: func(versions map[string]*model.VersionLog, deleteIdsMap map[string][]string, insertListMap, updateListMap map[string][]*sdkws.GroupMemberFullInfo, fullMap map[string]bool) *pbgroup.BatchGetIncrementalGroupMemberResp {
|
|
||||||
resList := make(map[string]*pbgroup.GetIncrementalGroupMemberResp)
|
|
||||||
|
|
||||||
for groupID, versionLog := range versions {
|
|
||||||
resList[groupID] = &pbgroup.GetIncrementalGroupMemberResp{
|
|
||||||
VersionID: versionLog.ID.Hex(),
|
|
||||||
Version: uint64(versionLog.Version),
|
|
||||||
Full: fullMap[groupID],
|
|
||||||
Delete: deleteIdsMap[groupID],
|
|
||||||
Insert: insertListMap[groupID],
|
|
||||||
Update: updateListMap[groupID],
|
|
||||||
SortVersion: sortVersionMap[groupID],
|
|
||||||
}
|
|
||||||
|
|
||||||
requestBodyLen += len(insertListMap[groupID]) + len(updateListMap[groupID]) + len(deleteIdsMap[groupID])
|
|
||||||
if requestBodyLen > 200 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pbgroup.BatchGetIncrementalGroupMemberResp{
|
|
||||||
RespList: resList,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err = opt.Build()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errs.Wrap(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for groupID, val := range resp.RespList {
|
|
||||||
if val.Full || hasGroupUpdateMap[groupID] {
|
|
||||||
count, err := s.db.FindGroupMemberNum(ctx, groupID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
owner, err := s.db.TakeGroupOwner(ctx, groupID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.RespList[groupID].Group = s.groupDB2PB(groupsMap[groupID], owner.UserID, count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *pbgroup.GetIncrementalJoinGroupReq) (*pbgroup.GetIncrementalJoinGroupResp, error) {
|
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opt := incrversion.Option[*sdkws.GroupInfo, pbgroup.GetIncrementalJoinGroupResp]{
|
opt := incrversion.Option[*sdkws.GroupInfo, pbgroup.GetIncrementalJoinGroupResp]{
|
||||||
@@ -285,9 +155,9 @@ func (s *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *pbgroup.
|
|||||||
VersionKey: req.UserID,
|
VersionKey: req.UserID,
|
||||||
VersionID: req.VersionID,
|
VersionID: req.VersionID,
|
||||||
VersionNumber: req.Version,
|
VersionNumber: req.Version,
|
||||||
Version: s.db.FindJoinIncrVersion,
|
Version: g.db.FindJoinIncrVersion,
|
||||||
CacheMaxVersion: s.db.FindMaxJoinGroupVersionCache,
|
CacheMaxVersion: g.db.FindMaxJoinGroupVersionCache,
|
||||||
Find: s.getGroupsInfo,
|
Find: g.getGroupsInfo,
|
||||||
Resp: func(version *model.VersionLog, delIDs []string, insertList, updateList []*sdkws.GroupInfo, full bool) *pbgroup.GetIncrementalJoinGroupResp {
|
Resp: func(version *model.VersionLog, delIDs []string, insertList, updateList []*sdkws.GroupInfo, full bool) *pbgroup.GetIncrementalJoinGroupResp {
|
||||||
return &pbgroup.GetIncrementalJoinGroupResp{
|
return &pbgroup.GetIncrementalJoinGroupResp{
|
||||||
VersionID: version.ID.Hex(),
|
VersionID: version.ID.Hex(),
|
||||||
@@ -301,3 +171,23 @@ func (s *groupServer) GetIncrementalJoinGroup(ctx context.Context, req *pbgroup.
|
|||||||
}
|
}
|
||||||
return opt.Build()
|
return opt.Build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *groupServer) BatchGetIncrementalGroupMember(ctx context.Context, req *pbgroup.BatchGetIncrementalGroupMemberReq) (*pbgroup.BatchGetIncrementalGroupMemberResp, error) {
|
||||||
|
var num int
|
||||||
|
resp := make(map[string]*pbgroup.GetIncrementalGroupMemberResp)
|
||||||
|
for _, memberReq := range req.ReqList {
|
||||||
|
if _, ok := resp[memberReq.GroupID]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
memberResp, err := g.GetIncrementalGroupMember(ctx, memberReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp[memberReq.GroupID] = memberResp
|
||||||
|
num += len(memberResp.Insert) + len(memberResp.Update) + len(memberResp.Delete)
|
||||||
|
if num >= versionSyncLimit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &pbgroup.BatchGetIncrementalGroupMemberResp{RespList: resp}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type MsgNotificationSender struct {
|
type MsgNotificationSender struct {
|
||||||
*rpcclient.NotificationSender
|
*notification.NotificationSender
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMsgNotificationSender(config *Config, opts ...rpcclient.NotificationSenderOptions) *MsgNotificationSender {
|
func NewMsgNotificationSender(config *Config, opts ...notification.NotificationSenderOptions) *MsgNotificationSender {
|
||||||
return &MsgNotificationSender{rpcclient.NewNotificationSender(&config.NotificationConfig, opts...)}
|
return &MsgNotificationSender{notification.NewNotificationSender(&config.NotificationConfig, opts...)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgNotificationSender) UserDeleteMsgsNotification(ctx context.Context, userID, conversationID string, seqs []int64) {
|
func (m *MsgNotificationSender) UserDeleteMsgsNotification(ctx context.Context, userID, conversationID string, seqs []int64) {
|
||||||
|
|||||||
@@ -17,9 +17,10 @@ package msg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
@@ -79,8 +80,10 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
switch members[req.UserID].RoleLevel {
|
switch members[req.UserID].RoleLevel {
|
||||||
case constant.GroupOwner:
|
case constant.GroupOwner:
|
||||||
case constant.GroupAdmin:
|
case constant.GroupAdmin:
|
||||||
if members[msgs[0].SendID].RoleLevel != constant.GroupOrdinaryUsers {
|
if sendMember, ok := members[msgs[0].SendID]; ok {
|
||||||
return nil, errs.ErrNoPermission.WrapMsg("no permission")
|
if sendMember.RoleLevel != constant.GroupOrdinaryUsers {
|
||||||
|
return nil, errs.ErrNoPermission.WrapMsg("no permission")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, errs.ErrNoPermission.WrapMsg("no permission")
|
return nil, errs.ErrNoPermission.WrapMsg("no permission")
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ package msg
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/notification"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
@@ -27,7 +29,6 @@ import (
|
|||||||
"github.com/openimsdk/tools/db/redisutil"
|
"github.com/openimsdk/tools/db/redisutil"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/notification"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpccache"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpccache"
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
"github.com/openimsdk/protocol/conversation"
|
"github.com/openimsdk/protocol/conversation"
|
||||||
@@ -63,7 +64,7 @@ type msgServer struct {
|
|||||||
GroupLocalCache *rpccache.GroupLocalCache // Local cache for group data.
|
GroupLocalCache *rpccache.GroupLocalCache // Local cache for group data.
|
||||||
ConversationLocalCache *rpccache.ConversationLocalCache // Local cache for conversation data.
|
ConversationLocalCache *rpccache.ConversationLocalCache // Local cache for conversation data.
|
||||||
Handlers MessageInterceptorChain // Chain of handlers for processing messages.
|
Handlers MessageInterceptorChain // Chain of handlers for processing messages.
|
||||||
notificationSender *rpcclient.NotificationSender // RPC client for sending notifications.
|
notificationSender *notification.NotificationSender // RPC client for sending notifications.
|
||||||
msgNotificationSender *MsgNotificationSender // RPC client for sending msg notifications.
|
msgNotificationSender *MsgNotificationSender // RPC client for sending msg notifications.
|
||||||
config *Config // Global configuration settings.
|
config *Config // Global configuration settings.
|
||||||
webhookClient *webhook.Client
|
webhookClient *webhook.Client
|
||||||
@@ -132,8 +133,8 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
|||||||
conversationClient: conversationClient,
|
conversationClient: conversationClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.notificationSender = rpcclient.NewNotificationSender(&config.NotificationConfig, rpcclient.WithLocalSendMsg(s.SendMsg))
|
s.notificationSender = notification.NewNotificationSender(&config.NotificationConfig, notification.WithLocalSendMsg(s.SendMsg))
|
||||||
s.msgNotificationSender = NewMsgNotificationSender(config, rpcclient.WithLocalSendMsg(s.SendMsg))
|
s.msgNotificationSender = NewMsgNotificationSender(config, notification.WithLocalSendMsg(s.SendMsg))
|
||||||
|
|
||||||
msg.RegisterMsgServer(server, s)
|
msg.RegisterMsgServer(server, s)
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ package relation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/notification/common_user"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
|
||||||
"github.com/openimsdk/tools/mq/memamq"
|
"github.com/openimsdk/tools/mq/memamq"
|
||||||
@@ -101,22 +103,24 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
|||||||
}
|
}
|
||||||
userClient := rpcli.NewUserClient(userConn)
|
userClient := rpcli.NewUserClient(userConn)
|
||||||
|
|
||||||
|
database := controller.NewFriendDatabase(
|
||||||
|
friendMongoDB,
|
||||||
|
friendRequestMongoDB,
|
||||||
|
redis.NewFriendCacheRedis(rdb, &config.LocalCacheConfig, friendMongoDB, redis.GetRocksCacheOptions()),
|
||||||
|
mgocli.GetTx(),
|
||||||
|
)
|
||||||
// Initialize notification sender
|
// Initialize notification sender
|
||||||
notificationSender := NewFriendNotificationSender(
|
notificationSender := NewFriendNotificationSender(
|
||||||
&config.NotificationConfig,
|
&config.NotificationConfig,
|
||||||
rpcli.NewMsgClient(msgConn),
|
rpcli.NewMsgClient(msgConn),
|
||||||
WithRpcFunc(userClient.GetUsersInfo),
|
WithRpcFunc(userClient.GetUsersInfo),
|
||||||
|
WithFriendDB(database),
|
||||||
)
|
)
|
||||||
localcache.InitLocalCache(&config.LocalCacheConfig)
|
localcache.InitLocalCache(&config.LocalCacheConfig)
|
||||||
|
|
||||||
// Register Friend server with refactored MongoDB and Redis integrations
|
// Register Friend server with refactored MongoDB and Redis integrations
|
||||||
relation.RegisterFriendServer(server, &friendServer{
|
relation.RegisterFriendServer(server, &friendServer{
|
||||||
db: controller.NewFriendDatabase(
|
db: database,
|
||||||
friendMongoDB,
|
|
||||||
friendRequestMongoDB,
|
|
||||||
redis.NewFriendCacheRedis(rdb, &config.LocalCacheConfig, friendMongoDB, redis.GetRocksCacheOptions()),
|
|
||||||
mgocli.GetTx(),
|
|
||||||
),
|
|
||||||
blackDatabase: controller.NewBlackDatabase(
|
blackDatabase: controller.NewBlackDatabase(
|
||||||
blackMongoDB,
|
blackMongoDB,
|
||||||
redis.NewBlackCacheRedis(rdb, &config.LocalCacheConfig, blackMongoDB, redis.GetRocksCacheOptions()),
|
redis.NewBlackCacheRedis(rdb, &config.LocalCacheConfig, blackMongoDB, redis.GetRocksCacheOptions()),
|
||||||
@@ -280,6 +284,9 @@ func (s *friendServer) SetFriendRemark(ctx context.Context, req *relation.SetFri
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) GetFriendInfo(ctx context.Context, req *relation.GetFriendInfoReq) (*relation.GetFriendInfoResp, error) {
|
func (s *friendServer) GetFriendInfo(ctx context.Context, req *relation.GetFriendInfoReq) (*relation.GetFriendInfoResp, error) {
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
friends, err := s.db.FindFriendsWithError(ctx, req.OwnerUserID, req.FriendUserIDs)
|
friends, err := s.db.FindFriendsWithError(ctx, req.OwnerUserID, req.FriendUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -292,6 +299,9 @@ func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *relation.G
|
|||||||
if datautil.Duplicate(req.FriendUserIDs) {
|
if datautil.Duplicate(req.FriendUserIDs) {
|
||||||
return nil, errs.ErrArgs.WrapMsg("friend userID repeated")
|
return nil, errs.ErrArgs.WrapMsg("friend userID repeated")
|
||||||
}
|
}
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
friends, err := s.getFriend(ctx, req.OwnerUserID, req.FriendUserIDs)
|
friends, err := s.getFriend(ctx, req.OwnerUserID, req.FriendUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -321,7 +331,7 @@ func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp = &relation.GetDesignatedFriendsApplyResp{}
|
resp = &relation.GetDesignatedFriendsApplyResp{}
|
||||||
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userClient.GetUsersInfoMap)
|
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.getCommonUserMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -334,13 +344,16 @@ func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *rel
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
total, friendRequests, err := s.db.PageFriendRequestToMe(ctx, req.UserID, req.Pagination)
|
handleResults := datautil.Slice(req.HandleResults, func(e int32) int {
|
||||||
|
return int(e)
|
||||||
|
})
|
||||||
|
total, friendRequests, err := s.db.PageFriendRequestToMe(ctx, req.UserID, handleResults, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = &relation.GetPaginationFriendsApplyToResp{}
|
resp = &relation.GetPaginationFriendsApplyToResp{}
|
||||||
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userClient.GetUsersInfoMap)
|
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.getCommonUserMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -357,12 +370,15 @@ func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *r
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
total, friendRequests, err := s.db.PageFriendRequestFromMe(ctx, req.UserID, req.Pagination)
|
handleResults := datautil.Slice(req.HandleResults, func(e int32) int {
|
||||||
|
return int(e)
|
||||||
|
})
|
||||||
|
total, friendRequests, err := s.db.PageFriendRequestFromMe(ctx, req.UserID, handleResults, req.Pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.userClient.GetUsersInfoMap)
|
resp.FriendRequests, err = convert.FriendRequestDB2Pb(ctx, friendRequests, s.getCommonUserMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -426,6 +442,10 @@ func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, req *relatio
|
|||||||
return nil, errs.ErrArgs.WrapMsg("userIDList repeated")
|
return nil, errs.ErrArgs.WrapMsg("userIDList repeated")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
userMap, err := s.userClient.GetUsersInfoMap(ctx, req.UserIDList)
|
userMap, err := s.userClient.GetUsersInfoMap(ctx, req.UserIDList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -505,6 +525,10 @@ func (s *friendServer) UpdateFriends(
|
|||||||
return nil, errs.ErrArgs.WrapMsg("friendIDList repeated")
|
return nil, errs.ErrArgs.WrapMsg("friendIDList repeated")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
_, err := s.db.FindFriendsWithError(ctx, req.OwnerUserID, req.FriendUserIDs)
|
_, err := s.db.FindFriendsWithError(ctx, req.OwnerUserID, req.FriendUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -530,3 +554,28 @@ func (s *friendServer) UpdateFriends(
|
|||||||
s.notificationSender.FriendsInfoUpdateNotification(ctx, req.OwnerUserID, req.FriendUserIDs)
|
s.notificationSender.FriendsInfoUpdateNotification(ctx, req.OwnerUserID, req.FriendUserIDs)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *friendServer) GetSelfUnhandledApplyCount(ctx context.Context, req *relation.GetSelfUnhandledApplyCountReq) (*relation.GetSelfUnhandledApplyCountResp, error) {
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err := s.db.GetUnhandledCount(ctx, req.UserID, req.Time)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &relation.GetSelfUnhandledApplyCountResp{
|
||||||
|
Count: count,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *friendServer) getCommonUserMap(ctx context.Context, userIDs []string) (map[string]common_user.CommonUser, error) {
|
||||||
|
users, err := s.userClient.GetUsersInfo(ctx, userIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return datautil.SliceToMapAny(users, func(e *sdkws.UserInfo) (string, common_user.CommonUser) {
|
||||||
|
return e.UserID, e
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,8 +16,12 @@ package relation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
"github.com/openimsdk/protocol/msg"
|
"github.com/openimsdk/protocol/msg"
|
||||||
|
"github.com/openimsdk/tools/errs"
|
||||||
|
"github.com/openimsdk/tools/log"
|
||||||
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/versionctx"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/versionctx"
|
||||||
@@ -36,7 +40,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FriendNotificationSender struct {
|
type FriendNotificationSender struct {
|
||||||
*rpcclient.NotificationSender
|
*notification.NotificationSender
|
||||||
// Target not found err
|
// Target not found err
|
||||||
getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error)
|
getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error)
|
||||||
// db controller
|
// db controller
|
||||||
@@ -51,9 +55,7 @@ func WithFriendDB(db controller.FriendDatabase) friendNotificationSenderOptions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithDBFunc(
|
func WithDBFunc(fn func(ctx context.Context, userIDs []string) (users []*relationtb.User, err error)) friendNotificationSenderOptions {
|
||||||
fn func(ctx context.Context, userIDs []string) (users []*relationtb.User, err error),
|
|
||||||
) friendNotificationSenderOptions {
|
|
||||||
return func(s *FriendNotificationSender) {
|
return func(s *FriendNotificationSender) {
|
||||||
f := func(ctx context.Context, userIDs []string) (result []common_user.CommonUser, err error) {
|
f := func(ctx context.Context, userIDs []string) (result []common_user.CommonUser, err error) {
|
||||||
users, err := fn(ctx, userIDs)
|
users, err := fn(ctx, userIDs)
|
||||||
@@ -69,9 +71,7 @@ func WithDBFunc(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRpcFunc(
|
func WithRpcFunc(fn func(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error)) friendNotificationSenderOptions {
|
||||||
fn func(ctx context.Context, userIDs []string) ([]*sdkws.UserInfo, error),
|
|
||||||
) friendNotificationSenderOptions {
|
|
||||||
return func(s *FriendNotificationSender) {
|
return func(s *FriendNotificationSender) {
|
||||||
f := func(ctx context.Context, userIDs []string) (result []common_user.CommonUser, err error) {
|
f := func(ctx context.Context, userIDs []string) (result []common_user.CommonUser, err error) {
|
||||||
users, err := fn(ctx, userIDs)
|
users, err := fn(ctx, userIDs)
|
||||||
@@ -89,7 +89,7 @@ func WithRpcFunc(
|
|||||||
|
|
||||||
func NewFriendNotificationSender(conf *config.Notification, msgClient *rpcli.MsgClient, opts ...friendNotificationSenderOptions) *FriendNotificationSender {
|
func NewFriendNotificationSender(conf *config.Notification, msgClient *rpcli.MsgClient, opts ...friendNotificationSenderOptions) *FriendNotificationSender {
|
||||||
f := &FriendNotificationSender{
|
f := &FriendNotificationSender{
|
||||||
NotificationSender: rpcclient.NewNotificationSender(conf, rpcclient.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
NotificationSender: notification.NewNotificationSender(conf, notification.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
||||||
return msgClient.SendMsg(ctx, req)
|
return msgClient.SendMsg(ctx, req)
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
@@ -99,10 +99,7 @@ func NewFriendNotificationSender(conf *config.Notification, msgClient *rpcli.Msg
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) getUsersInfoMap(
|
func (f *FriendNotificationSender) getUsersInfoMap(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error) {
|
||||||
ctx context.Context,
|
|
||||||
userIDs []string,
|
|
||||||
) (map[string]*sdkws.UserInfo, error) {
|
|
||||||
users, err := f.getUsersInfo(ctx, userIDs)
|
users, err := f.getUsersInfo(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -115,10 +112,7 @@ func (f *FriendNotificationSender) getUsersInfoMap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//nolint:unused
|
//nolint:unused
|
||||||
func (f *FriendNotificationSender) getFromToUserNickname(
|
func (f *FriendNotificationSender) getFromToUserNickname(ctx context.Context, fromUserID, toUserID string) (string, string, error) {
|
||||||
ctx context.Context,
|
|
||||||
fromUserID, toUserID string,
|
|
||||||
) (string, string, error) {
|
|
||||||
users, err := f.getUsersInfoMap(ctx, []string{fromUserID, toUserID})
|
users, err := f.getUsersInfoMap(ctx, []string{fromUserID, toUserID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", nil
|
return "", "", nil
|
||||||
@@ -131,60 +125,107 @@ func (f *FriendNotificationSender) UserInfoUpdatedNotification(ctx context.Conte
|
|||||||
f.Notification(ctx, mcontext.GetOpUserID(ctx), changedUserID, constant.UserInfoUpdatedNotification, &tips)
|
f.Notification(ctx, mcontext.GetOpUserID(ctx), changedUserID, constant.UserInfoUpdatedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FriendNotificationSender) getCommonUserMap(ctx context.Context, userIDs []string) (map[string]common_user.CommonUser, error) {
|
||||||
|
users, err := f.getUsersInfo(ctx, userIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return datautil.SliceToMap(users, func(e common_user.CommonUser) string {
|
||||||
|
return e.GetUserID()
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FriendNotificationSender) getFriendRequests(ctx context.Context, fromUserID, toUserID string) (*sdkws.FriendRequest, error) {
|
||||||
|
if f.db == nil {
|
||||||
|
return nil, errs.ErrInternalServer.WithDetail("db is nil")
|
||||||
|
}
|
||||||
|
friendRequests, err := f.db.FindBothFriendRequests(ctx, fromUserID, toUserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
requests, err := convert.FriendRequestDB2Pb(ctx, friendRequests, f.getCommonUserMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, request := range requests {
|
||||||
|
if request.FromUserID == fromUserID && request.ToUserID == toUserID {
|
||||||
|
return request, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, errs.ErrRecordNotFound.WrapMsg("friend request not found", "fromUserID", fromUserID, "toUserID", toUserID)
|
||||||
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendApplicationAddNotification(ctx context.Context, req *relation.ApplyToAddFriendReq) {
|
func (f *FriendNotificationSender) FriendApplicationAddNotification(ctx context.Context, req *relation.ApplyToAddFriendReq) {
|
||||||
tips := sdkws.FriendApplicationTips{FromToUserID: &sdkws.FromToUserID{
|
request, err := f.getFriendRequests(ctx, req.FromUserID, req.ToUserID)
|
||||||
FromUserID: req.FromUserID,
|
if err != nil {
|
||||||
ToUserID: req.ToUserID,
|
log.ZError(ctx, "FriendApplicationAddNotification get friend request", err, "fromUserID", req.FromUserID, "toUserID", req.ToUserID)
|
||||||
}}
|
return
|
||||||
|
}
|
||||||
|
tips := sdkws.FriendApplicationTips{
|
||||||
|
FromToUserID: &sdkws.FromToUserID{
|
||||||
|
FromUserID: req.FromUserID,
|
||||||
|
ToUserID: req.ToUserID,
|
||||||
|
},
|
||||||
|
Request: request,
|
||||||
|
}
|
||||||
f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips)
|
f.Notification(ctx, req.FromUserID, req.ToUserID, constant.FriendApplicationNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendApplicationAgreedNotification(
|
func (f *FriendNotificationSender) FriendApplicationAgreedNotification(ctx context.Context, req *relation.RespondFriendApplyReq) {
|
||||||
ctx context.Context,
|
request, err := f.getFriendRequests(ctx, req.FromUserID, req.ToUserID)
|
||||||
req *relation.RespondFriendApplyReq,
|
if err != nil {
|
||||||
) {
|
log.ZError(ctx, "FriendApplicationAgreedNotification get friend request", err, "fromUserID", req.FromUserID, "toUserID", req.ToUserID)
|
||||||
tips := sdkws.FriendApplicationApprovedTips{FromToUserID: &sdkws.FromToUserID{
|
return
|
||||||
FromUserID: req.FromUserID,
|
}
|
||||||
ToUserID: req.ToUserID,
|
tips := sdkws.FriendApplicationApprovedTips{
|
||||||
}, HandleMsg: req.HandleMsg}
|
FromToUserID: &sdkws.FromToUserID{
|
||||||
|
FromUserID: req.FromUserID,
|
||||||
|
ToUserID: req.ToUserID,
|
||||||
|
},
|
||||||
|
HandleMsg: req.HandleMsg,
|
||||||
|
Request: request,
|
||||||
|
}
|
||||||
f.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips)
|
f.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationApprovedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendApplicationRefusedNotification(
|
func (f *FriendNotificationSender) FriendApplicationRefusedNotification(ctx context.Context, req *relation.RespondFriendApplyReq) {
|
||||||
ctx context.Context,
|
request, err := f.getFriendRequests(ctx, req.FromUserID, req.ToUserID)
|
||||||
req *relation.RespondFriendApplyReq,
|
if err != nil {
|
||||||
) {
|
log.ZError(ctx, "FriendApplicationRefusedNotification get friend request", err, "fromUserID", req.FromUserID, "toUserID", req.ToUserID)
|
||||||
tips := sdkws.FriendApplicationApprovedTips{FromToUserID: &sdkws.FromToUserID{
|
return
|
||||||
FromUserID: req.FromUserID,
|
}
|
||||||
ToUserID: req.ToUserID,
|
tips := sdkws.FriendApplicationRejectedTips{
|
||||||
}, HandleMsg: req.HandleMsg}
|
FromToUserID: &sdkws.FromToUserID{
|
||||||
|
FromUserID: req.FromUserID,
|
||||||
|
ToUserID: req.ToUserID,
|
||||||
|
},
|
||||||
|
HandleMsg: req.HandleMsg,
|
||||||
|
Request: request,
|
||||||
|
}
|
||||||
f.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips)
|
f.Notification(ctx, req.ToUserID, req.FromUserID, constant.FriendApplicationRejectedNotification, &tips)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendAddedNotification(
|
//func (f *FriendNotificationSender) FriendAddedNotification(ctx context.Context, operationID, opUserID, fromUserID, toUserID string) error {
|
||||||
ctx context.Context,
|
// tips := sdkws.FriendAddedTips{Friend: &sdkws.FriendInfo{}, OpUser: &sdkws.PublicUserInfo{}}
|
||||||
operationID, opUserID, fromUserID, toUserID string,
|
// user, err := f.getUsersInfo(ctx, []string{opUserID})
|
||||||
) error {
|
// if err != nil {
|
||||||
tips := sdkws.FriendAddedTips{Friend: &sdkws.FriendInfo{}, OpUser: &sdkws.PublicUserInfo{}}
|
// return err
|
||||||
user, err := f.getUsersInfo(ctx, []string{opUserID})
|
// }
|
||||||
if err != nil {
|
// tips.OpUser.UserID = user[0].GetUserID()
|
||||||
return err
|
// tips.OpUser.Ex = user[0].GetEx()
|
||||||
}
|
// tips.OpUser.Nickname = user[0].GetNickname()
|
||||||
tips.OpUser.UserID = user[0].GetUserID()
|
// tips.OpUser.FaceURL = user[0].GetFaceURL()
|
||||||
tips.OpUser.Ex = user[0].GetEx()
|
// friends, err := f.db.FindFriendsWithError(ctx, fromUserID, []string{toUserID})
|
||||||
tips.OpUser.Nickname = user[0].GetNickname()
|
// if err != nil {
|
||||||
tips.OpUser.FaceURL = user[0].GetFaceURL()
|
// return err
|
||||||
friends, err := f.db.FindFriendsWithError(ctx, fromUserID, []string{toUserID})
|
// }
|
||||||
if err != nil {
|
// tips.Friend, err = convert.FriendDB2Pb(ctx, friends[0], f.getUsersInfoMap)
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
tips.Friend, err = convert.FriendDB2Pb(ctx, friends[0], f.getUsersInfoMap)
|
// }
|
||||||
if err != nil {
|
// f.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips)
|
||||||
return err
|
// return nil
|
||||||
}
|
//}
|
||||||
f.Notification(ctx, fromUserID, toUserID, constant.FriendAddedNotification, &tips)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *relation.DeleteFriendReq) {
|
func (f *FriendNotificationSender) FriendDeletedNotification(ctx context.Context, req *relation.DeleteFriendReq) {
|
||||||
tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{
|
tips := sdkws.FriendDeletedTips{FromToUserID: &sdkws.FromToUserID{
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ package relation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/util/hashutil"
|
"github.com/openimsdk/open-im-server/v3/pkg/util/hashutil"
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"slices"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/incrversion"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/incrversion"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
@@ -39,6 +40,9 @@ func (s *friendServer) NotificationUserInfoUpdate(ctx context.Context, req *rela
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) GetFullFriendUserIDs(ctx context.Context, req *relation.GetFullFriendUserIDsReq) (*relation.GetFullFriendUserIDsResp, error) {
|
func (s *friendServer) GetFullFriendUserIDs(ctx context.Context, req *relation.GetFullFriendUserIDsReq) (*relation.GetFullFriendUserIDsResp, error) {
|
||||||
|
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
vl, err := s.db.FindMaxFriendVersionCache(ctx, req.UserID)
|
vl, err := s.db.FindMaxFriendVersionCache(ctx, req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -19,11 +19,12 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
@@ -37,7 +38,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (t *thirdServer) PartLimit(ctx context.Context, req *third.PartLimitReq) (*third.PartLimitResp, error) {
|
func (t *thirdServer) PartLimit(ctx context.Context, req *third.PartLimitReq) (*third.PartLimitResp, error) {
|
||||||
limit := t.s3dataBase.PartLimit()
|
limit, err := t.s3dataBase.PartLimit()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &third.PartLimitResp{
|
return &third.PartLimitResp{
|
||||||
MinPartSize: limit.MinPartSize,
|
MinPartSize: limit.MinPartSize,
|
||||||
MaxPartSize: limit.MaxPartSize,
|
MaxPartSize: limit.MaxPartSize,
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ package third
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
|
"github.com/openimsdk/tools/s3/aws"
|
||||||
|
"github.com/openimsdk/tools/s3/disable"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller"
|
||||||
@@ -90,6 +93,10 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
|||||||
o, err = oss.NewOSS(*config.RpcConfig.Object.Oss.Build())
|
o, err = oss.NewOSS(*config.RpcConfig.Object.Oss.Build())
|
||||||
case "kodo":
|
case "kodo":
|
||||||
o, err = kodo.NewKodo(*config.RpcConfig.Object.Kodo.Build())
|
o, err = kodo.NewKodo(*config.RpcConfig.Object.Kodo.Build())
|
||||||
|
case "aws":
|
||||||
|
o, err = aws.NewAws(*config.RpcConfig.Object.Aws.Build())
|
||||||
|
case "":
|
||||||
|
o = disable.NewDisable()
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("invalid object enable: %s", enable)
|
err = fmt.Errorf("invalid object enable: %s", enable)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||||
"github.com/openimsdk/protocol/msg"
|
"github.com/openimsdk/protocol/msg"
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type UserNotificationSender struct {
|
type UserNotificationSender struct {
|
||||||
*rpcclient.NotificationSender
|
*notification.NotificationSender
|
||||||
getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error)
|
getUsersInfo func(ctx context.Context, userIDs []string) ([]common_user.CommonUser, error)
|
||||||
// db controller
|
// db controller
|
||||||
db controller.UserDatabase
|
db controller.UserDatabase
|
||||||
@@ -63,7 +64,7 @@ func WithUserFunc(
|
|||||||
|
|
||||||
func NewUserNotificationSender(config *Config, msgClient *rpcli.MsgClient, opts ...userNotificationSenderOptions) *UserNotificationSender {
|
func NewUserNotificationSender(config *Config, msgClient *rpcli.MsgClient, opts ...userNotificationSenderOptions) *UserNotificationSender {
|
||||||
f := &UserNotificationSender{
|
f := &UserNotificationSender{
|
||||||
NotificationSender: rpcclient.NewNotificationSender(&config.NotificationConfig, rpcclient.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
NotificationSender: notification.NewNotificationSender(&config.NotificationConfig, notification.WithRpcClient(func(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
||||||
return msgClient.SendMsg(ctx, req)
|
return msgClient.SendMsg(ctx, req)
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-2
@@ -4,14 +4,23 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/openimsdk/gomake/mageutil"
|
"flag"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/openimsdk/gomake/mageutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Default = Build
|
var Default = Build
|
||||||
|
|
||||||
func Build() {
|
func Build() {
|
||||||
mageutil.Build()
|
flag.Parse()
|
||||||
|
|
||||||
|
bin := flag.Args()
|
||||||
|
if len(bin) != 0 {
|
||||||
|
bin = bin[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
mageutil.Build(bin)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start() {
|
func Start() {
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
"github.com/openimsdk/tools/db/mongoutil"
|
"github.com/openimsdk/tools/db/mongoutil"
|
||||||
"github.com/openimsdk/tools/db/redisutil"
|
"github.com/openimsdk/tools/db/redisutil"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
"github.com/openimsdk/tools/s3/aws"
|
"github.com/openimsdk/tools/s3/aws"
|
||||||
"github.com/openimsdk/tools/s3/cos"
|
"github.com/openimsdk/tools/s3/cos"
|
||||||
"github.com/openimsdk/tools/s3/kodo"
|
"github.com/openimsdk/tools/s3/kodo"
|
||||||
@@ -384,6 +384,12 @@ type Share struct {
|
|||||||
RpcRegisterName RpcRegisterName `mapstructure:"rpcRegisterName"`
|
RpcRegisterName RpcRegisterName `mapstructure:"rpcRegisterName"`
|
||||||
IMAdminUserID []string `mapstructure:"imAdminUserID"`
|
IMAdminUserID []string `mapstructure:"imAdminUserID"`
|
||||||
MultiLogin MultiLogin `mapstructure:"multiLogin"`
|
MultiLogin MultiLogin `mapstructure:"multiLogin"`
|
||||||
|
RPCMaxBodySize MaxRequestBody `mapstructure:"rpcMaxBodySize"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MaxRequestBody struct {
|
||||||
|
RequestMaxBodySize int `mapstructure:"requestMaxBodySize"`
|
||||||
|
ResponseMaxBodySize int `mapstructure:"responseMaxBodySize"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MultiLogin struct {
|
type MultiLogin struct {
|
||||||
|
|||||||
@@ -15,8 +15,10 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ConfKey = "conf"
|
MountConfigFilePath = "CONFIG_PATH"
|
||||||
ETCD = "etcd"
|
DeploymentType = "DEPLOYMENT_TYPE"
|
||||||
|
KUBERNETES = "kubernetes"
|
||||||
|
ETCD = "etcd"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
var EnvPrefixMap map[string]string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
EnvPrefixMap = make(map[string]string)
|
||||||
|
fileNames := []string{
|
||||||
|
FileName, NotificationFileName, ShareFileName, WebhooksConfigFileName,
|
||||||
|
KafkaConfigFileName, RedisConfigFileName,
|
||||||
|
MongodbConfigFileName, MinioConfigFileName, LogConfigFileName,
|
||||||
|
OpenIMAPICfgFileName, OpenIMCronTaskCfgFileName, OpenIMMsgGatewayCfgFileName,
|
||||||
|
OpenIMMsgTransferCfgFileName, OpenIMPushCfgFileName, OpenIMRPCAuthCfgFileName,
|
||||||
|
OpenIMRPCConversationCfgFileName, OpenIMRPCFriendCfgFileName, OpenIMRPCGroupCfgFileName,
|
||||||
|
OpenIMRPCMsgCfgFileName, OpenIMRPCThirdCfgFileName, OpenIMRPCUserCfgFileName, DiscoveryConfigFilename,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fileName := range fileNames {
|
||||||
|
envKey := strings.TrimSuffix(strings.TrimSuffix(fileName, ".yml"), ".yaml")
|
||||||
|
envKey = "IMENV_" + envKey
|
||||||
|
envKey = strings.ToUpper(strings.ReplaceAll(envKey, "-", "_"))
|
||||||
|
EnvPrefixMap[fileName] = envKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
FlagConf = "config_folder_path"
|
||||||
|
FlagTransferIndex = "index"
|
||||||
|
)
|
||||||
@@ -58,10 +58,13 @@ func GetProjectRoot() (string, error) {
|
|||||||
return projectRoot, nil
|
return projectRoot, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetOptionsByNotification(cfg NotificationConfig) msgprocessor.Options {
|
func GetOptionsByNotification(cfg NotificationConfig, sendMessage *bool) msgprocessor.Options {
|
||||||
opts := msgprocessor.NewOptions()
|
opts := msgprocessor.NewOptions()
|
||||||
|
|
||||||
if cfg.UnreadCount {
|
if sendMessage != nil {
|
||||||
|
cfg.IsSendMsg = *sendMessage
|
||||||
|
}
|
||||||
|
if cfg.IsSendMsg {
|
||||||
opts = msgprocessor.WithOptions(opts, msgprocessor.WithUnreadCount(true))
|
opts = msgprocessor.WithOptions(opts, msgprocessor.WithUnreadCount(true))
|
||||||
}
|
}
|
||||||
if cfg.OfflinePush.Enable {
|
if cfg.OfflinePush.Enable {
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ package convert
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/notification/common_user"
|
||||||
"github.com/openimsdk/protocol/relation"
|
"github.com/openimsdk/protocol/relation"
|
||||||
|
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
@@ -98,7 +100,7 @@ func FriendOnlyDB2PbOnly(friendsDB []*model.Friend) []*relation.FriendInfoOnly {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func FriendRequestDB2Pb(ctx context.Context, friendRequests []*model.FriendRequest, getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error)) ([]*sdkws.FriendRequest, error) {
|
func FriendRequestDB2Pb(ctx context.Context, friendRequests []*model.FriendRequest, getUsers func(ctx context.Context, userIDs []string) (map[string]common_user.CommonUser, error)) ([]*sdkws.FriendRequest, error) {
|
||||||
if len(friendRequests) == 0 {
|
if len(friendRequests) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -117,11 +119,11 @@ func FriendRequestDB2Pb(ctx context.Context, friendRequests []*model.FriendReque
|
|||||||
fromUser := users[friendRequest.FromUserID]
|
fromUser := users[friendRequest.FromUserID]
|
||||||
res = append(res, &sdkws.FriendRequest{
|
res = append(res, &sdkws.FriendRequest{
|
||||||
FromUserID: friendRequest.FromUserID,
|
FromUserID: friendRequest.FromUserID,
|
||||||
FromNickname: fromUser.Nickname,
|
FromNickname: fromUser.GetNickname(),
|
||||||
FromFaceURL: fromUser.FaceURL,
|
FromFaceURL: fromUser.GetFaceURL(),
|
||||||
ToUserID: friendRequest.ToUserID,
|
ToUserID: friendRequest.ToUserID,
|
||||||
ToNickname: toUser.Nickname,
|
ToNickname: toUser.GetNickname(),
|
||||||
ToFaceURL: toUser.FaceURL,
|
ToFaceURL: toUser.GetFaceURL(),
|
||||||
HandleResult: friendRequest.HandleResult,
|
HandleResult: friendRequest.HandleResult,
|
||||||
ReqMsg: friendRequest.ReqMsg,
|
ReqMsg: friendRequest.ReqMsg,
|
||||||
CreateTime: friendRequest.CreateTime.UnixMilli(),
|
CreateTime: friendRequest.CreateTime.UnixMilli(),
|
||||||
|
|||||||
@@ -18,17 +18,22 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister/kubernetes"
|
|
||||||
"github.com/openimsdk/tools/discovery"
|
"github.com/openimsdk/tools/discovery"
|
||||||
"github.com/openimsdk/tools/discovery/etcd"
|
"github.com/openimsdk/tools/discovery/etcd"
|
||||||
|
"github.com/openimsdk/tools/discovery/kubernetes"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewDiscoveryRegister creates a new service discovery and registry client based on the provided environment type.
|
// NewDiscoveryRegister creates a new service discovery and registry client based on the provided environment type.
|
||||||
func NewDiscoveryRegister(discovery *config.Discovery, share *config.Share, watchNames []string) (discovery.SvcDiscoveryRegistry, error) {
|
func NewDiscoveryRegister(discovery *config.Discovery, share *config.Share, watchNames []string) (discovery.SvcDiscoveryRegistry, error) {
|
||||||
switch discovery.Enable {
|
switch discovery.Enable {
|
||||||
case "k8s":
|
case "k8s":
|
||||||
return kubernetes.NewK8sDiscoveryRegister(share.RpcRegisterName.MessageGateway)
|
return kubernetes.NewKubernetesConnManager("default",
|
||||||
|
grpc.WithDefaultCallOptions(
|
||||||
|
grpc.MaxCallSendMsgSize(1024*1024*20),
|
||||||
|
),
|
||||||
|
)
|
||||||
case "etcd":
|
case "etcd":
|
||||||
return etcd.NewSvcDiscoveryRegistry(
|
return etcd.NewSvcDiscoveryRegistry(
|
||||||
discovery.Etcd.RootDirectory,
|
discovery.Etcd.RootDirectory,
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
// Copyright © 2024 OpenIM. 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.
|
|
||||||
// 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 kubernetes // import "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister/kubernetes"
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
// Copyright © 2023 OpenIM. 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.
|
|
||||||
// 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 kubernetes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/openimsdk/tools/discovery"
|
|
||||||
"github.com/openimsdk/tools/log"
|
|
||||||
"github.com/stathat/consistent"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
// K8sDR represents the Kubernetes service discovery and registration client.
|
|
||||||
type K8sDR struct {
|
|
||||||
options []grpc.DialOption
|
|
||||||
rpcRegisterAddr string
|
|
||||||
gatewayHostConsistent *consistent.Consistent
|
|
||||||
gatewayName string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewK8sDiscoveryRegister(gatewayName string) (discovery.SvcDiscoveryRegistry, error) {
|
|
||||||
gatewayConsistent := consistent.New()
|
|
||||||
gatewayHosts := getMsgGatewayHost(context.Background(), gatewayName)
|
|
||||||
for _, v := range gatewayHosts {
|
|
||||||
gatewayConsistent.Add(v)
|
|
||||||
}
|
|
||||||
return &K8sDR{gatewayHostConsistent: gatewayConsistent}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) Register(serviceName, host string, port int, opts ...grpc.DialOption) error {
|
|
||||||
if serviceName != cli.gatewayName {
|
|
||||||
cli.rpcRegisterAddr = serviceName
|
|
||||||
} else {
|
|
||||||
cli.rpcRegisterAddr = getSelfHost(context.Background(), cli.gatewayName)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) UnRegister() error {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) CreateRpcRootNodes(serviceNames []string) error {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) RegisterConf2Registry(key string, conf []byte) error {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) GetConfFromRegistry(key string) ([]byte, error) {
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) GetUserIdHashGatewayHost(ctx context.Context, userId string) (string, error) {
|
|
||||||
host, err := cli.gatewayHostConsistent.Get(userId)
|
|
||||||
if err != nil {
|
|
||||||
log.ZError(ctx, "GetUserIdHashGatewayHost error", err)
|
|
||||||
}
|
|
||||||
return host, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSelfHost(ctx context.Context, gatewayName string) string {
|
|
||||||
port := 88
|
|
||||||
instance := "openimserver"
|
|
||||||
selfPodName := os.Getenv("MY_POD_NAME")
|
|
||||||
ns := os.Getenv("MY_POD_NAMESPACE")
|
|
||||||
statefuleIndex := 0
|
|
||||||
gatewayEnds := strings.Split(gatewayName, ":")
|
|
||||||
if len(gatewayEnds) != 2 {
|
|
||||||
log.ZError(ctx, "msggateway RpcRegisterName is error:config.RpcRegisterName.OpenImMessageGatewayName", errors.New("config error"))
|
|
||||||
} else {
|
|
||||||
port, _ = strconv.Atoi(gatewayEnds[1])
|
|
||||||
}
|
|
||||||
podInfo := strings.Split(selfPodName, "-")
|
|
||||||
instance = podInfo[0]
|
|
||||||
count := len(podInfo)
|
|
||||||
statefuleIndex, _ = strconv.Atoi(podInfo[count-1])
|
|
||||||
host := fmt.Sprintf("%s-openim-msggateway-%d.%s-openim-msggateway-headless.%s.svc.cluster.local:%d", instance, statefuleIndex, instance, ns, port)
|
|
||||||
return host
|
|
||||||
}
|
|
||||||
|
|
||||||
// like openimserver-openim-msggateway-0.openimserver-openim-msggateway-headless.openim-lin.svc.cluster.local:88.
|
|
||||||
// Replica set in kubernetes environment
|
|
||||||
func getMsgGatewayHost(ctx context.Context, gatewayName string) []string {
|
|
||||||
port := 88
|
|
||||||
instance := "openimserver"
|
|
||||||
selfPodName := os.Getenv("MY_POD_NAME")
|
|
||||||
replicas := os.Getenv("MY_MSGGATEWAY_REPLICACOUNT")
|
|
||||||
ns := os.Getenv("MY_POD_NAMESPACE")
|
|
||||||
gatewayEnds := strings.Split(gatewayName, ":")
|
|
||||||
if len(gatewayEnds) != 2 {
|
|
||||||
log.ZError(ctx, "msggateway RpcRegisterName is error:config.RpcRegisterName.OpenImMessageGatewayName", errors.New("config error"))
|
|
||||||
} else {
|
|
||||||
port, _ = strconv.Atoi(gatewayEnds[1])
|
|
||||||
}
|
|
||||||
nReplicas, _ := strconv.Atoi(replicas)
|
|
||||||
podInfo := strings.Split(selfPodName, "-")
|
|
||||||
instance = podInfo[0]
|
|
||||||
var ret []string
|
|
||||||
for i := 0; i < nReplicas; i++ {
|
|
||||||
host := fmt.Sprintf("%s-openim-msggateway-%d.%s-openim-msggateway-headless.%s.svc.cluster.local:%d", instance, i, instance, ns, port)
|
|
||||||
ret = append(ret, host)
|
|
||||||
}
|
|
||||||
log.ZDebug(ctx, "getMsgGatewayHost", "instance", instance, "selfPodName", selfPodName, "replicas", replicas, "ns", ns, "ret", ret)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetConns returns the gRPC client connections to the specified service.
|
|
||||||
func (cli *K8sDR) GetConns(ctx context.Context, serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error) {
|
|
||||||
|
|
||||||
// This conditional checks if the serviceName is not the OpenImMessageGatewayName.
|
|
||||||
// It seems to handle a special case for the OpenImMessageGateway.
|
|
||||||
if serviceName != cli.gatewayName {
|
|
||||||
// DialContext creates a client connection to the given target (serviceName) using the specified context.
|
|
||||||
// 'cli.options' are likely default or common options for all connections in this struct.
|
|
||||||
// 'opts...' allows for additional gRPC dial options to be passed and used.
|
|
||||||
conn, err := grpc.DialContext(ctx, serviceName, append(cli.options, opts...)...)
|
|
||||||
|
|
||||||
// The function returns a slice of client connections with the new connection, or an error if occurred.
|
|
||||||
return []*grpc.ClientConn{conn}, err
|
|
||||||
} else {
|
|
||||||
// This block is executed if the serviceName is OpenImMessageGatewayName.
|
|
||||||
// 'ret' will accumulate the connections to return.
|
|
||||||
var ret []*grpc.ClientConn
|
|
||||||
|
|
||||||
// getMsgGatewayHost presumably retrieves hosts for the message gateway service.
|
|
||||||
// The context is passed, likely for cancellation and timeout control.
|
|
||||||
gatewayHosts := getMsgGatewayHost(ctx, cli.gatewayName)
|
|
||||||
|
|
||||||
// Iterating over the retrieved gateway hosts.
|
|
||||||
for _, host := range gatewayHosts {
|
|
||||||
// Establishes a connection to each host.
|
|
||||||
// Again, appending cli.options with any additional opts provided.
|
|
||||||
conn, err := grpc.DialContext(ctx, host, append(cli.options, opts...)...)
|
|
||||||
|
|
||||||
// If there's an error while dialing any host, the function returns immediately with the error.
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
// If the connection is successful, it is added to the 'ret' slice.
|
|
||||||
ret = append(ret, conn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// After all hosts are processed, the slice of connections is returned.
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
|
|
||||||
|
|
||||||
return grpc.DialContext(ctx, serviceName, append(cli.options, opts...)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) GetSelfConnTarget() string {
|
|
||||||
|
|
||||||
return cli.rpcRegisterAddr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) AddOption(opts ...grpc.DialOption) {
|
|
||||||
cli.options = append(cli.options, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) CloseConn(conn *grpc.ClientConn) {
|
|
||||||
conn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// do not use this method for call rpc.
|
|
||||||
func (cli *K8sDR) GetClientLocalConns() map[string][]*grpc.ClientConn {
|
|
||||||
log.ZError(context.Background(), "should not call this function!", nil)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *K8sDR) Close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
@@ -43,6 +44,36 @@ import (
|
|||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getConfigRpcMaxRequestBody(value reflect.Value) *conf.MaxRequestBody {
|
||||||
|
for value.Kind() == reflect.Pointer {
|
||||||
|
value = value.Elem()
|
||||||
|
}
|
||||||
|
if value.Kind() == reflect.Struct {
|
||||||
|
num := value.NumField()
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
field := value.Field(i)
|
||||||
|
if !field.CanInterface() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for field.Kind() == reflect.Pointer {
|
||||||
|
field = field.Elem()
|
||||||
|
}
|
||||||
|
switch elem := field.Interface().(type) {
|
||||||
|
case conf.Share:
|
||||||
|
return &elem.RPCMaxBodySize
|
||||||
|
case conf.MaxRequestBody:
|
||||||
|
return &elem
|
||||||
|
}
|
||||||
|
if field.Kind() == reflect.Struct {
|
||||||
|
if elem := getConfigRpcMaxRequestBody(field); elem != nil {
|
||||||
|
return elem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Start rpc server.
|
// Start rpc server.
|
||||||
func Start[T any](ctx context.Context, discovery *conf.Discovery, prometheusConfig *conf.Prometheus, listenIP,
|
func Start[T any](ctx context.Context, discovery *conf.Discovery, prometheusConfig *conf.Prometheus, listenIP,
|
||||||
registerIP string, autoSetPorts bool, rpcPorts []int, index int, rpcRegisterName string, share *conf.Share, config T,
|
registerIP string, autoSetPorts bool, rpcPorts []int, index int, rpcRegisterName string, share *conf.Share, config T,
|
||||||
@@ -50,6 +81,19 @@ func Start[T any](ctx context.Context, discovery *conf.Discovery, prometheusConf
|
|||||||
rpcFn func(ctx context.Context, config T, client discovery.SvcDiscoveryRegistry, server *grpc.Server) error,
|
rpcFn func(ctx context.Context, config T, client discovery.SvcDiscoveryRegistry, server *grpc.Server) error,
|
||||||
options ...grpc.ServerOption) error {
|
options ...grpc.ServerOption) error {
|
||||||
|
|
||||||
|
maxRequestBody := &share.RPCMaxBodySize
|
||||||
|
var clientOptions []grpc.DialOption
|
||||||
|
if maxRequestBody != nil {
|
||||||
|
if maxRequestBody.RequestMaxBodySize > 0 {
|
||||||
|
options = append(options, grpc.MaxRecvMsgSize(maxRequestBody.RequestMaxBodySize))
|
||||||
|
clientOptions = append(clientOptions, grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(maxRequestBody.RequestMaxBodySize)))
|
||||||
|
}
|
||||||
|
if maxRequestBody.ResponseMaxBodySize > 0 {
|
||||||
|
options = append(options, grpc.MaxSendMsgSize(maxRequestBody.ResponseMaxBodySize))
|
||||||
|
clientOptions = append(clientOptions, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxRequestBody.ResponseMaxBodySize)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rpcTcpAddr string
|
rpcTcpAddr string
|
||||||
netDone = make(chan struct{}, 2)
|
netDone = make(chan struct{}, 2)
|
||||||
@@ -93,6 +137,10 @@ func Start[T any](ctx context.Context, discovery *conf.Discovery, prometheusConf
|
|||||||
defer client.Close()
|
defer client.Close()
|
||||||
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
||||||
|
|
||||||
|
if len(clientOptions) > 0 {
|
||||||
|
client.AddOption(clientOptions...)
|
||||||
|
}
|
||||||
|
|
||||||
// var reg *prometheus.Registry
|
// var reg *prometheus.Registry
|
||||||
// var metric *grpcprometheus.ServerMetrics
|
// var metric *grpcprometheus.ServerMetrics
|
||||||
if prometheusConfig.Enable {
|
if prometheusConfig.Enable {
|
||||||
@@ -167,6 +215,7 @@ func Start[T any](ctx context.Context, discovery *conf.Discovery, prometheusConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = client.Register(
|
err = client.Register(
|
||||||
|
ctx,
|
||||||
rpcRegisterName,
|
rpcRegisterName,
|
||||||
registerIP,
|
registerIP,
|
||||||
port,
|
port,
|
||||||
|
|||||||
@@ -59,16 +59,15 @@ func (a *authDatabase) BatchSetTokenMapByUidPid(ctx context.Context, tokens []st
|
|||||||
setMap := make(map[string]map[string]any)
|
setMap := make(map[string]map[string]any)
|
||||||
for _, token := range tokens {
|
for _, token := range tokens {
|
||||||
claims, err := tokenverify.GetClaimFromToken(token, authverify.Secret(a.accessSecret))
|
claims, err := tokenverify.GetClaimFromToken(token, authverify.Secret(a.accessSecret))
|
||||||
key := cachekey.GetTokenKey(claims.UserID, claims.PlatformID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
key := cachekey.GetTokenKey(claims.UserID, claims.PlatformID)
|
||||||
|
if v, ok := setMap[key]; ok {
|
||||||
|
v[token] = constant.KickedToken
|
||||||
} else {
|
} else {
|
||||||
if v, ok := setMap[key]; ok {
|
setMap[key] = map[string]any{
|
||||||
v[token] = constant.KickedToken
|
token: constant.KickedToken,
|
||||||
} else {
|
|
||||||
setMap[key] = map[string]any{
|
|
||||||
token: constant.KickedToken,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,11 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
@@ -61,10 +62,10 @@ type FriendDatabase interface {
|
|||||||
PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error)
|
PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error)
|
||||||
|
|
||||||
// PageFriendRequestFromMe retrieves the friend requests sent by the user with pagination
|
// PageFriendRequestFromMe retrieves the friend requests sent by the user with pagination
|
||||||
PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error)
|
PageFriendRequestFromMe(ctx context.Context, userID string, handleResults []int, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error)
|
||||||
|
|
||||||
// PageFriendRequestToMe retrieves the friend requests received by the user with pagination
|
// PageFriendRequestToMe retrieves the friend requests received by the user with pagination
|
||||||
PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error)
|
PageFriendRequestToMe(ctx context.Context, userID string, handleResults []int, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error)
|
||||||
|
|
||||||
// FindFriendsWithError fetches specified friends of a user and returns an error if any do not exist
|
// FindFriendsWithError fetches specified friends of a user and returns an error if any do not exist
|
||||||
FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*model.Friend, err error)
|
FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*model.Friend, err error)
|
||||||
@@ -87,6 +88,8 @@ type FriendDatabase interface {
|
|||||||
FindFriendUserID(ctx context.Context, friendUserID string) ([]string, error)
|
FindFriendUserID(ctx context.Context, friendUserID string) ([]string, error)
|
||||||
|
|
||||||
OwnerIncrVersion(ctx context.Context, ownerUserID string, friendUserIDs []string, state int32) error
|
OwnerIncrVersion(ctx context.Context, ownerUserID string, friendUserIDs []string, state int32) error
|
||||||
|
|
||||||
|
GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type friendDatabase struct {
|
type friendDatabase struct {
|
||||||
@@ -334,13 +337,13 @@ func (f *friendDatabase) PageInWhoseFriends(ctx context.Context, friendUserID st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PageFriendRequestFromMe retrieves friend requests sent by me. It does not return an error if the result is empty.
|
// PageFriendRequestFromMe retrieves friend requests sent by me. It does not return an error if the result is empty.
|
||||||
func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) {
|
func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, handleResults []int, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) {
|
||||||
return f.friendRequest.FindFromUserID(ctx, userID, pagination)
|
return f.friendRequest.FindFromUserID(ctx, userID, handleResults, pagination)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PageFriendRequestToMe retrieves friend requests received by me. It does not return an error if the result is empty.
|
// PageFriendRequestToMe retrieves friend requests received by me. It does not return an error if the result is empty.
|
||||||
func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) {
|
func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, handleResults []int, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) {
|
||||||
return f.friendRequest.FindToUserID(ctx, userID, pagination)
|
return f.friendRequest.FindToUserID(ctx, userID, handleResults, pagination)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindFriendsWithError retrieves specified friends' information for ownerUserID. Returns an error if any friend does not exist.
|
// FindFriendsWithError retrieves specified friends' information for ownerUserID. Returns an error if any friend does not exist.
|
||||||
@@ -397,3 +400,7 @@ func (f *friendDatabase) OwnerIncrVersion(ctx context.Context, ownerUserID strin
|
|||||||
}
|
}
|
||||||
return f.cache.DelMaxFriendVersion(ownerUserID).ChainExecDel(ctx)
|
return f.cache.DelMaxFriendVersion(ownerUserID).ChainExecDel(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *friendDatabase) GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error) {
|
||||||
|
return f.friendRequest.GetUnhandledCount(ctx, userID, ts)
|
||||||
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ type GroupDatabase interface {
|
|||||||
// FindUserManagedGroupID retrieves group IDs managed by a user.
|
// FindUserManagedGroupID retrieves group IDs managed by a user.
|
||||||
FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error)
|
FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error)
|
||||||
// PageGroupRequest paginates through group requests for specified groups.
|
// PageGroupRequest paginates through group requests for specified groups.
|
||||||
PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*model.GroupRequest, error)
|
PageGroupRequest(ctx context.Context, groupIDs []string, handleResults []int, pagination pagination.Pagination) (int64, []*model.GroupRequest, error)
|
||||||
// GetGroupRoleLevelMemberIDs retrieves user IDs of group members with a specific role level.
|
// GetGroupRoleLevelMemberIDs retrieves user IDs of group members with a specific role level.
|
||||||
GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error)
|
GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error)
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ type GroupDatabase interface {
|
|||||||
// FindGroupRequests retrieves multiple group join requests.
|
// FindGroupRequests retrieves multiple group join requests.
|
||||||
FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupRequest, error)
|
FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupRequest, error)
|
||||||
// PageGroupRequestUser paginates through group join requests made by a user.
|
// PageGroupRequestUser paginates through group join requests made by a user.
|
||||||
PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*model.GroupRequest, error)
|
PageGroupRequestUser(ctx context.Context, userID string, groupIDs []string, handleResults []int, pagination pagination.Pagination) (int64, []*model.GroupRequest, error)
|
||||||
|
|
||||||
// CountTotal counts the total number of groups as of a certain date.
|
// CountTotal counts the total number of groups as of a certain date.
|
||||||
CountTotal(ctx context.Context, before *time.Time) (count int64, err error)
|
CountTotal(ctx context.Context, before *time.Time) (count int64, err error)
|
||||||
@@ -124,6 +124,8 @@ type GroupDatabase interface {
|
|||||||
SearchJoinGroup(ctx context.Context, userID string, keyword string, pagination pagination.Pagination) (int64, []*model.Group, error)
|
SearchJoinGroup(ctx context.Context, userID string, keyword string, pagination pagination.Pagination) (int64, []*model.Group, error)
|
||||||
|
|
||||||
FindJoinGroupID(ctx context.Context, userID string) ([]string, error)
|
FindJoinGroupID(ctx context.Context, userID string) ([]string, error)
|
||||||
|
|
||||||
|
GetGroupApplicationUnhandledCount(ctx context.Context, groupIDs []string, ts int64) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGroupDatabase(
|
func NewGroupDatabase(
|
||||||
@@ -304,8 +306,8 @@ func (g *groupDatabase) FindUserManagedGroupID(ctx context.Context, userID strin
|
|||||||
return g.groupMemberDB.FindUserManagedGroupID(ctx, userID)
|
return g.groupMemberDB.FindUserManagedGroupID(ctx, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupDatabase) PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*model.GroupRequest, error) {
|
func (g *groupDatabase) PageGroupRequest(ctx context.Context, groupIDs []string, handleResults []int, pagination pagination.Pagination) (int64, []*model.GroupRequest, error) {
|
||||||
return g.groupRequestDB.PageGroup(ctx, groupIDs, pagination)
|
return g.groupRequestDB.PageGroup(ctx, groupIDs, handleResults, pagination)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*model.GroupMember, err error) {
|
func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*model.GroupMember, err error) {
|
||||||
@@ -463,16 +465,12 @@ func (g *groupDatabase) CreateGroupRequest(ctx context.Context, requests []*mode
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupDatabase) TakeGroupRequest(
|
func (g *groupDatabase) TakeGroupRequest(ctx context.Context, groupID string, userID string) (*model.GroupRequest, error) {
|
||||||
ctx context.Context,
|
|
||||||
groupID string,
|
|
||||||
userID string,
|
|
||||||
) (*model.GroupRequest, error) {
|
|
||||||
return g.groupRequestDB.Take(ctx, groupID, userID)
|
return g.groupRequestDB.Take(ctx, groupID, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupDatabase) PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*model.GroupRequest, error) {
|
func (g *groupDatabase) PageGroupRequestUser(ctx context.Context, userID string, groupIDs []string, handleResults []int, pagination pagination.Pagination) (int64, []*model.GroupRequest, error) {
|
||||||
return g.groupRequestDB.Page(ctx, userID, pagination)
|
return g.groupRequestDB.Page(ctx, userID, groupIDs, handleResults, pagination)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
|
func (g *groupDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
|
||||||
@@ -565,3 +563,7 @@ func (g *groupDatabase) MemberGroupIncrVersion(ctx context.Context, groupID stri
|
|||||||
}
|
}
|
||||||
return g.cache.DelMaxGroupMemberVersion(groupID).ChainExecDel(ctx)
|
return g.cache.DelMaxGroupMemberVersion(groupID).ChainExecDel(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *groupDatabase) GetGroupApplicationUnhandledCount(ctx context.Context, groupIDs []string, ts int64) (int64, error) {
|
||||||
|
return g.groupRequestDB.GetUnhandledCount(ctx, groupIDs, ts)
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/openimsdk/tools/utils/jsonutil"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
|
"github.com/openimsdk/tools/utils/jsonutil"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
|
|
||||||
@@ -37,7 +39,6 @@ import (
|
|||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -309,7 +310,7 @@ func (db *commonMsgDatabase) handlerDBMsg(ctx context.Context, cache map[int64][
|
|||||||
log.ZError(ctx, "json.Unmarshal", err)
|
log.ZError(ctx, "json.Unmarshal", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if quoteMsg.QuoteMessage == nil || quoteMsg.QuoteMessage.Content == "" {
|
if quoteMsg.QuoteMessage == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if quoteMsg.QuoteMessage.Content == "e30=" {
|
if quoteMsg.QuoteMessage.Content == "e30=" {
|
||||||
@@ -722,13 +723,13 @@ func (db *commonMsgDatabase) DeleteDoc(ctx context.Context, docID string) error
|
|||||||
if index <= 0 {
|
if index <= 0 {
|
||||||
return errs.ErrInternalServer.WrapMsg("docID is invalid", "docID", docID)
|
return errs.ErrInternalServer.WrapMsg("docID is invalid", "docID", docID)
|
||||||
}
|
}
|
||||||
index, err := strconv.Atoi(docID[index+1:])
|
docIndex, err := strconv.Atoi(docID[index+1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.WrapMsg(err, "strconv.Atoi", "docID", docID)
|
return errs.WrapMsg(err, "strconv.Atoi", "docID", docID)
|
||||||
}
|
}
|
||||||
conversationID := docID[:index]
|
conversationID := docID[:index]
|
||||||
seqs := make([]int64, db.msgTable.GetSingleGocMsgNum())
|
seqs := make([]int64, db.msgTable.GetSingleGocMsgNum())
|
||||||
minSeq := db.msgTable.GetMinSeq(index)
|
minSeq := db.msgTable.GetMinSeq(docIndex)
|
||||||
for i := range seqs {
|
for i := range seqs {
|
||||||
seqs[i] = minSeq + int64(i)
|
seqs[i] = minSeq + int64(i)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
"github.com/openimsdk/protocol/constant"
|
"github.com/openimsdk/protocol/constant"
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
|
|
||||||
@@ -14,7 +16,6 @@ import (
|
|||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ import (
|
|||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
"github.com/openimsdk/protocol/push"
|
"github.com/openimsdk/protocol/push"
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/log"
|
"github.com/openimsdk/tools/log"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PushDatabase interface {
|
type PushDatabase interface {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type S3Database interface {
|
type S3Database interface {
|
||||||
PartLimit() *s3.PartLimit
|
PartLimit() (*s3.PartLimit, error)
|
||||||
PartSize(ctx context.Context, size int64) (int64, error)
|
PartSize(ctx context.Context, size int64) (int64, error)
|
||||||
AuthSign(ctx context.Context, uploadID string, partNumbers []int) (*s3.AuthSignResult, error)
|
AuthSign(ctx context.Context, uploadID string, partNumbers []int) (*s3.AuthSignResult, error)
|
||||||
InitiateMultipartUpload(ctx context.Context, hash string, size int64, expire time.Duration, maxParts int) (*cont.InitiateUploadResult, error)
|
InitiateMultipartUpload(ctx context.Context, hash string, size int64, expire time.Duration, maxParts int) (*cont.InitiateUploadResult, error)
|
||||||
@@ -65,7 +65,7 @@ func (s *s3Database) PartSize(ctx context.Context, size int64) (int64, error) {
|
|||||||
return s.s3.PartSize(ctx, size)
|
return s.s3.PartSize(ctx, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *s3Database) PartLimit() *s3.PartLimit {
|
func (s *s3Database) PartLimit() (*s3.PartLimit, error) {
|
||||||
return s.s3.PartLimit()
|
return s.s3.PartLimit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package database
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
"github.com/openimsdk/tools/db/pagination"
|
"github.com/openimsdk/tools/db/pagination"
|
||||||
)
|
)
|
||||||
@@ -33,8 +34,9 @@ type FriendRequest interface {
|
|||||||
Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error)
|
Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error)
|
||||||
Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error)
|
Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error)
|
||||||
// Get list of friend requests received by toUserID
|
// Get list of friend requests received by toUserID
|
||||||
FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error)
|
FindToUserID(ctx context.Context, toUserID string, handleResults []int, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error)
|
||||||
// Get list of friend requests sent by fromUserID
|
// Get list of friend requests sent by fromUserID
|
||||||
FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error)
|
FindFromUserID(ctx context.Context, fromUserID string, handleResults []int, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error)
|
||||||
FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error)
|
FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error)
|
||||||
|
GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ package database
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
"github.com/openimsdk/tools/db/pagination"
|
"github.com/openimsdk/tools/db/pagination"
|
||||||
)
|
)
|
||||||
@@ -26,6 +27,7 @@ type GroupRequest interface {
|
|||||||
UpdateHandler(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32) (err error)
|
UpdateHandler(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32) (err error)
|
||||||
Take(ctx context.Context, groupID string, userID string) (groupRequest *model.GroupRequest, err error)
|
Take(ctx context.Context, groupID string, userID string) (groupRequest *model.GroupRequest, err error)
|
||||||
FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupRequest, error)
|
FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupRequest, error)
|
||||||
Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error)
|
Page(ctx context.Context, userID string, groupIDs []string, handleResults []int, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error)
|
||||||
PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error)
|
PageGroup(ctx context.Context, groupIDs []string, handleResults []int, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error)
|
||||||
|
GetUnhandledCount(ctx context.Context, groupIDs []string, ts int64) (int64, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,7 +243,14 @@ func (c *ConversationMgo) FindRandConversation(ctx context.Context, ts int64, li
|
|||||||
"$add": []any{
|
"$add": []any{
|
||||||
bson.M{
|
bson.M{
|
||||||
"$toLong": "$latest_msg_destruct_time",
|
"$toLong": "$latest_msg_destruct_time",
|
||||||
}, "$msg_destruct_time"},
|
},
|
||||||
|
bson.M{
|
||||||
|
"$multiply": []any{
|
||||||
|
"$msg_destruct_time",
|
||||||
|
1000, // convert to milliseconds
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,24 +16,35 @@ package mgo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
|
|
||||||
"github.com/openimsdk/tools/db/mongoutil"
|
|
||||||
"github.com/openimsdk/tools/db/pagination"
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
|
||||||
|
"github.com/openimsdk/tools/db/mongoutil"
|
||||||
|
"github.com/openimsdk/tools/db/pagination"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewFriendRequestMongo(db *mongo.Database) (database.FriendRequest, error) {
|
func NewFriendRequestMongo(db *mongo.Database) (database.FriendRequest, error) {
|
||||||
coll := db.Collection(database.FriendRequestName)
|
coll := db.Collection(database.FriendRequestName)
|
||||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
|
||||||
Keys: bson.D{
|
{
|
||||||
{Key: "from_user_id", Value: 1},
|
Keys: bson.D{
|
||||||
{Key: "to_user_id", Value: 1},
|
{Key: "from_user_id", Value: 1},
|
||||||
|
{Key: "to_user_id", Value: 1},
|
||||||
|
},
|
||||||
|
Options: options.Index().SetUnique(true),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: bson.D{
|
||||||
|
{Key: "create_time", Value: -1},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Options: options.Index().SetUnique(true),
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -45,12 +56,24 @@ type FriendRequestMgo struct {
|
|||||||
coll *mongo.Collection
|
coll *mongo.Collection
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendRequestMgo) FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) {
|
func (f *FriendRequestMgo) sort() any {
|
||||||
return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, bson.M{"to_user_id": toUserID}, pagination)
|
return bson.D{{Key: "create_time", Value: -1}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendRequestMgo) FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) {
|
func (f *FriendRequestMgo) FindToUserID(ctx context.Context, toUserID string, handleResults []int, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) {
|
||||||
return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, bson.M{"from_user_id": fromUserID}, pagination)
|
filter := bson.M{"to_user_id": toUserID}
|
||||||
|
if len(handleResults) > 0 {
|
||||||
|
filter["handle_result"] = bson.M{"$in": handleResults}
|
||||||
|
}
|
||||||
|
return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, filter, pagination, options.Find().SetSort(f.sort()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FriendRequestMgo) FindFromUserID(ctx context.Context, fromUserID string, handleResults []int, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) {
|
||||||
|
filter := bson.M{"from_user_id": fromUserID}
|
||||||
|
if len(handleResults) > 0 {
|
||||||
|
filter["handle_result"] = bson.M{"$in": handleResults}
|
||||||
|
}
|
||||||
|
return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, filter, pagination, options.Find().SetSort(f.sort()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FriendRequestMgo) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error) {
|
func (f *FriendRequestMgo) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error) {
|
||||||
@@ -110,3 +133,11 @@ func (f *FriendRequestMgo) Find(ctx context.Context, fromUserID, toUserID string
|
|||||||
func (f *FriendRequestMgo) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error) {
|
func (f *FriendRequestMgo) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error) {
|
||||||
return f.Find(ctx, fromUserID, toUserID)
|
return f.Find(ctx, fromUserID, toUserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FriendRequestMgo) GetUnhandledCount(ctx context.Context, userID string, ts int64) (int64, error) {
|
||||||
|
filter := bson.M{"to_user_id": userID, "handle_result": 0}
|
||||||
|
if ts != 0 {
|
||||||
|
filter["create_time"] = bson.M{"$gt": time.Unix(ts, 0)}
|
||||||
|
}
|
||||||
|
return mongoutil.Count(ctx, f.coll, filter)
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,25 +16,36 @@ package mgo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||||
|
"github.com/openimsdk/tools/utils/datautil"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
|
||||||
"github.com/openimsdk/tools/db/mongoutil"
|
"github.com/openimsdk/tools/db/mongoutil"
|
||||||
"github.com/openimsdk/tools/db/pagination"
|
"github.com/openimsdk/tools/db/pagination"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewGroupRequestMgo(db *mongo.Database) (database.GroupRequest, error) {
|
func NewGroupRequestMgo(db *mongo.Database) (database.GroupRequest, error) {
|
||||||
coll := db.Collection(database.GroupRequestName)
|
coll := db.Collection(database.GroupRequestName)
|
||||||
_, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{
|
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
|
||||||
Keys: bson.D{
|
{
|
||||||
{Key: "group_id", Value: 1},
|
Keys: bson.D{
|
||||||
{Key: "user_id", Value: 1},
|
{Key: "group_id", Value: 1},
|
||||||
|
{Key: "user_id", Value: 1},
|
||||||
|
},
|
||||||
|
Options: options.Index().SetUnique(true),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Keys: bson.D{
|
||||||
|
{Key: "req_time", Value: -1},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Options: options.Index().SetUnique(true),
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err)
|
return nil, errs.Wrap(err)
|
||||||
@@ -66,10 +77,39 @@ func (g *GroupRequestMgo) FindGroupRequests(ctx context.Context, groupID string,
|
|||||||
return mongoutil.Find[*model.GroupRequest](ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}})
|
return mongoutil.Find[*model.GroupRequest](ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupRequestMgo) Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) {
|
func (g *GroupRequestMgo) sort() any {
|
||||||
return mongoutil.FindPage[*model.GroupRequest](ctx, g.coll, bson.M{"user_id": userID}, pagination)
|
return bson.D{{Key: "req_time", Value: -1}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GroupRequestMgo) PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) {
|
func (g *GroupRequestMgo) Page(ctx context.Context, userID string, groupIDs []string, handleResults []int, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) {
|
||||||
return mongoutil.FindPage[*model.GroupRequest](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}, pagination)
|
filter := bson.M{"user_id": userID}
|
||||||
|
if len(groupIDs) > 0 {
|
||||||
|
filter["group_id"] = bson.M{"$in": datautil.Distinct(groupIDs)}
|
||||||
|
}
|
||||||
|
if len(handleResults) > 0 {
|
||||||
|
filter["handle_result"] = bson.M{"$in": handleResults}
|
||||||
|
}
|
||||||
|
return mongoutil.FindPage[*model.GroupRequest](ctx, g.coll, filter, pagination, options.Find().SetSort(g.sort()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GroupRequestMgo) PageGroup(ctx context.Context, groupIDs []string, handleResults []int, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) {
|
||||||
|
if len(groupIDs) == 0 {
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
filter := bson.M{"group_id": bson.M{"$in": groupIDs}}
|
||||||
|
if len(handleResults) > 0 {
|
||||||
|
filter["handle_result"] = bson.M{"$in": handleResults}
|
||||||
|
}
|
||||||
|
return mongoutil.FindPage[*model.GroupRequest](ctx, g.coll, filter, pagination, options.Find().SetSort(g.sort()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GroupRequestMgo) GetUnhandledCount(ctx context.Context, groupIDs []string, ts int64) (int64, error) {
|
||||||
|
if len(groupIDs) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
filter := bson.M{"group_id": bson.M{"$in": groupIDs}, "handle_result": 0}
|
||||||
|
if ts != 0 {
|
||||||
|
filter["req_time"] = bson.M{"$gt": time.Unix(ts, 0)}
|
||||||
|
}
|
||||||
|
return mongoutil.Count(ctx, g.coll, filter)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1091,22 +1091,148 @@ func (m *MsgMgo) onlyFindDocIndex(ctx context.Context, docID string, indexes []i
|
|||||||
return msgDocModel[0].Msg, nil
|
return msgDocModel[0].Msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//func (m *MsgMgo) FindSeqs(ctx context.Context, conversationID string, seqs []int64) ([]*model.MsgInfoModel, error) {
|
||||||
|
// if len(seqs) == 0 {
|
||||||
|
// return nil, nil
|
||||||
|
// }
|
||||||
|
// result := make([]*model.MsgInfoModel, 0, len(seqs))
|
||||||
|
// for docID, seqs := range m.model.GetDocIDSeqsMap(conversationID, seqs) {
|
||||||
|
// res, err := m.onlyFindDocIndex(ctx, docID, datautil.Slice(seqs, m.model.GetMsgIndex))
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// for i, re := range res {
|
||||||
|
// if re == nil || re.Msg == nil {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// result = append(result, res[i])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return result, nil
|
||||||
|
//}
|
||||||
|
|
||||||
|
func (m *MsgMgo) findBeforeDocSendTime(ctx context.Context, docID string, limit int64) (int64, int64, error) {
|
||||||
|
if limit == 0 {
|
||||||
|
return 0, 0, nil
|
||||||
|
}
|
||||||
|
pipeline := []bson.M{
|
||||||
|
{
|
||||||
|
"$match": bson.M{
|
||||||
|
"doc_id": docID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$project": bson.M{
|
||||||
|
"_id": 0,
|
||||||
|
"doc_id": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$unwind": "$msgs",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$project": bson.M{
|
||||||
|
//"_id": 0,
|
||||||
|
//"doc_id": 0,
|
||||||
|
"msgs.msg.send_time": 1,
|
||||||
|
"msgs.msg.seq": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if limit > 0 {
|
||||||
|
pipeline = append(pipeline, bson.M{"$limit": limit})
|
||||||
|
}
|
||||||
|
type Result struct {
|
||||||
|
Msgs *model.MsgInfoModel `bson:"msgs"`
|
||||||
|
}
|
||||||
|
res, err := mongoutil.Aggregate[Result](ctx, m.coll, pipeline)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
for i := len(res) - 1; i > 0; i-- {
|
||||||
|
v := res[i]
|
||||||
|
if v.Msgs != nil && v.Msgs.Msg != nil && v.Msgs.Msg.SendTime > 0 {
|
||||||
|
return v.Msgs.Msg.Seq, v.Msgs.Msg.SendTime, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MsgMgo) findBeforeSendTime(ctx context.Context, conversationID string, seq int64) (int64, int64, error) {
|
||||||
|
first := true
|
||||||
|
for i := m.model.GetDocIndex(seq); i >= 0; i-- {
|
||||||
|
limit := int64(-1)
|
||||||
|
if first {
|
||||||
|
first = false
|
||||||
|
limit = m.model.GetMsgIndex(seq)
|
||||||
|
}
|
||||||
|
docID := m.model.BuildDocIDByIndex(conversationID, i)
|
||||||
|
msgSeq, msgSendTime, err := m.findBeforeDocSendTime(ctx, docID, limit)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
if msgSendTime > 0 {
|
||||||
|
return msgSeq, msgSendTime, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MsgMgo) FindSeqs(ctx context.Context, conversationID string, seqs []int64) ([]*model.MsgInfoModel, error) {
|
func (m *MsgMgo) FindSeqs(ctx context.Context, conversationID string, seqs []int64) ([]*model.MsgInfoModel, error) {
|
||||||
if len(seqs) == 0 {
|
if len(seqs) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
var abnormalSeq []int64
|
||||||
result := make([]*model.MsgInfoModel, 0, len(seqs))
|
result := make([]*model.MsgInfoModel, 0, len(seqs))
|
||||||
for docID, seqs := range m.model.GetDocIDSeqsMap(conversationID, seqs) {
|
for docID, docSeqs := range m.model.GetDocIDSeqsMap(conversationID, seqs) {
|
||||||
res, err := m.onlyFindDocIndex(ctx, docID, datautil.Slice(seqs, m.model.GetMsgIndex))
|
res, err := m.onlyFindDocIndex(ctx, docID, datautil.Slice(docSeqs, m.model.GetMsgIndex))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if len(res) == 0 {
|
||||||
|
abnormalSeq = append(abnormalSeq, docSeqs...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
for i, re := range res {
|
for i, re := range res {
|
||||||
if re == nil || re.Msg == nil {
|
if re == nil || re.Msg == nil || re.Msg.SendTime == 0 {
|
||||||
|
abnormalSeq = append(abnormalSeq, docSeqs[i])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result = append(result, res[i])
|
result = append(result, res[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(abnormalSeq) > 0 {
|
||||||
|
datautil.Sort(abnormalSeq, false)
|
||||||
|
sendTime := make(map[int64]int64)
|
||||||
|
var (
|
||||||
|
lastSeq int64
|
||||||
|
lastSendTime int64
|
||||||
|
)
|
||||||
|
for _, seq := range abnormalSeq {
|
||||||
|
if lastSendTime > 0 && lastSeq <= seq {
|
||||||
|
sendTime[seq] = lastSendTime
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
msgSeq, msgSendTime, err := m.findBeforeSendTime(ctx, conversationID, seq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if msgSendTime <= 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
sendTime[seq] = msgSendTime
|
||||||
|
lastSeq = msgSeq
|
||||||
|
lastSendTime = msgSendTime
|
||||||
|
}
|
||||||
|
for _, seq := range abnormalSeq {
|
||||||
|
result = append(result, &model.MsgInfoModel{
|
||||||
|
Msg: &model.MsgDataModel{
|
||||||
|
Seq: seq,
|
||||||
|
Status: constant.MsgStatusHasDeleted,
|
||||||
|
SendTime: sendTime[seq],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Copyright © 2024 OpenIM open source community. 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.
|
||||||
|
// 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 kafka
|
||||||
|
|
||||||
|
type TLSConfig struct {
|
||||||
|
EnableTLS bool `yaml:"enableTLS"`
|
||||||
|
CACrt string `yaml:"caCrt"`
|
||||||
|
ClientCrt string `yaml:"clientCrt"`
|
||||||
|
ClientKey string `yaml:"clientKey"`
|
||||||
|
ClientKeyPwd string `yaml:"clientKeyPwd"`
|
||||||
|
InsecureSkipVerify bool `yaml:"insecureSkipVerify"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Username string `yaml:"username"`
|
||||||
|
Password string `yaml:"password"`
|
||||||
|
ProducerAck string `yaml:"producerAck"`
|
||||||
|
CompressType string `yaml:"compressType"`
|
||||||
|
Addr []string `yaml:"addr"`
|
||||||
|
TLS TLSConfig `yaml:"tls"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright © 2023 OpenIM. 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.
|
||||||
|
// 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 kafka
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/IBM/sarama"
|
||||||
|
"github.com/openimsdk/tools/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MConsumerGroup struct {
|
||||||
|
sarama.ConsumerGroup
|
||||||
|
groupID string
|
||||||
|
topics []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMConsumerGroup(conf *Config, groupID string, topics []string, autoCommitEnable bool) (*MConsumerGroup, error) {
|
||||||
|
config, err := BuildConsumerGroupConfig(conf, sarama.OffsetNewest, autoCommitEnable)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
group, err := NewConsumerGroup(config, conf.Addr, groupID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &MConsumerGroup{
|
||||||
|
ConsumerGroup: group,
|
||||||
|
groupID: groupID,
|
||||||
|
topics: topics,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *MConsumerGroup) GetContextFromMsg(cMsg *sarama.ConsumerMessage) context.Context {
|
||||||
|
return GetContextWithMQHeader(cMsg.Headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *MConsumerGroup) RegisterHandleAndConsumer(ctx context.Context, handler sarama.ConsumerGroupHandler) {
|
||||||
|
for {
|
||||||
|
err := mc.ConsumerGroup.Consume(ctx, mc.topics, handler)
|
||||||
|
if errors.Is(err, sarama.ErrClosedConsumerGroup) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if errors.Is(err, context.Canceled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.ZWarn(ctx, "consume err", err, "topic", mc.topics, "groupID", mc.groupID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *MConsumerGroup) Close() error {
|
||||||
|
return mc.ConsumerGroup.Close()
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright © 2023 OpenIM. 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.
|
||||||
|
// 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 kafka
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/IBM/sarama"
|
||||||
|
"github.com/openimsdk/tools/errs"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Producer represents a Kafka producer.
|
||||||
|
type Producer struct {
|
||||||
|
addr []string
|
||||||
|
topic string
|
||||||
|
config *sarama.Config
|
||||||
|
producer sarama.SyncProducer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKafkaProducer(config *sarama.Config, addr []string, topic string) (*Producer, error) {
|
||||||
|
producer, err := NewProducer(config, addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Producer{
|
||||||
|
addr: addr,
|
||||||
|
topic: topic,
|
||||||
|
config: config,
|
||||||
|
producer: producer,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMessage sends a message to the Kafka topic configured in the Producer.
|
||||||
|
func (p *Producer) SendMessage(ctx context.Context, key string, msg proto.Message) (int32, int64, error) {
|
||||||
|
// Marshal the protobuf message
|
||||||
|
bMsg, err := proto.Marshal(msg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, errs.WrapMsg(err, "kafka proto Marshal err")
|
||||||
|
}
|
||||||
|
if len(bMsg) == 0 {
|
||||||
|
return 0, 0, errs.WrapMsg(errEmptyMsg, "kafka proto Marshal err")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare Kafka message
|
||||||
|
kMsg := &sarama.ProducerMessage{
|
||||||
|
Topic: p.topic,
|
||||||
|
Key: sarama.StringEncoder(key),
|
||||||
|
Value: sarama.ByteEncoder(bMsg),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate message key and value
|
||||||
|
if kMsg.Key.Length() == 0 || kMsg.Value.Length() == 0 {
|
||||||
|
return 0, 0, errs.Wrap(errEmptyMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach context metadata as headers
|
||||||
|
header, err := GetMQHeaderWithContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
kMsg.Headers = header
|
||||||
|
|
||||||
|
// Send the message
|
||||||
|
partition, offset, err := p.producer.SendMessage(kMsg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, errs.WrapMsg(err, "p.producer.SendMessage error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return partition, offset, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package kafka
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/IBM/sarama"
|
||||||
|
"github.com/openimsdk/tools/errs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BuildConsumerGroupConfig(conf *Config, initial int64, autoCommitEnable bool) (*sarama.Config, error) {
|
||||||
|
kfk := sarama.NewConfig()
|
||||||
|
kfk.Version = sarama.V2_0_0_0
|
||||||
|
kfk.Consumer.Offsets.Initial = initial
|
||||||
|
kfk.Consumer.Offsets.AutoCommit.Enable = autoCommitEnable
|
||||||
|
kfk.Consumer.Return.Errors = false
|
||||||
|
if conf.Username != "" || conf.Password != "" {
|
||||||
|
kfk.Net.SASL.Enable = true
|
||||||
|
kfk.Net.SASL.User = conf.Username
|
||||||
|
kfk.Net.SASL.Password = conf.Password
|
||||||
|
}
|
||||||
|
if conf.TLS.EnableTLS {
|
||||||
|
tls, err := newTLSConfig(conf.TLS.ClientCrt, conf.TLS.ClientKey, conf.TLS.CACrt, []byte(conf.TLS.ClientKeyPwd), conf.TLS.InsecureSkipVerify)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
kfk.Net.TLS.Config = tls
|
||||||
|
kfk.Net.TLS.Enable = true
|
||||||
|
}
|
||||||
|
return kfk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConsumerGroup(conf *sarama.Config, addr []string, groupID string) (sarama.ConsumerGroup, error) {
|
||||||
|
cg, err := sarama.NewConsumerGroup(addr, groupID, conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.WrapMsg(err, "NewConsumerGroup failed", "addr", addr, "groupID", groupID, "conf", *conf)
|
||||||
|
}
|
||||||
|
return cg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildProducerConfig(conf Config) (*sarama.Config, error) {
|
||||||
|
kfk := sarama.NewConfig()
|
||||||
|
kfk.Producer.Return.Successes = true
|
||||||
|
kfk.Producer.Return.Errors = true
|
||||||
|
kfk.Producer.Partitioner = sarama.NewHashPartitioner
|
||||||
|
if conf.Username != "" || conf.Password != "" {
|
||||||
|
kfk.Net.SASL.Enable = true
|
||||||
|
kfk.Net.SASL.User = conf.Username
|
||||||
|
kfk.Net.SASL.Password = conf.Password
|
||||||
|
}
|
||||||
|
switch strings.ToLower(conf.ProducerAck) {
|
||||||
|
case "no_response":
|
||||||
|
kfk.Producer.RequiredAcks = sarama.NoResponse
|
||||||
|
case "wait_for_local":
|
||||||
|
kfk.Producer.RequiredAcks = sarama.WaitForLocal
|
||||||
|
case "wait_for_all":
|
||||||
|
kfk.Producer.RequiredAcks = sarama.WaitForAll
|
||||||
|
default:
|
||||||
|
kfk.Producer.RequiredAcks = sarama.WaitForAll
|
||||||
|
}
|
||||||
|
if conf.CompressType == "" {
|
||||||
|
kfk.Producer.Compression = sarama.CompressionNone
|
||||||
|
} else {
|
||||||
|
if err := kfk.Producer.Compression.UnmarshalText(bytes.ToLower([]byte(conf.CompressType))); err != nil {
|
||||||
|
return nil, errs.WrapMsg(err, "UnmarshalText failed", "compressType", conf.CompressType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if conf.TLS.EnableTLS {
|
||||||
|
tls, err := newTLSConfig(conf.TLS.ClientCrt, conf.TLS.ClientKey, conf.TLS.CACrt, []byte(conf.TLS.ClientKeyPwd), conf.TLS.InsecureSkipVerify)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
kfk.Net.TLS.Config = tls
|
||||||
|
kfk.Net.TLS.Enable = true
|
||||||
|
}
|
||||||
|
return kfk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProducer(conf *sarama.Config, addr []string) (sarama.SyncProducer, error) {
|
||||||
|
producer, err := sarama.NewSyncProducer(addr, conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.WrapMsg(err, "NewSyncProducer failed", "addr", addr, "conf", *conf)
|
||||||
|
}
|
||||||
|
return producer, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
// Copyright © 2024 OpenIM open source community. 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.
|
||||||
|
// 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 kafka
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/openimsdk/tools/errs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// decryptPEM decrypts a PEM block using a password.
|
||||||
|
func decryptPEM(data []byte, passphrase []byte) ([]byte, error) {
|
||||||
|
if len(passphrase) == 0 {
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
b, _ := pem.Decode(data)
|
||||||
|
d, err := x509.DecryptPEMBlock(b, passphrase)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.WrapMsg(err, "DecryptPEMBlock failed")
|
||||||
|
}
|
||||||
|
return pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: b.Type,
|
||||||
|
Bytes: d,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readEncryptablePEMBlock(path string, pwd []byte) ([]byte, error) {
|
||||||
|
data, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.WrapMsg(err, "ReadFile failed", "path", path)
|
||||||
|
}
|
||||||
|
return decryptPEM(data, pwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// newTLSConfig setup the TLS config from general config file.
|
||||||
|
func newTLSConfig(clientCertFile, clientKeyFile, caCertFile string, keyPwd []byte, insecureSkipVerify bool) (*tls.Config, error) {
|
||||||
|
var tlsConfig tls.Config
|
||||||
|
if clientCertFile != "" && clientKeyFile != "" {
|
||||||
|
certPEMBlock, err := os.ReadFile(clientCertFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.WrapMsg(err, "ReadFile failed", "clientCertFile", clientCertFile)
|
||||||
|
}
|
||||||
|
keyPEMBlock, err := readEncryptablePEMBlock(clientKeyFile, keyPwd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.WrapMsg(err, "X509KeyPair failed")
|
||||||
|
}
|
||||||
|
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||||
|
}
|
||||||
|
|
||||||
|
if caCertFile != "" {
|
||||||
|
caCert, err := os.ReadFile(caCertFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.WrapMsg(err, "ReadFile failed", "caCertFile", caCertFile)
|
||||||
|
}
|
||||||
|
caCertPool := x509.NewCertPool()
|
||||||
|
if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {
|
||||||
|
return nil, errs.New("AppendCertsFromPEM failed")
|
||||||
|
}
|
||||||
|
tlsConfig.RootCAs = caCertPool
|
||||||
|
}
|
||||||
|
tlsConfig.InsecureSkipVerify = insecureSkipVerify
|
||||||
|
return &tlsConfig, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package kafka
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"github.com/IBM/sarama"
|
||||||
|
"github.com/openimsdk/protocol/constant"
|
||||||
|
"github.com/openimsdk/tools/mcontext"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errEmptyMsg = errors.New("kafka binary msg is empty")
|
||||||
|
|
||||||
|
// GetMQHeaderWithContext extracts message queue headers from the context.
|
||||||
|
func GetMQHeaderWithContext(ctx context.Context) ([]sarama.RecordHeader, error) {
|
||||||
|
operationID, opUserID, platform, connID, err := mcontext.GetCtxInfos(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return []sarama.RecordHeader{
|
||||||
|
{Key: []byte(constant.OperationID), Value: []byte(operationID)},
|
||||||
|
{Key: []byte(constant.OpUserID), Value: []byte(opUserID)},
|
||||||
|
{Key: []byte(constant.OpUserPlatform), Value: []byte(platform)},
|
||||||
|
{Key: []byte(constant.ConnID), Value: []byte(connID)},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContextWithMQHeader creates a context from message queue headers.
|
||||||
|
func GetContextWithMQHeader(header []*sarama.RecordHeader) context.Context {
|
||||||
|
var values []string
|
||||||
|
for _, recordHeader := range header {
|
||||||
|
values = append(values, string(recordHeader.Value))
|
||||||
|
}
|
||||||
|
return mcontext.WithMustInfoCtx(values) // Attach extracted values to context
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
// Copyright © 2024 OpenIM open source community. 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.
|
||||||
|
// 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 kafka
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/IBM/sarama"
|
||||||
|
"github.com/openimsdk/tools/errs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckTopics(ctx context.Context, conf *Config, topics []string) error {
|
||||||
|
kfk, err := BuildConsumerGroupConfig(conf, sarama.OffsetNewest, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cli, err := sarama.NewClient(conf.Addr, kfk)
|
||||||
|
if err != nil {
|
||||||
|
return errs.WrapMsg(err, "NewClient failed", "config: ", fmt.Sprintf("%+v", conf))
|
||||||
|
}
|
||||||
|
defer cli.Close()
|
||||||
|
|
||||||
|
existingTopics, err := cli.Topics()
|
||||||
|
if err != nil {
|
||||||
|
return errs.WrapMsg(err, "Failed to list topics")
|
||||||
|
}
|
||||||
|
|
||||||
|
existingTopicsMap := make(map[string]bool)
|
||||||
|
for _, t := range existingTopics {
|
||||||
|
existingTopicsMap[t] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, topic := range topics {
|
||||||
|
if !existingTopicsMap[topic] {
|
||||||
|
return errs.New("topic not exist", "topic", topic).Wrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckHealth(ctx context.Context, conf *Config) error {
|
||||||
|
kfk, err := BuildConsumerGroupConfig(conf, sarama.OffsetNewest, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cli, err := sarama.NewClient(conf.Addr, kfk)
|
||||||
|
if err != nil {
|
||||||
|
return errs.WrapMsg(err, "NewClient failed", "config: ", fmt.Sprintf("%+v", conf))
|
||||||
|
}
|
||||||
|
defer cli.Close()
|
||||||
|
|
||||||
|
// Get broker list
|
||||||
|
brokers := cli.Brokers()
|
||||||
|
if len(brokers) == 0 {
|
||||||
|
return errs.New("no brokers found").Wrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all brokers are reachable
|
||||||
|
for _, broker := range brokers {
|
||||||
|
if err := broker.Open(kfk); err != nil {
|
||||||
|
return errs.WrapMsg(err, "failed to open broker", "broker", broker.Addr())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -15,9 +15,10 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/openimsdk/protocol/sdkws"
|
"github.com/openimsdk/protocol/sdkws"
|
||||||
"github.com/openimsdk/tools/errs"
|
"github.com/openimsdk/tools/errs"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -108,6 +109,10 @@ func (m *MsgDocModel) IsFull() bool {
|
|||||||
return m.Msg[len(m.Msg)-1].Msg != nil
|
return m.Msg[len(m.Msg)-1].Msg != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MsgDocModel) GetDocIndex(seq int64) int64 {
|
||||||
|
return (seq - 1) / singleGocMsgNum
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MsgDocModel) GetDocID(conversationID string, seq int64) string {
|
func (m *MsgDocModel) GetDocID(conversationID string, seq int64) string {
|
||||||
seqSuffix := (seq - 1) / singleGocMsgNum
|
seqSuffix := (seq - 1) / singleGocMsgNum
|
||||||
return m.indexGen(conversationID, seqSuffix)
|
return m.indexGen(conversationID, seqSuffix)
|
||||||
@@ -135,6 +140,10 @@ func (*MsgDocModel) indexGen(conversationID string, seqSuffix int64) string {
|
|||||||
return conversationID + ":" + strconv.FormatInt(seqSuffix, 10)
|
return conversationID + ":" + strconv.FormatInt(seqSuffix, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*MsgDocModel) BuildDocIDByIndex(conversationID string, index int64) string {
|
||||||
|
return conversationID + ":" + strconv.FormatInt(index, 10)
|
||||||
|
}
|
||||||
|
|
||||||
func (*MsgDocModel) GenExceptionMessageBySeqs(seqs []int64) (exceptionMsg []*sdkws.MsgData) {
|
func (*MsgDocModel) GenExceptionMessageBySeqs(seqs []int64) (exceptionMsg []*sdkws.MsgData) {
|
||||||
for _, v := range seqs {
|
for _, v := range seqs {
|
||||||
msgModel := new(sdkws.MsgData)
|
msgModel := new(sdkws.MsgData)
|
||||||
|
|||||||
+11
-6
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package rpcclient
|
package notification
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -179,19 +179,24 @@ func NewNotificationSender(conf *config.Notification, opts ...NotificationSender
|
|||||||
}
|
}
|
||||||
|
|
||||||
type notificationOpt struct {
|
type notificationOpt struct {
|
||||||
WithRpcGetUsername bool
|
RpcGetUsername bool
|
||||||
|
SendMessage *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type NotificationOptions func(*notificationOpt)
|
type NotificationOptions func(*notificationOpt)
|
||||||
|
|
||||||
func WithRpcGetUserName() NotificationOptions {
|
func WithRpcGetUserName() NotificationOptions {
|
||||||
return func(opt *notificationOpt) {
|
return func(opt *notificationOpt) {
|
||||||
opt.WithRpcGetUsername = true
|
opt.RpcGetUsername = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func WithSendMessage(sendMessage *bool) NotificationOptions {
|
||||||
|
return func(opt *notificationOpt) {
|
||||||
|
opt.SendMessage = sendMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NotificationSender) send(ctx context.Context, sendID, recvID string, contentType, sessionType int32, m proto.Message, opts ...NotificationOptions) {
|
func (s *NotificationSender) send(ctx context.Context, sendID, recvID string, contentType, sessionType int32, m proto.Message, opts ...NotificationOptions) {
|
||||||
//ctx = mcontext.WithMustInfoCtx([]string{mcontext.GetOperationID(ctx), mcontext.GetOpUserID(ctx), mcontext.GetOpUserPlatform(ctx), mcontext.GetConnID(ctx)})
|
|
||||||
ctx = context.WithoutCancel(ctx)
|
ctx = context.WithoutCancel(ctx)
|
||||||
ctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(5))
|
ctx, cancel := context.WithTimeout(ctx, time.Second*time.Duration(5))
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -208,7 +213,7 @@ func (s *NotificationSender) send(ctx context.Context, sendID, recvID string, co
|
|||||||
var req msg.SendMsgReq
|
var req msg.SendMsgReq
|
||||||
var msg sdkws.MsgData
|
var msg sdkws.MsgData
|
||||||
var userInfo *sdkws.UserInfo
|
var userInfo *sdkws.UserInfo
|
||||||
if notificationOpt.WithRpcGetUsername && s.getUserInfo != nil {
|
if notificationOpt.RpcGetUsername && s.getUserInfo != nil {
|
||||||
userInfo, err = s.getUserInfo(ctx, sendID)
|
userInfo, err = s.getUserInfo(ctx, sendID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "getUserInfo failed", err, "sendID", sendID)
|
log.ZWarn(ctx, "getUserInfo failed", err, "sendID", sendID)
|
||||||
@@ -233,7 +238,7 @@ func (s *NotificationSender) send(ctx context.Context, sendID, recvID string, co
|
|||||||
if sendID == recvID && contentType == constant.HasReadReceipt {
|
if sendID == recvID && contentType == constant.HasReadReceipt {
|
||||||
optionsConfig.ReliabilityLevel = constant.UnreliableNotification
|
optionsConfig.ReliabilityLevel = constant.UnreliableNotification
|
||||||
}
|
}
|
||||||
options := config.GetOptionsByNotification(optionsConfig)
|
options := config.GetOptionsByNotification(optionsConfig, notificationOpt.SendMessage)
|
||||||
s.SetOptionsByContentType(ctx, options, contentType)
|
s.SetOptionsByContentType(ctx, options, contentType)
|
||||||
msg.Options = options
|
msg.Options = options
|
||||||
// fill Notification OfflinePush by config
|
// fill Notification OfflinePush by config
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ import (
|
|||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/kafka"
|
||||||
"github.com/openimsdk/tools/db/mongoutil"
|
"github.com/openimsdk/tools/db/mongoutil"
|
||||||
"github.com/openimsdk/tools/db/redisutil"
|
"github.com/openimsdk/tools/db/redisutil"
|
||||||
"github.com/openimsdk/tools/discovery/etcd"
|
"github.com/openimsdk/tools/discovery/etcd"
|
||||||
"github.com/openimsdk/tools/discovery/zookeeper"
|
"github.com/openimsdk/tools/discovery/zookeeper"
|
||||||
"github.com/openimsdk/tools/mq/kafka"
|
|
||||||
"github.com/openimsdk/tools/s3/minio"
|
"github.com/openimsdk/tools/s3/minio"
|
||||||
"github.com/openimsdk/tools/system/program"
|
"github.com/openimsdk/tools/system/program"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,6 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
|
||||||
@@ -19,10 +24,6 @@ import (
|
|||||||
"github.com/openimsdk/tools/s3/oss"
|
"github.com/openimsdk/tools/s3/oss"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultTimeout = time.Second * 10
|
const defaultTimeout = time.Second * 10
|
||||||
@@ -159,7 +160,7 @@ func doObject(db database.ObjectInfo, newS3, oldS3 s3.Interface, skip int) (*Res
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
putURL, err := newS3.PresignedPutObject(ctx, obj.Key, time.Hour)
|
putURL, err := newS3.PresignedPutObject(ctx, obj.Key, time.Hour, &s3.PutOption{ContentType: obj.ContentType})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -176,7 +177,7 @@ func doObject(db database.ObjectInfo, newS3, oldS3 s3.Interface, skip int) (*Res
|
|||||||
return nil, fmt.Errorf("download object failed %s", downloadResp.Status)
|
return nil, fmt.Errorf("download object failed %s", downloadResp.Status)
|
||||||
}
|
}
|
||||||
log.Printf("file size %d", obj.Size)
|
log.Printf("file size %d", obj.Size)
|
||||||
request, err := http.NewRequest(http.MethodPut, putURL, downloadResp.Body)
|
request, err := http.NewRequest(http.MethodPut, putURL.URL, downloadResp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-13
@@ -5,16 +5,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
|
|
||||||
"github.com/openimsdk/tools/db/mongoutil"
|
|
||||||
"github.com/openimsdk/tools/db/redisutil"
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -24,6 +14,19 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
|
||||||
|
"github.com/openimsdk/tools/db/mongoutil"
|
||||||
|
"github.com/openimsdk/tools/db/redisutil"
|
||||||
|
"github.com/openimsdk/tools/utils/runtimeenv"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -41,12 +44,22 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func readConfig[T any](dir string, name string) (*T, error) {
|
func readConfig[T any](dir string, name string) (*T, error) {
|
||||||
data, err := os.ReadFile(filepath.Join(dir, name))
|
if runtimeenv.RuntimeEnvironment() == config.KUBERNETES {
|
||||||
if err != nil {
|
dir = os.Getenv(config.MountConfigFilePath)
|
||||||
|
}
|
||||||
|
v := viper.New()
|
||||||
|
v.SetEnvPrefix(config.EnvPrefixMap[name])
|
||||||
|
v.AutomaticEnv()
|
||||||
|
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
|
v.SetConfigFile(filepath.Join(dir, name))
|
||||||
|
if err := v.ReadInConfig(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
fn := func(config *mapstructure.DecoderConfig) {
|
||||||
|
config.TagName = "mapstructure"
|
||||||
|
}
|
||||||
var conf T
|
var conf T
|
||||||
if err := yaml.Unmarshal(data, &conf); err != nil {
|
if err := v.Unmarshal(&conf, fn); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &conf, nil
|
return &conf, nil
|
||||||
|
|||||||
+5
-1
@@ -3,8 +3,10 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/openimsdk/open-im-server/v3/tools/seq/internal"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/tools/seq/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -17,6 +19,8 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
if err := internal.Main(config, time.Duration(second)*time.Second); err != nil {
|
if err := internal.Main(config, time.Duration(second)*time.Second); err != nil {
|
||||||
fmt.Println("seq task", err)
|
fmt.Println("seq task", err)
|
||||||
|
os.Exit(1)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
fmt.Println("seq task success!")
|
fmt.Println("seq task success!")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
v3.8.3
|
v3.8.3-patch.6
|
||||||
+9
-1
@@ -1,6 +1,14 @@
|
|||||||
package version
|
package version
|
||||||
|
|
||||||
import _ "embed"
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
//go:embed version
|
//go:embed version
|
||||||
var Version string
|
var Version string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Version = strings.Trim(Version, "\n")
|
||||||
|
Version = strings.TrimSpace(Version)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user