157 lines
3.9 KiB
Go
157 lines
3.9 KiB
Go
|
|
package highclient
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"errors"
|
|||
|
|
"fmt"
|
|||
|
|
|
|||
|
|
"github.com/ThreeDotsLabs/watermill/message"
|
|||
|
|
|
|||
|
|
"go.yandata.net/iod/iod/trustlog-sdk/api/adapter"
|
|||
|
|
"go.yandata.net/iod/iod/trustlog-sdk/api/logger"
|
|||
|
|
"go.yandata.net/iod/iod/trustlog-sdk/api/model"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
type Client struct {
|
|||
|
|
publisher message.Publisher
|
|||
|
|
logger logger.Logger
|
|||
|
|
envelopeConfig model.EnvelopeConfig
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewClient 创建HighClient,使用Envelope序列化方式.
|
|||
|
|
// publisher可以使用任意(包含forwarder)创建的publisher,但是我们所有的订阅者必须可以处理Envelope格式的消息.
|
|||
|
|
// 参数:
|
|||
|
|
// - publisher: 消息发布器
|
|||
|
|
// - logger: 日志记录器
|
|||
|
|
// - envelopeConfig: SM2密钥配置,用于签名和序列化
|
|||
|
|
func NewClient(publisher message.Publisher, logger logger.Logger, envelopeConfig model.EnvelopeConfig) *Client {
|
|||
|
|
return &Client{
|
|||
|
|
publisher: publisher,
|
|||
|
|
logger: logger,
|
|||
|
|
envelopeConfig: envelopeConfig,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (c *Client) GetLow() message.Publisher {
|
|||
|
|
return c.publisher
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (c *Client) OperationPublish(operation *model.Operation) error {
|
|||
|
|
if operation == nil {
|
|||
|
|
c.logger.Error("operation publish failed: operation is nil")
|
|||
|
|
return errors.New("operation cannot be nil")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
c.logger.Debug("publishing operation",
|
|||
|
|
"opID", operation.OpID,
|
|||
|
|
"opType", operation.OpType,
|
|||
|
|
"doPrefix", operation.DoPrefix,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
err := publish(operation, adapter.OperationTopic, c.publisher, c.envelopeConfig, c.logger)
|
|||
|
|
if err != nil {
|
|||
|
|
c.logger.Error("operation publish failed",
|
|||
|
|
"opID", operation.OpID,
|
|||
|
|
"error", err,
|
|||
|
|
)
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
c.logger.Info("operation published successfully",
|
|||
|
|
"opID", operation.OpID,
|
|||
|
|
"opType", operation.OpType,
|
|||
|
|
)
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (c *Client) RecordPublish(record *model.Record) error {
|
|||
|
|
if record == nil {
|
|||
|
|
c.logger.Error("record publish failed: record is nil")
|
|||
|
|
return errors.New("record cannot be nil")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
c.logger.Debug("publishing record",
|
|||
|
|
"recordID", record.ID,
|
|||
|
|
"rcType", record.RCType,
|
|||
|
|
"doPrefix", record.DoPrefix,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
err := publish(record, adapter.RecordTopic, c.publisher, c.envelopeConfig, c.logger)
|
|||
|
|
if err != nil {
|
|||
|
|
c.logger.Error("record publish failed",
|
|||
|
|
"recordID", record.ID,
|
|||
|
|
"error", err,
|
|||
|
|
)
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
c.logger.Info("record published successfully",
|
|||
|
|
"recordID", record.ID,
|
|||
|
|
"rcType", record.RCType,
|
|||
|
|
)
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (c *Client) Close() error {
|
|||
|
|
c.logger.Info("closing high client")
|
|||
|
|
err := c.publisher.Close()
|
|||
|
|
if err != nil {
|
|||
|
|
c.logger.Error("failed to close publisher", "error", err)
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
c.logger.Info("high client closed successfully")
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// publish 通用的发布函数,支持任何实现了 Trustlog 接口的类型。
|
|||
|
|
// 使用 Envelope 格式序列化并发布到指定 topic。
|
|||
|
|
func publish(
|
|||
|
|
data model.Trustlog,
|
|||
|
|
topic string,
|
|||
|
|
publisher message.Publisher,
|
|||
|
|
config model.EnvelopeConfig,
|
|||
|
|
logger logger.Logger,
|
|||
|
|
) error {
|
|||
|
|
messageKey := data.Key()
|
|||
|
|
|
|||
|
|
logger.Debug("starting envelope serialization",
|
|||
|
|
"messageKey", messageKey,
|
|||
|
|
"topic", topic,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 使用 Envelope 序列化(MarshalTrustlog 会自动提取 producerID)
|
|||
|
|
envelopeData, err := model.MarshalTrustlog(data, config)
|
|||
|
|
if err != nil {
|
|||
|
|
logger.Error("envelope serialization failed",
|
|||
|
|
"messageKey", messageKey,
|
|||
|
|
"error", err,
|
|||
|
|
)
|
|||
|
|
return fmt.Errorf("failed to marshal envelope: %w", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.Debug("envelope serialized successfully",
|
|||
|
|
"messageKey", messageKey,
|
|||
|
|
"envelopeSize", len(envelopeData),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
msg := message.NewMessage(messageKey, envelopeData)
|
|||
|
|
logger.Debug("publishing message to topic",
|
|||
|
|
"messageKey", messageKey,
|
|||
|
|
"topic", topic,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if publishErr := publisher.Publish(topic, msg); publishErr != nil {
|
|||
|
|
logger.Error("failed to publish to topic",
|
|||
|
|
"messageKey", messageKey,
|
|||
|
|
"topic", topic,
|
|||
|
|
"error", publishErr,
|
|||
|
|
)
|
|||
|
|
return fmt.Errorf("failed to publish message to topic %s: %w", topic, publishErr)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.Debug("message published to topic successfully",
|
|||
|
|
"messageKey", messageKey,
|
|||
|
|
"topic", topic,
|
|||
|
|
)
|
|||
|
|
return nil
|
|||
|
|
}
|