refactor: 重构trustlog-sdk目录结构到trustlog/go-trustlog

- 将所有trustlog-sdk文件移动到trustlog/go-trustlog/目录
- 更新README中所有import路径从trustlog-sdk改为go-trustlog
- 更新cookiecutter配置文件中的项目名称
- 更新根目录.lefthook.yml以引用新位置的配置
- 添加go.sum文件到版本控制
- 删除过时的示例文件

这次重构与trustlog-server保持一致的目录结构,
为未来支持多语言SDK(Python、Java等)预留空间。
This commit is contained in:
ryan
2025-12-22 13:37:57 +08:00
commit d313449c5c
87 changed files with 20622 additions and 0 deletions

View File

@@ -0,0 +1,608 @@
package mocks
import (
"context"
"errors"
"fmt"
"sync"
"time"
"github.com/apache/pulsar-client-go/pulsar"
)
// MockPulsarClient is a mock implementation of pulsar.Client.
type MockPulsarClient struct {
mu sync.RWMutex
producers map[string]*MockProducer
consumers map[string]*MockConsumer
closed bool
}
// NewMockPulsarClient creates a new mock Pulsar client.
func NewMockPulsarClient() *MockPulsarClient {
return &MockPulsarClient{
producers: make(map[string]*MockProducer),
consumers: make(map[string]*MockConsumer),
}
}
// CreateProducer creates a mock producer.
func (m *MockPulsarClient) CreateProducer(options pulsar.ProducerOptions) (pulsar.Producer, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return nil, errors.New("client is closed")
}
if m.producers == nil {
m.producers = make(map[string]*MockProducer)
}
producer := NewMockProducer(options.Topic)
m.producers[options.Topic] = producer
return producer, nil
}
// Subscribe creates a mock consumer.
func (m *MockPulsarClient) Subscribe(options pulsar.ConsumerOptions) (pulsar.Consumer, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return nil, errors.New("client is closed")
}
if m.consumers == nil {
m.consumers = make(map[string]*MockConsumer)
}
consumer := NewMockConsumer(options.Topic, options.Name)
m.consumers[options.Name] = consumer
return consumer, nil
}
// CreateReader is not implemented.
func (m *MockPulsarClient) CreateReader(options pulsar.ReaderOptions) (pulsar.Reader, error) {
return nil, errors.New("CreateReader not implemented")
}
// CreateTableView is not implemented.
func (m *MockPulsarClient) CreateTableView(options pulsar.TableViewOptions) (pulsar.TableView, error) {
return nil, errors.New("CreateTableView not implemented")
}
// NewTransaction creates a new transaction.
func (m *MockPulsarClient) NewTransaction(timeout time.Duration) (pulsar.Transaction, error) {
return nil, errors.New("not implemented")
}
// TopicPartitions returns the partitions for a topic.
func (m *MockPulsarClient) TopicPartitions(topic string) ([]string, error) {
return []string{topic}, nil
}
// Close closes the mock client.
func (m *MockPulsarClient) Close() {
m.mu.Lock()
defer m.mu.Unlock()
m.closed = true
for _, producer := range m.producers {
producer.Close()
}
for _, consumer := range m.consumers {
consumer.Close()
}
}
// GetProducer returns a producer by topic (for testing).
func (m *MockPulsarClient) GetProducer(topic string) *MockProducer {
m.mu.RLock()
defer m.mu.RUnlock()
return m.producers[topic]
}
// GetConsumer returns a consumer by name (for testing).
func (m *MockPulsarClient) GetConsumer(name string) *MockConsumer {
m.mu.RLock()
defer m.mu.RUnlock()
return m.consumers[name]
}
// MockProducer is a mock implementation of pulsar.Producer.
type MockProducer struct {
topic string
name string
messages []*pulsar.ProducerMessage
mu sync.RWMutex
closed bool
}
// NewMockProducer creates a new mock producer.
func NewMockProducer(topic string) *MockProducer {
return &MockProducer{
topic: topic,
name: "mock-producer",
messages: make([]*pulsar.ProducerMessage, 0),
}
}
// Topic returns the topic name.
func (m *MockProducer) Topic() string {
return m.topic
}
// Name returns the producer name.
func (m *MockProducer) Name() string {
return m.name
}
// Send sends a message.
func (m *MockProducer) Send(ctx context.Context, msg *pulsar.ProducerMessage) (pulsar.MessageID, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return nil, errors.New("producer is closed")
}
m.messages = append(m.messages, msg)
return &MockMessageID{id: len(m.messages)}, nil
}
// SendAsync sends a message asynchronously.
func (m *MockProducer) SendAsync(
ctx context.Context,
msg *pulsar.ProducerMessage,
callback func(pulsar.MessageID, *pulsar.ProducerMessage, error),
) {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
callback(nil, msg, errors.New("producer is closed"))
return
}
m.messages = append(m.messages, msg)
callback(&MockMessageID{id: len(m.messages)}, msg, nil)
}
// LastSequenceID returns the last sequence ID.
func (m *MockProducer) LastSequenceID() int64 {
return 0
}
// Flush flushes pending messages.
func (m *MockProducer) Flush() error {
return nil
}
// FlushWithCtx flushes pending messages with context.
func (m *MockProducer) FlushWithCtx(ctx context.Context) error {
return nil
}
// Close closes the producer.
func (m *MockProducer) Close() {
m.mu.Lock()
defer m.mu.Unlock()
m.closed = true
}
// GetMessages returns all sent messages (for testing).
func (m *MockProducer) GetMessages() []*pulsar.ProducerMessage {
m.mu.RLock()
defer m.mu.RUnlock()
result := make([]*pulsar.ProducerMessage, len(m.messages))
copy(result, m.messages)
return result
}
// MockConsumer is a mock implementation of pulsar.Consumer.
type MockConsumer struct {
topic string
name string
messageChan chan pulsar.ConsumerMessage
mu sync.RWMutex
closed bool
}
const (
// defaultMessageChannelSize 定义消息通道的默认缓冲大小.
defaultMessageChannelSize = 10
)
// NewMockConsumer creates a new mock consumer.
func NewMockConsumer(topic, name string) *MockConsumer {
return &MockConsumer{
topic: topic,
name: name,
messageChan: make(chan pulsar.ConsumerMessage, defaultMessageChannelSize),
}
}
// Subscription returns the subscription name.
func (m *MockConsumer) Subscription() string {
return m.name
}
// Topic returns the topic name.
func (m *MockConsumer) Topic() string {
return m.topic
}
// Chan returns the message channel.
func (m *MockConsumer) Chan() <-chan pulsar.ConsumerMessage {
return m.messageChan
}
// Ack acknowledges a message.
func (m *MockConsumer) Ack(msg pulsar.Message) error {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// Nack negatively acknowledges a message.
func (m *MockConsumer) Nack(msg pulsar.Message) {
m.mu.RLock()
defer m.mu.RUnlock()
// Mock implementation: 实际不做任何操作
_ = msg
}
// NackID negatively acknowledges a message by ID.
func (m *MockConsumer) NackID(msgID pulsar.MessageID) {
m.mu.RLock()
defer m.mu.RUnlock()
// Mock implementation: 实际不做任何操作
_ = msgID
}
// Unsubscribe unsubscribes the consumer.
func (m *MockConsumer) Unsubscribe() error {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// UnsubscribeForce forcefully unsubscribes the consumer.
func (m *MockConsumer) UnsubscribeForce() error {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// Receive receives a single message.
func (m *MockConsumer) Receive(ctx context.Context) (pulsar.Message, error) {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return nil, errors.New("consumer is closed")
}
select {
case msg := <-m.messageChan:
return msg.Message, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
// AckCumulative acknowledges all messages up to and including the provided message.
func (m *MockConsumer) AckCumulative(msg pulsar.Message) error {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// AckID acknowledges a message by ID.
func (m *MockConsumer) AckID(msgID pulsar.MessageID) error {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// AckIDCumulative acknowledges all messages up to and including the provided message ID.
func (m *MockConsumer) AckIDCumulative(msgID pulsar.MessageID) error {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// AckIDList acknowledges a list of message IDs.
func (m *MockConsumer) AckIDList(msgIDs []pulsar.MessageID) error {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// AckWithTxn acknowledges a message with transaction.
func (m *MockConsumer) AckWithTxn(msg pulsar.Message, txn pulsar.Transaction) error {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// GetLastMessageIDs returns the last message IDs.
func (m *MockConsumer) GetLastMessageIDs() ([]pulsar.TopicMessageID, error) {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return nil, errors.New("consumer is closed")
}
return []pulsar.TopicMessageID{}, nil
}
// ReconsumeLater reconsumes a message later with delay.
func (m *MockConsumer) ReconsumeLater(msg pulsar.Message, delay time.Duration) {
m.mu.RLock()
defer m.mu.RUnlock()
// Mock implementation: 实际不做任何操作
_, _ = msg, delay
}
// ReconsumeLaterWithCustomProperties reconsumes a message later with custom properties.
func (m *MockConsumer) ReconsumeLaterWithCustomProperties(
msg pulsar.Message,
customProperties map[string]string,
delay time.Duration,
) {
m.mu.RLock()
defer m.mu.RUnlock()
// Mock implementation: 实际不做任何操作
_, _, _ = msg, customProperties, delay
}
// Seek seeks to a message ID.
func (m *MockConsumer) Seek(msgID pulsar.MessageID) error {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// SeekByTime seeks to a time.
func (m *MockConsumer) SeekByTime(t time.Time) error {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return errors.New("consumer is closed")
}
return nil
}
// Name returns the consumer name.
func (m *MockConsumer) Name() string {
m.mu.RLock()
defer m.mu.RUnlock()
return m.name
}
// Close closes the consumer.
func (m *MockConsumer) Close() {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return
}
m.closed = true
close(m.messageChan)
}
// SendMessage sends a message to the consumer channel (for testing).
func (m *MockConsumer) SendMessage(msg pulsar.ConsumerMessage) error {
m.mu.RLock()
defer m.mu.RUnlock()
if m.closed {
return errors.New("consumer is closed")
}
select {
case m.messageChan <- msg:
return nil
default:
return errors.New("channel full")
}
}
// MockMessageID is a mock implementation of pulsar.MessageID.
type MockMessageID struct {
id int
}
// Serialize serializes the message ID.
func (m *MockMessageID) Serialize() []byte {
return []byte{byte(m.id)}
}
// BatchIdx returns the batch index.
func (m *MockMessageID) BatchIdx() int32 {
return 0
}
// BatchSize returns the batch size.
func (m *MockMessageID) BatchSize() int32 {
return 1
}
// String returns the string representation of the message ID.
func (m *MockMessageID) String() string {
return fmt.Sprintf("mock-message-id-%d", m.id)
}
// EntryID returns the entry ID.
func (m *MockMessageID) EntryID() int64 {
return int64(m.id)
}
// LedgerID returns the ledger ID.
func (m *MockMessageID) LedgerID() int64 {
return int64(m.id)
}
// PartitionIdx returns the partition index.
func (m *MockMessageID) PartitionIdx() int32 {
return 0
}
// MockMessage is a mock implementation of pulsar.Message.
type MockMessage struct {
key string
payload []byte
id pulsar.MessageID
}
// NewMockMessage creates a new mock message.
func NewMockMessage(key string, payload []byte) *MockMessage {
return &MockMessage{
key: key,
payload: payload,
id: &MockMessageID{id: 1},
}
}
// Topic returns the topic name.
func (m *MockMessage) Topic() string {
return "mock-topic"
}
// Properties returns message properties.
func (m *MockMessage) Properties() map[string]string {
return make(map[string]string)
}
// Payload returns the message payload.
func (m *MockMessage) Payload() []byte {
return m.payload
}
// ID returns the message ID.
func (m *MockMessage) ID() pulsar.MessageID {
return m.id
}
// PublishTime returns the publish time.
func (m *MockMessage) PublishTime() time.Time {
return time.Now()
}
// EventTime returns the event time.
func (m *MockMessage) EventTime() time.Time {
return time.Time{}
}
// Key returns the message key.
func (m *MockMessage) Key() string {
return m.key
}
// OrderingKey returns the ordering key.
func (m *MockMessage) OrderingKey() string {
return ""
}
// RedeliveryCount returns the redelivery count.
func (m *MockMessage) RedeliveryCount() uint32 {
return 0
}
// IsReplicated returns whether the message is replicated.
func (m *MockMessage) IsReplicated() bool {
return false
}
// GetReplicatedFrom returns the replication source.
func (m *MockMessage) GetReplicatedFrom() string {
return ""
}
// GetSchemaValue returns the schema value.
func (m *MockMessage) GetSchemaValue(v interface{}) error {
return nil
}
// GetEncryptionContext returns the encryption context.
func (m *MockMessage) GetEncryptionContext() *pulsar.EncryptionContext {
return nil
}
// Index returns the message index.
func (m *MockMessage) Index() *uint64 {
return nil
}
// BrokerPublishTime returns the broker publish time.
func (m *MockMessage) BrokerPublishTime() *time.Time {
return nil
}
// ProducerName returns the producer name.
func (m *MockMessage) ProducerName() string {
return "mock-producer"
}
// SchemaVersion returns the schema version.
func (m *MockMessage) SchemaVersion() []byte {
return nil
}
// ReplicatedFrom returns the replication source.
func (m *MockMessage) ReplicatedFrom() string {
return ""
}
// NewMockConsumerMessage creates a new mock consumer message.
func NewMockConsumerMessage(key string, payload []byte) pulsar.ConsumerMessage {
return pulsar.ConsumerMessage{
Message: NewMockMessage(key, payload),
Consumer: nil,
}
}