-
Notifications
You must be signed in to change notification settings - Fork 198
Expand file tree
/
Copy paths3.go
More file actions
118 lines (102 loc) · 3.6 KB
/
Copy paths3.go
File metadata and controls
118 lines (102 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package conns3
import (
"context"
"fmt"
"strconv"
"github.com/aws/aws-sdk-go-v2/service/s3"
"go.temporal.io/sdk/log"
metadataStore "github.com/PeerDB-io/peerdb/flow/connectors/external_metadata"
"github.com/PeerDB-io/peerdb/flow/connectors/utils"
"github.com/PeerDB-io/peerdb/flow/generated/protos"
"github.com/PeerDB-io/peerdb/flow/internal"
"github.com/PeerDB-io/peerdb/flow/model"
)
type S3Connector struct {
*metadataStore.PostgresMetadata
logger log.Logger
credentialsProvider utils.AWSCredentialsProvider
client s3.Client
url string
}
func NewS3Connector(
ctx context.Context,
config *protos.S3Config,
) (*S3Connector, error) {
logger := internal.LoggerFromCtx(ctx)
provider, err := utils.GetAWSCredentialsProvider(ctx, "s3", utils.NewPeerAWSCredentials(config))
if err != nil {
return nil, err
}
s3Client, err := utils.CreateS3Client(ctx, provider)
if err != nil {
return nil, fmt.Errorf("failed to create S3 client: %w", err)
}
pgMetadata, err := metadataStore.NewPostgresMetadata(ctx)
if err != nil {
logger.Error("failed to create postgres metadata store", "error", err)
return nil, err
}
return &S3Connector{
url: config.Url,
PostgresMetadata: pgMetadata,
client: *s3Client,
credentialsProvider: provider,
logger: logger,
}, nil
}
func (c *S3Connector) CreateRawTable(_ context.Context, req *protos.CreateRawTableInput) (*protos.CreateRawTableOutput, error) {
c.logger.Info("CreateRawTable for S3 is a no-op")
return nil, nil
}
func (c *S3Connector) Close() error {
return nil
}
func (c *S3Connector) ValidateCheck(ctx context.Context) error {
bucketPrefix, parseErr := utils.NewS3BucketAndPrefix(c.url)
if parseErr != nil {
return fmt.Errorf("failed to parse bucket url: %w", parseErr)
}
return utils.PutAndRemoveS3(ctx, &c.client, bucketPrefix.Bucket, bucketPrefix.Prefix)
}
func (c *S3Connector) ConnectionActive(ctx context.Context) error {
return nil
}
func (c *S3Connector) SyncRecords(ctx context.Context, req *model.SyncRecordsRequest[model.RecordItems]) (*model.SyncResponse, error) {
tableNameRowsMapping := utils.InitialiseTableRowsMap(req.TableMappings)
streamReq := model.NewRecordsToStreamRequest(req.Records.GetRecords(), tableNameRowsMapping, req.SyncBatchID)
recordStream, err := utils.RecordsToRawTableStream(streamReq)
if err != nil {
return nil, fmt.Errorf("failed to convert records to raw table stream: %w", err)
}
qrepConfig := &protos.QRepConfig{
FlowJobName: req.FlowJobName,
DestinationTableIdentifier: "raw_table_" + req.FlowJobName,
Env: req.Env,
}
partition := &protos.QRepPartition{
PartitionId: strconv.FormatInt(req.SyncBatchID, 10),
}
numRecords, err := c.SyncQRepRecords(ctx, qrepConfig, partition, recordStream)
if err != nil {
return nil, err
}
c.logger.Info(fmt.Sprintf("Synced %d records", numRecords))
lastCheckpoint := req.Records.GetLastCheckpoint()
if err := c.FinishBatch(ctx, req.FlowJobName, req.SyncBatchID, lastCheckpoint); err != nil {
c.logger.Error("failed to increment id", "error", err)
return nil, err
}
return &model.SyncResponse{
LastSyncedCheckpoint: lastCheckpoint,
NumRecordsSynced: numRecords,
CurrentSyncBatchID: req.SyncBatchID,
TableNameRowsMapping: tableNameRowsMapping,
TableSchemaDeltas: req.Records.SchemaDeltas,
}, nil
}
func (c *S3Connector) ReplayTableSchemaDeltas(_ context.Context, _ map[string]string,
flowJobName string, schemaDeltas []*protos.TableSchemaDelta,
) error {
c.logger.Info("ReplayTableSchemaDeltas for S3 is a no-op")
return nil
}