# Conflicts: # internal/msggateway/n_ws_server.go # internal/rpc/group/group.go # internal/rpc/third/third.go # pkg/common/convert/user.go # pkg/common/http/http_client.gopull/1450/head
commit
775e62b539
@ -1,308 +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.
|
|
||||||
|
|
||||||
# ======================================
|
|
||||||
# ========= Basic Configuration ========
|
|
||||||
# ======================================
|
|
||||||
|
|
||||||
# The user for authentication or system operations.
|
|
||||||
# Default: USER=root
|
|
||||||
USER=root
|
|
||||||
|
|
||||||
# Password associated with the specified user for authentication.
|
|
||||||
# Default: PASSWORD=openIM123
|
|
||||||
PASSWORD=openIM123
|
|
||||||
|
|
||||||
# Endpoint for the MinIO object storage service.
|
|
||||||
# Default: MINIO_ENDPOINT=http://172.28.0.1:10005
|
|
||||||
MINIO_ENDPOINT=http://172.28.0.1:10005
|
|
||||||
|
|
||||||
# Base URL for the application programming interface (API).
|
|
||||||
# Default: API_URL=http://172.28.0.1:10002
|
|
||||||
API_URL=http://172.28.0.1:10002
|
|
||||||
|
|
||||||
# Directory path for storing data files or related information.
|
|
||||||
# Default: DATA_DIR=./
|
|
||||||
DATA_DIR=./
|
|
||||||
|
|
||||||
# Choose the appropriate image address, the default is GITHUB image,
|
|
||||||
# you can choose docker hub, for Chinese users can choose Ali Cloud
|
|
||||||
# export IMAGE_REGISTRY="ghcr.io/openimsdk"
|
|
||||||
# export IMAGE_REGISTRY="openim"
|
|
||||||
# export IMAGE_REGISTRY="registry.cn-hangzhou.aliyuncs.com/openimsdk"
|
|
||||||
IMAGE_REGISTRY=ghcr.io/openimsdk
|
|
||||||
|
|
||||||
# ======================================
|
|
||||||
# ========= Network Configuration ======
|
|
||||||
# ======================================
|
|
||||||
|
|
||||||
# Subnet for the Docker network.
|
|
||||||
# Default: DOCKER_BRIDGE_SUBNET=172.28.0.0/16
|
|
||||||
DOCKER_BRIDGE_SUBNET=172.28.0.0/16
|
|
||||||
|
|
||||||
# Gateway for the Docker network.
|
|
||||||
# Default: DOCKER_BRIDGE_GATEWAY=172.28.0.1
|
|
||||||
DOCKER_BRIDGE_GATEWAY=172.28.0.1
|
|
||||||
|
|
||||||
# Address or hostname for the MySQL network.
|
|
||||||
# Default: MYSQL_NETWORK_ADDRESS=172.28.0.2
|
|
||||||
MYSQL_NETWORK_ADDRESS=172.28.0.2
|
|
||||||
|
|
||||||
# Address or hostname for the MongoDB network.
|
|
||||||
# Default: MONGO_NETWORK_ADDRESS=172.28.0.3
|
|
||||||
MONGO_NETWORK_ADDRESS=172.28.0.3
|
|
||||||
|
|
||||||
# Address or hostname for the Redis network.
|
|
||||||
# Default: REDIS_NETWORK_ADDRESS=172.28.0.4
|
|
||||||
REDIS_NETWORK_ADDRESS=172.28.0.4
|
|
||||||
|
|
||||||
# Address or hostname for the Kafka network.
|
|
||||||
# Default: KAFKA_NETWORK_ADDRESS=172.28.0.5
|
|
||||||
KAFKA_NETWORK_ADDRESS=172.28.0.5
|
|
||||||
|
|
||||||
# Address or hostname for the ZooKeeper network.
|
|
||||||
# Default: ZOOKEEPER_NETWORK_ADDRESS=172.28.0.6
|
|
||||||
ZOOKEEPER_NETWORK_ADDRESS=172.28.0.6
|
|
||||||
|
|
||||||
# Address or hostname for the MinIO network.
|
|
||||||
# Default: MINIO_NETWORK_ADDRESS=172.28.0.7
|
|
||||||
MINIO_NETWORK_ADDRESS=172.28.0.7
|
|
||||||
|
|
||||||
# Address or hostname for the OpenIM web network.
|
|
||||||
# Default: OPENIM_WEB_NETWORK_ADDRESS=172.28.0.8
|
|
||||||
OPENIM_WEB_NETWORK_ADDRESS=172.28.0.8
|
|
||||||
|
|
||||||
# Address or hostname for the OpenIM server network.
|
|
||||||
# Default: OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.9
|
|
||||||
OPENIM_SERVER_NETWORK_ADDRESS=172.28.0.9
|
|
||||||
|
|
||||||
# Address or hostname for the OpenIM chat network.
|
|
||||||
# Default: OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.10
|
|
||||||
OPENIM_CHAT_NETWORK_ADDRESS=172.28.0.10
|
|
||||||
|
|
||||||
# Address or hostname for the Prometheus network.
|
|
||||||
# Default: PROMETHEUS_NETWORK_ADDRESS=172.28.0.11
|
|
||||||
PROMETHEUS_NETWORK_ADDRESS=172.28.0.11
|
|
||||||
|
|
||||||
# Address or hostname for the Grafana network.
|
|
||||||
# Default: GRAFANA_NETWORK_ADDRESS=172.28.0.12
|
|
||||||
GRAFANA_NETWORK_ADDRESS=172.28.0.12
|
|
||||||
|
|
||||||
# Address or hostname for the node_exporter network.
|
|
||||||
# Default: NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.13
|
|
||||||
NODE_EXPORTER_NETWORK_ADDRESS=172.28.0.13
|
|
||||||
|
|
||||||
# Address or hostname for the OpenIM admin network.
|
|
||||||
# Default: OPENIM_ADMIN_NETWORK_ADDRESS=172.28.0.14
|
|
||||||
OPENIM_ADMIN_FRONT_NETWORK_ADDRESS=172.28.0.14
|
|
||||||
|
|
||||||
# ===============================================
|
|
||||||
# = Component Extension Configuration =
|
|
||||||
# ===============================================
|
|
||||||
|
|
||||||
# ============ Component Extension Configuration ==========
|
|
||||||
# ----- ZooKeeper Configuration -----
|
|
||||||
# Address or hostname for the ZooKeeper service.
|
|
||||||
# Default: ZOOKEEPER_ADDRESS=172.28.0.1
|
|
||||||
ZOOKEEPER_ADDRESS=172.28.0.6
|
|
||||||
|
|
||||||
# Port for ZooKeeper service.
|
|
||||||
# Default: ZOOKEEPER_PORT=12181
|
|
||||||
ZOOKEEPER_PORT=12181
|
|
||||||
|
|
||||||
# ----- MySQL Configuration -----
|
|
||||||
|
|
||||||
# Address or hostname for the MySQL service.
|
|
||||||
# Default: MYSQL_ADDRESS=172.28.0.1
|
|
||||||
MYSQL_ADDRESS=172.28.0.2
|
|
||||||
|
|
||||||
# Port on which MySQL database service is running.
|
|
||||||
# Default: MYSQL_PORT=13306
|
|
||||||
MYSQL_PORT=13306
|
|
||||||
|
|
||||||
# Password to authenticate with the MySQL database service.
|
|
||||||
# Default: MYSQL_PASSWORD=openIM123
|
|
||||||
MYSQL_PASSWORD=openIM123
|
|
||||||
|
|
||||||
# ----- MongoDB Configuration -----
|
|
||||||
# Address or hostname for the MongoDB service.
|
|
||||||
# Default: MONGO_ADDRESS=172.28.0.1
|
|
||||||
MONGO_ADDRESS=172.28.0.3
|
|
||||||
|
|
||||||
# Port on which MongoDB service is running.
|
|
||||||
# Default: MONGO_PORT=37017
|
|
||||||
MONGO_PORT=37017
|
|
||||||
|
|
||||||
# Username to authenticate with the MongoDB service.
|
|
||||||
# Default: MONGO_USERNAME=root
|
|
||||||
MONGO_USERNAME=root
|
|
||||||
|
|
||||||
# Password to authenticate with the MongoDB service.
|
|
||||||
# Default: MONGO_PASSWORD=openIM123
|
|
||||||
MONGO_PASSWORD=openIM123
|
|
||||||
|
|
||||||
# Name of the database in MongoDB to be used.
|
|
||||||
# Default: MONGO_DATABASE=openIM_v3
|
|
||||||
MONGO_DATABASE=openIM_v3
|
|
||||||
|
|
||||||
# ----- Redis Configuration -----
|
|
||||||
# Address or hostname for the Redis service.
|
|
||||||
# Default: REDIS_ADDRESS=172.28.0.1
|
|
||||||
REDIS_ADDRESS=172.28.0.4
|
|
||||||
|
|
||||||
# Port on which Redis in-memory data structure store is running.
|
|
||||||
# Default: REDIS_PORT=16379
|
|
||||||
REDIS_PORT=16379
|
|
||||||
|
|
||||||
# Password to authenticate with the Redis service.
|
|
||||||
# Default: REDIS_PASSWORD=openIM123
|
|
||||||
REDIS_PASSWORD=openIM123
|
|
||||||
|
|
||||||
# ----- Kafka Configuration -----
|
|
||||||
# Address or hostname for the Kafka service.
|
|
||||||
# Default: KAFKA_ADDRESS=172.28.0.1
|
|
||||||
KAFKA_ADDRESS=172.28.0.5
|
|
||||||
|
|
||||||
# Port on which Kafka distributed streaming platform is running.
|
|
||||||
# Default: KAFKA_PORT=19092
|
|
||||||
KAFKA_PORT=19094
|
|
||||||
|
|
||||||
# Topic in Kafka for storing the latest messages in Redis.
|
|
||||||
# Default: KAFKA_LATESTMSG_REDIS_TOPIC=latestMsgToRedis
|
|
||||||
KAFKA_LATESTMSG_REDIS_TOPIC=latestMsgToRedis
|
|
||||||
|
|
||||||
# Topic in Kafka for pushing messages (e.g. notifications or updates).
|
|
||||||
# Default: KAFKA_MSG_PUSH_TOPIC=msgToPush
|
|
||||||
KAFKA_MSG_PUSH_TOPIC=msgToPush
|
|
||||||
|
|
||||||
# Topic in Kafka for storing offline messages in MongoDB.
|
|
||||||
# Default: KAFKA_OFFLINEMSG_MONGO_TOPIC=offlineMsgToMongoMysql
|
|
||||||
KAFKA_OFFLINEMSG_MONGO_TOPIC=offlineMsgToMongoMysql
|
|
||||||
|
|
||||||
# ----- MinIO Configuration ----
|
|
||||||
# Address or hostname for the MinIO object storage service.
|
|
||||||
# Default: MINIO_ADDRESS=172.28.0.1
|
|
||||||
MINIO_ADDRESS=172.28.0.7
|
|
||||||
|
|
||||||
# Port on which MinIO object storage service is running.
|
|
||||||
# Default: MINIO_PORT=10005
|
|
||||||
MINIO_PORT=10005
|
|
||||||
|
|
||||||
# Access key to authenticate with the MinIO service.
|
|
||||||
# Default: MINIO_ACCESS_KEY=root
|
|
||||||
MINIO_ACCESS_KEY=root
|
|
||||||
|
|
||||||
# Secret key corresponding to the access key for MinIO authentication.
|
|
||||||
# Default: MINIO_SECRET_KEY=openIM123
|
|
||||||
MINIO_SECRET_KEY=openIM123
|
|
||||||
|
|
||||||
# ----- Prometheus Configuration -----
|
|
||||||
# Address or hostname for the Prometheus service.
|
|
||||||
# Default: PROMETHEUS_ADDRESS=172.28.0.1
|
|
||||||
PROMETHEUS_ADDRESS=172.28.0.11
|
|
||||||
|
|
||||||
# Port on which Prometheus service is running.
|
|
||||||
# Default: PROMETHEUS_PORT=19090
|
|
||||||
PROMETHEUS_PORT=19090
|
|
||||||
|
|
||||||
# ----- Grafana Configuration -----
|
|
||||||
# Address or hostname for the Grafana service.
|
|
||||||
# Default: GRAFANA_ADDRESS=172.28.0.1
|
|
||||||
GRAFANA_ADDRESS=172.28.0.12
|
|
||||||
|
|
||||||
# Port on which Grafana service is running.
|
|
||||||
# Default: GRAFANA_PORT=3000
|
|
||||||
GRAFANA_PORT=3000
|
|
||||||
|
|
||||||
# ======================================
|
|
||||||
# ============ OpenIM Web ===============
|
|
||||||
# ======================================
|
|
||||||
|
|
||||||
# Path to the OpenIM web distribution.
|
|
||||||
# Default: OPENIM_WEB_DIST_PATH=/app/dist
|
|
||||||
OPENIM_WEB_DIST_PATH=/app/dist
|
|
||||||
|
|
||||||
# Port on which OpenIM web service is running.
|
|
||||||
# Default: OPENIM_WEB_PORT=11001
|
|
||||||
OPENIM_WEB_PORT=11001
|
|
||||||
|
|
||||||
# Address or hostname for the OpenIM web service.
|
|
||||||
# Default: OPENIM_WEB_ADDRESS=172.28.0.1
|
|
||||||
OPENIM_WEB_ADDRESS=172.28.0.8
|
|
||||||
|
|
||||||
# ======================================
|
|
||||||
# ========= OpenIM Server ==============
|
|
||||||
# ======================================
|
|
||||||
|
|
||||||
# Address or hostname for the OpenIM server.
|
|
||||||
# Default: OPENIM_SERVER_ADDRESS=172.28.0.1
|
|
||||||
OPENIM_SERVER_ADDRESS=172.28.0.9
|
|
||||||
|
|
||||||
# Port for the OpenIM WebSockets.
|
|
||||||
# Default: OPENIM_WS_PORT=10001
|
|
||||||
OPENIM_WS_PORT=10001
|
|
||||||
|
|
||||||
# Port for the OpenIM API.
|
|
||||||
# Default: API_OPENIM_PORT=10002
|
|
||||||
API_OPENIM_PORT=10002
|
|
||||||
|
|
||||||
|
|
||||||
# ======================================
|
|
||||||
# ========== OpenIM Chat ===============
|
|
||||||
# ======================================
|
|
||||||
|
|
||||||
# Branch name for OpenIM chat.
|
|
||||||
# Default: CHAT_BRANCH=main
|
|
||||||
CHAT_BRANCH=main
|
|
||||||
|
|
||||||
# Address or hostname for the OpenIM chat service.
|
|
||||||
# Default: OPENIM_CHAT_ADDRESS=172.28.0.1
|
|
||||||
OPENIM_CHAT_ADDRESS=172.28.0.10
|
|
||||||
|
|
||||||
# Port for the OpenIM chat API.
|
|
||||||
# Default: OPENIM_CHAT_API_PORT=10008
|
|
||||||
OPENIM_CHAT_API_PORT=10008
|
|
||||||
|
|
||||||
# Directory path for storing data files or related information for OpenIM chat.
|
|
||||||
# Default: OPENIM_CHAT_DATA_DIR=./openim-chat/main
|
|
||||||
OPENIM_CHAT_DATA_DIR=./openim-chat/main
|
|
||||||
|
|
||||||
|
|
||||||
# ======================================
|
|
||||||
# ========== OpenIM Admin ==============
|
|
||||||
# ======================================
|
|
||||||
|
|
||||||
# Branch name for OpenIM server.
|
|
||||||
# Default: SERVER_BRANCH=main
|
|
||||||
SERVER_BRANCH=main
|
|
||||||
|
|
||||||
# Port for the OpenIM admin API.
|
|
||||||
# Default: OPENIM_ADMIN_API_PORT=10009
|
|
||||||
OPENIM_ADMIN_API_PORT=10009
|
|
||||||
|
|
||||||
# Port for the node exporter.
|
|
||||||
# Default: NODE_EXPORTER_PORT=19100
|
|
||||||
NODE_EXPORTER_PORT=19100
|
|
||||||
|
|
||||||
# Port for the prometheus.
|
|
||||||
# Default: PROMETHEUS_PORT=19090
|
|
||||||
PROMETHEUS_PORT=19090
|
|
||||||
|
|
||||||
# Port for the grafana.
|
|
||||||
# Default: GRAFANA_PORT=3000
|
|
||||||
GRAFANA_PORT=3000
|
|
||||||
|
|
||||||
# Port for the admin front.
|
|
||||||
# Default: OPENIM_ADMIN_FRONT_PORT=11002
|
|
||||||
OPENIM_ADMIN_FRONT_PORT=11002
|
|
@ -1,32 +0,0 @@
|
|||||||
###################### AlertManager Configuration ######################
|
|
||||||
# AlertManager configuration using environment variables
|
|
||||||
#
|
|
||||||
# Resolve timeout
|
|
||||||
# SMTP configuration for sending alerts
|
|
||||||
# Templates for email notifications
|
|
||||||
# Routing configurations for alerts
|
|
||||||
# Receiver configurations
|
|
||||||
global:
|
|
||||||
resolve_timeout: 5m
|
|
||||||
smtp_from: alert@openim.io
|
|
||||||
smtp_smarthost: smtp.163.com:465
|
|
||||||
smtp_auth_username: alert@openim.io
|
|
||||||
smtp_auth_password: YOURAUTHPASSWORD
|
|
||||||
smtp_require_tls: false
|
|
||||||
smtp_hello: xxx监控告警
|
|
||||||
|
|
||||||
templates:
|
|
||||||
- /etc/alertmanager/email.tmpl
|
|
||||||
|
|
||||||
route:
|
|
||||||
group_wait: 5s
|
|
||||||
group_interval: 5s
|
|
||||||
repeat_interval: 5m
|
|
||||||
receiver: email
|
|
||||||
receivers:
|
|
||||||
- name: email
|
|
||||||
email_configs:
|
|
||||||
- to: {EMAIL_TO:-'alert@example.com'}
|
|
||||||
html: '{{ template "email.to.html" . }}'
|
|
||||||
headers: { Subject: "[OPENIM-SERVER]Alarm" }
|
|
||||||
send_resolved: true
|
|
@ -1,398 +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.
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
# TODO: This config file is the template file
|
|
||||||
# --| source: deployments/templates/openim.yaml
|
|
||||||
# --| env: scripts/install/environment
|
|
||||||
# --| target: config/config.yaml
|
|
||||||
# -----------------------------------------------------------------
|
|
||||||
|
|
||||||
envs:
|
|
||||||
discovery: zookeeper
|
|
||||||
|
|
||||||
###################### Zookeeper ######################
|
|
||||||
# Zookeeper configuration
|
|
||||||
# It's not recommended to modify the schema
|
|
||||||
#
|
|
||||||
# Zookeeper address
|
|
||||||
# Zookeeper username
|
|
||||||
# Zookeeper password
|
|
||||||
zookeeper:
|
|
||||||
schema: openim
|
|
||||||
address: [ 172.28.0.1:12181 ]
|
|
||||||
username: ''
|
|
||||||
password: ''
|
|
||||||
|
|
||||||
###################### Mysql ######################
|
|
||||||
# MySQL configuration
|
|
||||||
# Currently, only single machine setup is supported
|
|
||||||
#
|
|
||||||
# Maximum number of open connections
|
|
||||||
# Maximum number of idle connections
|
|
||||||
# Maximum lifetime in seconds a connection can be reused
|
|
||||||
# Log level: 1=slient, 2=error, 3=warn, 4=info
|
|
||||||
# Slow query threshold in milliseconds
|
|
||||||
mysql:
|
|
||||||
address: [ 172.28.0.1:13306 ]
|
|
||||||
username: root
|
|
||||||
password: openIM123
|
|
||||||
database: openIM_v3
|
|
||||||
maxOpenConn: 1000
|
|
||||||
maxIdleConn: 100
|
|
||||||
maxLifeTime: 60
|
|
||||||
logLevel: 4
|
|
||||||
slowThreshold: 500
|
|
||||||
|
|
||||||
###################### Mongo ######################
|
|
||||||
# MongoDB configuration
|
|
||||||
# If uri is not empty, it will be used directly
|
|
||||||
#
|
|
||||||
# MongoDB address for standalone setup, Mongos address for sharded cluster setup
|
|
||||||
# Default MongoDB database name
|
|
||||||
# Maximum connection pool size
|
|
||||||
mongo:
|
|
||||||
uri: ''
|
|
||||||
address: [ 172.28.0.1:37017 ]
|
|
||||||
database: openIM_v3
|
|
||||||
username: root
|
|
||||||
password: openIM123
|
|
||||||
maxPoolSize: 100
|
|
||||||
|
|
||||||
###################### Redis configuration information ######################
|
|
||||||
# Redis configuration
|
|
||||||
#
|
|
||||||
# Username is required only for Redis version 6.0+
|
|
||||||
redis:
|
|
||||||
address: [ 172.28.0.1:16379 ]
|
|
||||||
username: ''
|
|
||||||
password: openIM123
|
|
||||||
|
|
||||||
###################### Kafka configuration information ######################
|
|
||||||
# Kafka configuration
|
|
||||||
#
|
|
||||||
# Kafka username
|
|
||||||
# Kafka password
|
|
||||||
# It's not recommended to modify this topic name
|
|
||||||
# Consumer group ID, it's not recommended to modify
|
|
||||||
kafka:
|
|
||||||
username: ''
|
|
||||||
password: ''
|
|
||||||
addr: [ 172.28.0.1:19094 ]
|
|
||||||
latestMsgToRedis:
|
|
||||||
topic: "latestMsgToRedis"
|
|
||||||
offlineMsgToMongo:
|
|
||||||
topic: "offlineMsgToMongoMysql"
|
|
||||||
msgToPush:
|
|
||||||
topic: "msgToPush"
|
|
||||||
consumerGroupID:
|
|
||||||
msgToRedis: redis
|
|
||||||
msgToMongo: mongo
|
|
||||||
msgToMySql: mysql
|
|
||||||
msgToPush: push
|
|
||||||
|
|
||||||
###################### RPC configuration information ######################
|
|
||||||
# RPC configuration
|
|
||||||
#
|
|
||||||
# IP address to register with zookeeper when starting RPC, the IP and corresponding rpcPort should be accessible by api/gateway
|
|
||||||
# Default listen IP is 0.0.0.0
|
|
||||||
rpc:
|
|
||||||
registerIP: ''
|
|
||||||
listenIP: 0.0.0.0
|
|
||||||
|
|
||||||
###################### API configuration information ######################
|
|
||||||
# API configuration
|
|
||||||
#
|
|
||||||
# API service port
|
|
||||||
# Default listen IP is 0.0.0.0
|
|
||||||
api:
|
|
||||||
openImApiPort: [ 10002 ]
|
|
||||||
listenIP: 0.0.0.0
|
|
||||||
|
|
||||||
###################### Object configuration information ######################
|
|
||||||
# Object storage configuration
|
|
||||||
#
|
|
||||||
# Use minio for object storage
|
|
||||||
# API URL should be accessible by the app
|
|
||||||
# It's not recommended to modify the bucket name
|
|
||||||
# Endpoint should be accessible by the app
|
|
||||||
# Session token
|
|
||||||
# Configuration for Tencent COS
|
|
||||||
# Configuration for Aliyun OSS
|
|
||||||
# apiURL is the address of the api, the access address of the app, use s3 must be configured
|
|
||||||
# minio.endpoint can be configured as an intranet address,
|
|
||||||
# minio.signEndpoint is minio public network address
|
|
||||||
object:
|
|
||||||
enable: "minio"
|
|
||||||
apiURL: "http://127.0.0.1:10002"
|
|
||||||
minio:
|
|
||||||
bucket: "openim"
|
|
||||||
endpoint: "http://172.28.0.1:10005"
|
|
||||||
accessKeyID: "root"
|
|
||||||
secretAccessKey: "openIM123"
|
|
||||||
sessionToken: ''
|
|
||||||
signEndpoint: "http://127.0.0.1:10005"
|
|
||||||
publicRead: false
|
|
||||||
cos:
|
|
||||||
bucketURL: https://temp-1252357374.cos.ap-chengdu.myqcloud.com
|
|
||||||
secretID: ''
|
|
||||||
secretKey: ''
|
|
||||||
sessionToken: ''
|
|
||||||
publicRead: false
|
|
||||||
oss:
|
|
||||||
endpoint: "https://oss-cn-chengdu.aliyuncs.com"
|
|
||||||
bucket: "demo-9999999"
|
|
||||||
bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com"
|
|
||||||
accessKeyID: ''
|
|
||||||
accessKeySecret: ''
|
|
||||||
sessionToken: ''
|
|
||||||
publicRead: false
|
|
||||||
|
|
||||||
###################### RPC Port Configuration ######################
|
|
||||||
# RPC service ports
|
|
||||||
# These ports are passed into the program by the script and are not recommended to modify
|
|
||||||
# For launching multiple programs, just fill in multiple ports separated by commas
|
|
||||||
# For example, [10110, 10111]
|
|
||||||
rpcPort:
|
|
||||||
openImUserPort: [ 10110 ]
|
|
||||||
openImFriendPort: [ 10120 ]
|
|
||||||
openImMessagePort: [ 10130 ]
|
|
||||||
openImGroupPort: [ 10150 ]
|
|
||||||
openImAuthPort: [ 10160 ]
|
|
||||||
openImPushPort: [ 10170 ]
|
|
||||||
openImConversationPort: [ 10180 ]
|
|
||||||
openImThirdPort: [ 10190 ]
|
|
||||||
|
|
||||||
###################### RPC Register Name Configuration ######################
|
|
||||||
# RPC service names for registration, it's not recommended to modify these
|
|
||||||
rpcRegisterName:
|
|
||||||
openImUserName: User
|
|
||||||
openImFriendName: Friend
|
|
||||||
openImMsgName: Msg
|
|
||||||
openImPushName: Push
|
|
||||||
openImMessageGatewayName: MessageGateway
|
|
||||||
openImGroupName: Group
|
|
||||||
openImAuthName: Auth
|
|
||||||
openImConversationName: Conversation
|
|
||||||
openImThirdName: Third
|
|
||||||
|
|
||||||
###################### Log Configuration ######################
|
|
||||||
# Log configuration
|
|
||||||
#
|
|
||||||
# Storage directory
|
|
||||||
# Log rotation time
|
|
||||||
# Maximum number of logs to retain
|
|
||||||
# Log level, 6 means all levels
|
|
||||||
# Whether to output to stdout
|
|
||||||
# Whether to output in json format
|
|
||||||
# Whether to include stack trace in logs
|
|
||||||
log:
|
|
||||||
storageLocation: ../logs/
|
|
||||||
rotationTime: 24
|
|
||||||
remainRotationCount: 2
|
|
||||||
remainLogLevel: 6
|
|
||||||
isStdout: false
|
|
||||||
isJson: false
|
|
||||||
withStack: false
|
|
||||||
|
|
||||||
###################### Variables definition ######################
|
|
||||||
# Long connection server configuration
|
|
||||||
#
|
|
||||||
# Websocket port for msg_gateway
|
|
||||||
# Maximum number of websocket connections
|
|
||||||
# Maximum length of websocket request package
|
|
||||||
# Websocket connection handshake timeout
|
|
||||||
longConnSvr:
|
|
||||||
openImWsPort: [ 10001 ]
|
|
||||||
websocketMaxConnNum: 100000
|
|
||||||
openImMessageGatewayPort: [ 10140 ]
|
|
||||||
websocketMaxMsgLen: 4096
|
|
||||||
websocketTimeout: 10
|
|
||||||
|
|
||||||
# Push notification service configuration
|
|
||||||
#
|
|
||||||
# Use GeTui for push notifications
|
|
||||||
# GeTui offline push configuration
|
|
||||||
# FCM offline push configuration
|
|
||||||
# Account file, place it in the config directory
|
|
||||||
# JPush configuration, modify these after applying in JPush backend
|
|
||||||
push:
|
|
||||||
enable: getui
|
|
||||||
geTui:
|
|
||||||
pushUrl: "https://restapi.getui.com/v2/$appId"
|
|
||||||
masterSecret: ''
|
|
||||||
appKey: ''
|
|
||||||
intent: ''
|
|
||||||
channelID: ''
|
|
||||||
channelName: ''
|
|
||||||
fcm:
|
|
||||||
serviceAccount: "x.json"
|
|
||||||
jpns:
|
|
||||||
appKey: ''
|
|
||||||
masterSecret: ''
|
|
||||||
pushUrl: ''
|
|
||||||
pushIntent: ''
|
|
||||||
|
|
||||||
# App manager configuration
|
|
||||||
#
|
|
||||||
# Built-in app manager user IDs
|
|
||||||
# Built-in app manager nicknames
|
|
||||||
manager:
|
|
||||||
userID: [ "openIM123456", "openIM654321", "openIMAdmin" ]
|
|
||||||
nickname: [ "system1", "system2", "system3" ]
|
|
||||||
|
|
||||||
# Multi-platform login policy
|
|
||||||
# For each platform(Android, iOS, Windows, Mac, web), only one can be online at a time
|
|
||||||
multiLoginPolicy: 1
|
|
||||||
|
|
||||||
# Whether to store messages in MySQL, messages in MySQL are only used for management background
|
|
||||||
chatPersistenceMysql: true
|
|
||||||
|
|
||||||
# Message cache timeout in seconds, it's not recommended to modify
|
|
||||||
msgCacheTimeout: 86400
|
|
||||||
|
|
||||||
# Whether to enable read receipts for group chat
|
|
||||||
groupMessageHasReadReceiptEnable: true
|
|
||||||
|
|
||||||
# Whether to enable read receipts for single chat
|
|
||||||
singleMessageHasReadReceiptEnable: true
|
|
||||||
|
|
||||||
# MongoDB offline message retention period in days
|
|
||||||
retainChatRecords: 365
|
|
||||||
|
|
||||||
# Schedule to clear expired messages(older than retainChatRecords days) in MongoDB every Wednesday at 2am
|
|
||||||
# This deletion is just for cleaning up disk usage according to previous configuration retainChatRecords, no notification will be sent
|
|
||||||
chatRecordsClearTime: "0 2 * * 3"
|
|
||||||
|
|
||||||
# Schedule to auto delete messages every day at 2am
|
|
||||||
# This deletion is for messages that have been retained for more than msg_destruct_time (seconds) in the conversation field
|
|
||||||
msgDestructTime: "0 2 * * *"
|
|
||||||
|
|
||||||
# Secret key
|
|
||||||
secret: openIM123
|
|
||||||
|
|
||||||
# Token policy
|
|
||||||
#
|
|
||||||
# Token expiration period in days
|
|
||||||
tokenPolicy:
|
|
||||||
expire: 90
|
|
||||||
|
|
||||||
# Message verification policy
|
|
||||||
#
|
|
||||||
# Whether to verify friendship when sending messages
|
|
||||||
messageVerify:
|
|
||||||
friendVerify: false
|
|
||||||
|
|
||||||
# iOS push notification configuration
|
|
||||||
#
|
|
||||||
# iOS push notification sound
|
|
||||||
# Whether to count badge
|
|
||||||
# Whether it's production environment
|
|
||||||
iosPush:
|
|
||||||
pushSound: "xxx"
|
|
||||||
badgeCount: true
|
|
||||||
production: false
|
|
||||||
|
|
||||||
###################### Third-party service configuration ######################
|
|
||||||
# Callback configuration
|
|
||||||
#
|
|
||||||
# Callback URL
|
|
||||||
# Whether to enable this callback event
|
|
||||||
# Timeout in seconds
|
|
||||||
# Whether to continue execution if callback fails
|
|
||||||
callback:
|
|
||||||
url:
|
|
||||||
beforeSendSingleMsg:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
afterSendSingleMsg:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
beforeSendGroupMsg:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
afterSendGroupMsg:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
msgModify:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
userOnline:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
userOffline:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
userKickOff:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
offlinePush:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
onlinePush:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
superGroupOnlinePush:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
beforeAddFriend:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
beforeUpdateUserInfo:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
beforeCreateGroup:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
beforeMemberJoinGroup:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
beforeSetGroupMemberInfo:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
setMessageReactionExtensions:
|
|
||||||
enable: false
|
|
||||||
timeout: 5
|
|
||||||
failedContinue: true
|
|
||||||
|
|
||||||
###################### Prometheus ######################
|
|
||||||
# Prometheus configuration for various services
|
|
||||||
# The number of Prometheus ports per service needs to correspond to rpcPort
|
|
||||||
# The number of ports needs to be consistent with msg_transfer_service_num in script/path_info.sh
|
|
||||||
prometheus:
|
|
||||||
enable: false
|
|
||||||
prometheusUrl: "https://openim.prometheus"
|
|
||||||
apiPrometheusPort: [20100]
|
|
||||||
userPrometheusPort: [ 20110 ]
|
|
||||||
friendPrometheusPort: [ 20120 ]
|
|
||||||
messagePrometheusPort: [ 20130 ]
|
|
||||||
messageGatewayPrometheusPort: [ 20140 ]
|
|
||||||
groupPrometheusPort: [ 20150 ]
|
|
||||||
authPrometheusPort: [ 20160 ]
|
|
||||||
pushPrometheusPort: [ 20170 ]
|
|
||||||
conversationPrometheusPort: [ 20230 ]
|
|
||||||
rtcPrometheusPort: [ 21300 ]
|
|
||||||
thirdPrometheusPort: [ 21301 ]
|
|
||||||
messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ] # List of ports
|
|
@ -0,0 +1,49 @@
|
|||||||
|
package callbackstruct
|
||||||
|
|
||||||
|
const CallbackBeforeInviteJoinGroupCommand = "callbackBeforeInviteJoinGroupCommand"
|
||||||
|
const CallbackAfterJoinGroupCommand = "callbackAfterJoinGroupCommand"
|
||||||
|
const CallbackAfterSetGroupInfoCommand = "callbackAfterSetGroupInfoCommand"
|
||||||
|
const CallbackBeforeSetGroupInfoCommand = "callbackBeforeSetGroupInfoCommand"
|
||||||
|
|
||||||
|
const CallbackAfterRevokeMsgCommand = "callbackBeforeAfterMsgCommand"
|
||||||
|
const CallbackBeforeAddBlackCommand = "callbackBeforeAddBlackCommand"
|
||||||
|
const CallbackAfterAddFriendCommand = "callbackAfterAddFriendCommand"
|
||||||
|
const CallbackBeforeAddFriendAgreeCommand = "callbackBeforeAddFriendAgreeCommand"
|
||||||
|
|
||||||
|
const CallbackAfterDeleteFriendCommand = "callbackAfterDeleteFriendCommand"
|
||||||
|
const CallbackBeforeImportFriendsCommand = "callbackBeforeImportFriendsCommand"
|
||||||
|
const CallbackAfterImportFriendsCommand = "callbackAfterImportFriendsCommand"
|
||||||
|
const CallbackAfterRemoveBlackCommand = "callbackAfterRemoveBlackCommand"
|
||||||
|
|
||||||
|
const (
|
||||||
|
CallbackQuitGroupCommand = "callbackQuitGroupCommand"
|
||||||
|
CallbackKillGroupCommand = "callbackKillGroupCommand"
|
||||||
|
CallbackDisMissGroupCommand = "callbackDisMissGroupCommand"
|
||||||
|
CallbackBeforeJoinGroupCommand = "callbackBeforeJoinGroupCommand"
|
||||||
|
CallbackGroupMsgReadCommand = "callbackGroupMsgReadCommand"
|
||||||
|
CallbackMsgModifyCommand = "callbackMsgModifyCommand"
|
||||||
|
CallbackAfterUpdateUserInfoCommand = "callbackAfterUpdateUserInfoCommand"
|
||||||
|
CallbackBeforeUserRegisterCommand = "callbackBeforeUserRegisterCommand"
|
||||||
|
CallbackAfterUserRegisterCommand = "callbackAfterUserRegisterCommand"
|
||||||
|
CallbackTransferGroupOwnerAfter = "callbackTransferGroupOwnerAfter"
|
||||||
|
CallbackBeforeSetFriendRemark = "callbackBeforeSetFriendRemark"
|
||||||
|
CallbackAfterSetFriendRemark = "callbackAfterSetFriendRemark"
|
||||||
|
CallbackSingleMsgRead = "callbackSingleMsgRead"
|
||||||
|
CallbackBeforeSendSingleMsgCommand = "callbackBeforeSendSingleMsgCommand"
|
||||||
|
CallbackAfterSendSingleMsgCommand = "callbackAfterSendSingleMsgCommand"
|
||||||
|
CallbackBeforeSendGroupMsgCommand = "callbackBeforeSendGroupMsgCommand"
|
||||||
|
CallbackAfterSendGroupMsgCommand = "callbackAfterSendGroupMsgCommand"
|
||||||
|
CallbackUserOnlineCommand = "callbackUserOnlineCommand"
|
||||||
|
CallbackUserOfflineCommand = "callbackUserOfflineCommand"
|
||||||
|
CallbackUserKickOffCommand = "callbackUserKickOffCommand"
|
||||||
|
CallbackOfflinePushCommand = "callbackOfflinePushCommand"
|
||||||
|
CallbackOnlinePushCommand = "callbackOnlinePushCommand"
|
||||||
|
CallbackSuperGroupOnlinePushCommand = "callbackSuperGroupOnlinePushCommand"
|
||||||
|
CallbackBeforeAddFriendCommand = "callbackBeforeAddFriendCommand"
|
||||||
|
CallbackBeforeUpdateUserInfoCommand = "callbackBeforeUpdateUserInfoCommand"
|
||||||
|
CallbackBeforeCreateGroupCommand = "callbackBeforeCreateGroupCommand"
|
||||||
|
CallbackAfterCreateGroupCommand = "callbackAfterCreateGroupCommand"
|
||||||
|
CallbackBeforeMemberJoinGroupCommand = "callbackBeforeMemberJoinGroupCommand"
|
||||||
|
CallbackBeforeSetGroupMemberInfoCommand = "callbackBeforeSetGroupMemberInfoCommand"
|
||||||
|
CallbackAfterSetGroupMemberInfoCommand = "callbackAfterSetGroupMemberInfoCommand"
|
||||||
|
)
|
@ -0,0 +1,11 @@
|
|||||||
|
package callbackstruct
|
||||||
|
|
||||||
|
type CallbackAfterRevokeMsgReq struct {
|
||||||
|
CallbackCommand `json:"callbackCommand"`
|
||||||
|
ConversationID string `json:"conversationID"`
|
||||||
|
Seq int64 `json:"seq"`
|
||||||
|
UserID string `json:"userID"`
|
||||||
|
}
|
||||||
|
type CallbackAfterRevokeMsgResp struct {
|
||||||
|
CommonCallbackResp
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
package kodo
|
@ -0,0 +1,323 @@
|
|||||||
|
package kodo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
|
awss3config "github.com/aws/aws-sdk-go-v2/config"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||||
|
awss3 "github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
|
awss3types "github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||||
|
"github.com/qiniu/go-sdk/v7/auth"
|
||||||
|
"github.com/qiniu/go-sdk/v7/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minPartSize = 1024 * 1024 * 1 // 1MB
|
||||||
|
maxPartSize = 1024 * 1024 * 1024 * 5 // 5GB
|
||||||
|
maxNumSize = 10000
|
||||||
|
)
|
||||||
|
|
||||||
|
type Kodo struct {
|
||||||
|
AccessKey string
|
||||||
|
SecretKey string
|
||||||
|
Region string
|
||||||
|
Token string
|
||||||
|
Endpoint string
|
||||||
|
BucketURL string
|
||||||
|
Auth *auth.Credentials
|
||||||
|
Client *awss3.Client
|
||||||
|
PresignClient *awss3.PresignClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKodo() (s3.Interface, error) {
|
||||||
|
conf := config.Config.Object.Kodo
|
||||||
|
//init client
|
||||||
|
cfg, err := awss3config.LoadDefaultConfig(context.TODO(),
|
||||||
|
awss3config.WithRegion(conf.Bucket),
|
||||||
|
awss3config.WithEndpointResolverWithOptions(
|
||||||
|
aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
|
||||||
|
return aws.Endpoint{URL: conf.Endpoint}, nil
|
||||||
|
})),
|
||||||
|
awss3config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
|
||||||
|
conf.AccessKeyID,
|
||||||
|
conf.AccessKeySecret,
|
||||||
|
conf.SessionToken),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
client := awss3.NewFromConfig(cfg)
|
||||||
|
presignClient := awss3.NewPresignClient(client)
|
||||||
|
|
||||||
|
return &Kodo{
|
||||||
|
AccessKey: conf.AccessKeyID,
|
||||||
|
SecretKey: conf.AccessKeySecret,
|
||||||
|
Region: conf.Bucket,
|
||||||
|
BucketURL: conf.BucketURL,
|
||||||
|
Auth: auth.New(conf.AccessKeyID, conf.AccessKeySecret),
|
||||||
|
Client: client,
|
||||||
|
PresignClient: presignClient,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) Engine() string {
|
||||||
|
return "kodo"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) PartLimit() *s3.PartLimit {
|
||||||
|
return &s3.PartLimit{
|
||||||
|
MinPartSize: minPartSize,
|
||||||
|
MaxPartSize: maxPartSize,
|
||||||
|
MaxNumSize: maxNumSize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) InitiateMultipartUpload(ctx context.Context, name string) (*s3.InitiateMultipartUploadResult, error) {
|
||||||
|
result, err := k.Client.CreateMultipartUpload(ctx, &awss3.CreateMultipartUploadInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
Key: aws.String(name),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &s3.InitiateMultipartUploadResult{
|
||||||
|
UploadID: aws.ToString(result.UploadId),
|
||||||
|
Bucket: aws.ToString(result.Bucket),
|
||||||
|
Key: aws.ToString(result.Key),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) CompleteMultipartUpload(ctx context.Context, uploadID string, name string, parts []s3.Part) (*s3.CompleteMultipartUploadResult, error) {
|
||||||
|
kodoParts := make([]awss3types.CompletedPart, len(parts))
|
||||||
|
for i, part := range parts {
|
||||||
|
kodoParts[i] = awss3types.CompletedPart{
|
||||||
|
PartNumber: aws.Int32(int32(part.PartNumber)),
|
||||||
|
ETag: aws.String(part.ETag),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result, err := k.Client.CompleteMultipartUpload(ctx, &awss3.CompleteMultipartUploadInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
Key: aws.String(name),
|
||||||
|
UploadId: aws.String(uploadID),
|
||||||
|
MultipartUpload: &awss3types.CompletedMultipartUpload{Parts: kodoParts},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &s3.CompleteMultipartUploadResult{
|
||||||
|
Location: aws.ToString(result.Location),
|
||||||
|
Bucket: aws.ToString(result.Bucket),
|
||||||
|
Key: aws.ToString(result.Key),
|
||||||
|
ETag: strings.ToLower(strings.ReplaceAll(aws.ToString(result.ETag), `"`, ``)),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) PartSize(ctx context.Context, size int64) (int64, error) {
|
||||||
|
if size <= 0 {
|
||||||
|
return 0, errors.New("size must be greater than 0")
|
||||||
|
}
|
||||||
|
if size > maxPartSize*maxNumSize {
|
||||||
|
return 0, fmt.Errorf("size must be less than %db", maxPartSize*maxNumSize)
|
||||||
|
}
|
||||||
|
if size <= minPartSize*maxNumSize {
|
||||||
|
return minPartSize, nil
|
||||||
|
}
|
||||||
|
partSize := size / maxNumSize
|
||||||
|
if size%maxNumSize != 0 {
|
||||||
|
partSize++
|
||||||
|
}
|
||||||
|
return partSize, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) AuthSign(ctx context.Context, uploadID string, name string, expire time.Duration, partNumbers []int) (*s3.AuthSignResult, error) {
|
||||||
|
result := s3.AuthSignResult{
|
||||||
|
URL: k.BucketURL + "/" + name,
|
||||||
|
Query: url.Values{"uploadId": {uploadID}},
|
||||||
|
Header: make(http.Header),
|
||||||
|
Parts: make([]s3.SignPart, len(partNumbers)),
|
||||||
|
}
|
||||||
|
for i, partNumber := range partNumbers {
|
||||||
|
part, _ := k.PresignClient.PresignUploadPart(ctx, &awss3.UploadPartInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
UploadId: aws.String(uploadID),
|
||||||
|
Key: aws.String(name),
|
||||||
|
PartNumber: aws.Int32(int32(partNumber)),
|
||||||
|
})
|
||||||
|
result.Parts[i] = s3.SignPart{
|
||||||
|
PartNumber: partNumber,
|
||||||
|
URL: part.URL,
|
||||||
|
Header: part.SignedHeader,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &result, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) PresignedPutObject(ctx context.Context, name string, expire time.Duration) (string, error) {
|
||||||
|
object, err := k.PresignClient.PresignPutObject(ctx, &awss3.PutObjectInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
Key: aws.String(name),
|
||||||
|
}, func(po *awss3.PresignOptions) {
|
||||||
|
po.Expires = expire
|
||||||
|
})
|
||||||
|
return object.URL, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) DeleteObject(ctx context.Context, name string) error {
|
||||||
|
_, err := k.Client.DeleteObject(ctx, &awss3.DeleteObjectInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
Key: aws.String(name),
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyObjectInfo, error) {
|
||||||
|
result, err := k.Client.CopyObject(ctx, &awss3.CopyObjectInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
CopySource: aws.String(k.Region + "/" + src),
|
||||||
|
Key: aws.String(dst),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &s3.CopyObjectInfo{
|
||||||
|
Key: dst,
|
||||||
|
ETag: strings.ToLower(strings.ReplaceAll(aws.ToString(result.CopyObjectResult.ETag), `"`, ``)),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, error) {
|
||||||
|
info, err := k.Client.HeadObject(ctx, &awss3.HeadObjectInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
Key: aws.String(name),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res := &s3.ObjectInfo{Key: name}
|
||||||
|
res.Size = aws.ToInt64(info.ContentLength)
|
||||||
|
res.ETag = strings.ToLower(strings.ReplaceAll(aws.ToString(info.ETag), `"`, ``))
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) IsNotFound(err error) bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) AbortMultipartUpload(ctx context.Context, uploadID string, name string) error {
|
||||||
|
_, err := k.Client.AbortMultipartUpload(ctx, &awss3.AbortMultipartUploadInput{
|
||||||
|
UploadId: aws.String(uploadID),
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
Key: aws.String(name),
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) ListUploadedParts(ctx context.Context, uploadID string, name string, partNumberMarker int, maxParts int) (*s3.ListUploadedPartsResult, error) {
|
||||||
|
result, err := k.Client.ListParts(ctx, &awss3.ListPartsInput{
|
||||||
|
Key: aws.String(name),
|
||||||
|
UploadId: aws.String(uploadID),
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
MaxParts: aws.Int32(int32(maxParts)),
|
||||||
|
PartNumberMarker: aws.String(strconv.Itoa(partNumberMarker)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res := &s3.ListUploadedPartsResult{
|
||||||
|
Key: aws.ToString(result.Key),
|
||||||
|
UploadID: aws.ToString(result.UploadId),
|
||||||
|
MaxParts: int(aws.ToInt32(result.MaxParts)),
|
||||||
|
UploadedParts: make([]s3.UploadedPart, len(result.Parts)),
|
||||||
|
}
|
||||||
|
// int to string
|
||||||
|
NextPartNumberMarker, err := strconv.Atoi(aws.ToString(result.NextPartNumberMarker))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res.NextPartNumberMarker = NextPartNumberMarker
|
||||||
|
for i, part := range result.Parts {
|
||||||
|
res.UploadedParts[i] = s3.UploadedPart{
|
||||||
|
PartNumber: int(aws.ToInt32(part.PartNumber)),
|
||||||
|
LastModified: aws.ToTime(part.LastModified),
|
||||||
|
ETag: aws.ToString(part.ETag),
|
||||||
|
Size: aws.ToInt64(part.Size),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Kodo) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||||
|
//get object head
|
||||||
|
info, err := k.Client.HeadObject(ctx, &awss3.HeadObjectInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
Key: aws.String(name),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("AccessURL object not found")
|
||||||
|
}
|
||||||
|
if opt != nil {
|
||||||
|
if opt.ContentType != aws.ToString(info.ContentType) {
|
||||||
|
//修改文件类型
|
||||||
|
err := k.SetObjectContentType(ctx, name, opt.ContentType)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("AccessURL setContentType error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imageMogr := ""
|
||||||
|
//image dispose
|
||||||
|
if opt != nil {
|
||||||
|
if opt.Image != nil {
|
||||||
|
//https://developer.qiniu.com/dora/8255/the-zoom
|
||||||
|
process := ""
|
||||||
|
if opt.Image.Width > 0 {
|
||||||
|
process += strconv.Itoa(opt.Image.Width) + "x"
|
||||||
|
}
|
||||||
|
if opt.Image.Height > 0 {
|
||||||
|
if opt.Image.Width > 0 {
|
||||||
|
process += strconv.Itoa(opt.Image.Height)
|
||||||
|
} else {
|
||||||
|
process += "x" + strconv.Itoa(opt.Image.Height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imageMogr = "imageMogr2/thumbnail/" + process
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//expire
|
||||||
|
deadline := time.Now().Add(time.Second * expire).Unix()
|
||||||
|
domain := k.BucketURL
|
||||||
|
query := url.Values{}
|
||||||
|
if opt != nil && opt.Filename != "" {
|
||||||
|
query.Add("attname", opt.Filename)
|
||||||
|
}
|
||||||
|
privateURL := storage.MakePrivateURLv2WithQuery(k.Auth, domain, name, query, deadline)
|
||||||
|
if imageMogr != "" {
|
||||||
|
privateURL += "&" + imageMogr
|
||||||
|
}
|
||||||
|
return privateURL, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *Kodo) SetObjectContentType(ctx context.Context, name string, contentType string) error {
|
||||||
|
//set object content-type
|
||||||
|
_, err := k.Client.CopyObject(ctx, &awss3.CopyObjectInput{
|
||||||
|
Bucket: aws.String(k.Region),
|
||||||
|
CopySource: aws.String(k.Region + "/" + name),
|
||||||
|
Key: aws.String(name),
|
||||||
|
ContentType: aws.String(contentType),
|
||||||
|
MetadataDirective: awss3types.MetadataDirectiveReplace,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
@ -1,70 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
|
||||||
SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
||||||
OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/..
|
|
||||||
|
|
||||||
#Include shell font styles and some basic information
|
|
||||||
source $SCRIPTS_ROOT/lib/init.sh
|
|
||||||
source $SCRIPTS_ROOT/path_info.sh
|
|
||||||
|
|
||||||
cd $SCRIPTS_ROOT
|
|
||||||
|
|
||||||
source $OPENIM_ROOT/.env
|
|
||||||
|
|
||||||
# Check if PASSWORD only contains letters and numbers
|
|
||||||
if [[ "$PASSWORD" =~ ^[a-zA-Z0-9]+$ ]]
|
|
||||||
then
|
|
||||||
echo "PASSWORD is valid."
|
|
||||||
else
|
|
||||||
echo "ERR: PASSWORD should only contain letters and numbers. " $PASSWORD
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo -e "===> ${PURPLE_PREFIX} you user is:$USER ${COLOR_SUFFIX}"
|
|
||||||
echo -e "===> ${PURPLE_PREFIX} you password is:$PASSWORD ${COLOR_SUFFIX}"
|
|
||||||
echo -e "===> ${PURPLE_PREFIX} you minio endpoint is:$MINIO_ENDPOINT ${COLOR_SUFFIX}"
|
|
||||||
echo -e "===> ${PURPLE_PREFIX} you api url is:$API_URL ${COLOR_SUFFIX}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Specify the config file
|
|
||||||
config_file="${OPENIM_ROOT}"/config/config.yaml
|
|
||||||
|
|
||||||
# Load variables from .env file
|
|
||||||
source "${OPENIM_ROOT}"/.env
|
|
||||||
|
|
||||||
# Replace the password and username field for mysql
|
|
||||||
sed -i "/mysql:/,/database:/ s/password:.*/password: $PASSWORD/" $config_file
|
|
||||||
sed -i "/mysql:/,/database:/ s/username:.*/username: $USER/" $config_file
|
|
||||||
|
|
||||||
# Replace the password and username field for mongo
|
|
||||||
sed -i "/mongo:/,/maxPoolSize:/ s/password:.*/password: $PASSWORD/" $config_file
|
|
||||||
sed -i "/mongo:/,/maxPoolSize:/ s/username:.*/username: $USER/" $config_file
|
|
||||||
|
|
||||||
# Replace the password field for redis
|
|
||||||
sed -i '/redis:/,/password:/s/password: .*/password: '${PASSWORD}'/' $config_file
|
|
||||||
|
|
||||||
# Replace accessKeyID and secretAccessKey for minio
|
|
||||||
sed -i "/minio:/,/isDistributedMod:/ s/accessKeyID:.*/accessKeyID: $USER/" $config_file
|
|
||||||
sed -i "/minio:/,/isDistributedMod:/ s/secretAccessKey:.*/secretAccessKey: $PASSWORD/" $config_file
|
|
||||||
sed -i '/minio:/,/endpoint:/s|endpoint: .*|endpoint: '${MINIO_ENDPOINT}'|' $config_file
|
|
||||||
sed -i '/object:/,/apiURL:/s|apiURL: .*|apiURL: '${API_URL}'|' $config_file
|
|
||||||
|
|
||||||
|
|
||||||
# Replace secret for token
|
|
||||||
sed -i "s/secret: .*/secret: $PASSWORD/" $config_file
|
|
Loading…
Reference in new issue