Skip to content

Commit 4068e96

Browse files
Swapping ProjectId with ProjectNubmer for DataStream APIs (#733)
1 parent 8055ccd commit 4068e96

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
cloud.google.com/go/datastream v1.10.3
99
cloud.google.com/go/monitoring v1.16.3
1010
cloud.google.com/go/pubsub v1.33.0
11+
cloud.google.com/go/resourcemanager v1.9.4
1112
cloud.google.com/go/spanner v1.53.0
1213
cloud.google.com/go/storage v1.30.1
1314
github.com/DATA-DOG/go-sqlmock v1.5.1

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIA
4646
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
4747
cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g=
4848
cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc=
49+
cloud.google.com/go/resourcemanager v1.9.4 h1:JwZ7Ggle54XQ/FVYSBrMLOQIKoIT/uer8mmNvNLK51k=
50+
cloud.google.com/go/resourcemanager v1.9.4/go.mod h1:N1dhP9RFvo3lUfwtfLWVxfUWq8+KUQ+XLlHLH3BoFJ0=
4951
cloud.google.com/go/spanner v1.53.0 h1:/NzWQJ1MEhdRcffiutRKbW/AIGVKhcTeivWTDjEyCCo=
5052
cloud.google.com/go/spanner v1.53.0/go.mod h1:liG4iCeLqm5L3fFLU5whFITqP0e0orsAW1uUSrd4rws=
5153
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=

streaming/streaming.go

+39-6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import (
3131
dataflowpb "google.golang.org/genproto/googleapis/dataflow/v1beta3"
3232
"google.golang.org/protobuf/types/known/fieldmaskpb"
3333

34+
resourcemanager "cloud.google.com/go/resourcemanager/apiv3"
35+
resourcemanagerpb "cloud.google.com/go/resourcemanager/apiv3/resourcemanagerpb"
3436
"github.com/GoogleCloudPlatform/spanner-migration-tool/common/constants"
3537
"github.com/GoogleCloudPlatform/spanner-migration-tool/common/utils"
3638
"github.com/GoogleCloudPlatform/spanner-migration-tool/internal"
@@ -106,7 +108,7 @@ type DataflowCfg struct {
106108

107109
type StreamingCfg struct {
108110
DatastreamCfg DatastreamCfg `json:"datastreamCfg"`
109-
GcsCfg GcsCfg `json:"gcsCfg"`
111+
GcsCfg GcsCfg `json:"gcsCfg"`
110112
DataflowCfg DataflowCfg `json:"dataflowCfg"`
111113
TmpDir string `json:"tmpDir"`
112114
PubsubCfg internal.PubsubResources `json:"pubsubCfg"`
@@ -463,7 +465,8 @@ func createNotificationOnBucket(ctx context.Context, storageClient *storage.Clie
463465

464466
// LaunchStream populates the parameters from the streaming config and triggers a stream on Cloud Datastream.
465467
func LaunchStream(ctx context.Context, sourceProfile profiles.SourceProfile, dbList []profiles.LogicalShard, projectID string, datastreamCfg DatastreamCfg) error {
466-
fmt.Println("Launching stream ", fmt.Sprintf("projects/%s/locations/%s", projectID, datastreamCfg.StreamLocation))
468+
projectNumberResource := GetProjectNumberResource(ctx, fmt.Sprintf("projects/%s", projectID))
469+
fmt.Println("Launching stream ", fmt.Sprintf("%s/locations/%s", projectNumberResource, datastreamCfg.StreamLocation))
467470
dsClient, err := datastream.NewClient(ctx)
468471
if err != nil {
469472
return fmt.Errorf("datastream client can not be created: %v", err)
@@ -478,15 +481,15 @@ func LaunchStream(ctx context.Context, sourceProfile profiles.SourceProfile, dbL
478481
FileFormat: &datastreampb.GcsDestinationConfig_AvroFileFormat{},
479482
}
480483
srcCfg := &datastreampb.SourceConfig{
481-
SourceConnectionProfile: fmt.Sprintf("projects/%s/locations/%s/connectionProfiles/%s", projectID, datastreamCfg.SourceConnectionConfig.Location, datastreamCfg.SourceConnectionConfig.Name),
484+
SourceConnectionProfile: fmt.Sprintf("%s/locations/%s/connectionProfiles/%s", projectNumberResource, datastreamCfg.SourceConnectionConfig.Location, datastreamCfg.SourceConnectionConfig.Name),
482485
}
483486
err = getSourceStreamConfig(srcCfg, sourceProfile, dbList, datastreamCfg)
484487
if err != nil {
485488
return fmt.Errorf("could not get source stream config: %v", err)
486489
}
487490

488491
dstCfg := &datastreampb.DestinationConfig{
489-
DestinationConnectionProfile: fmt.Sprintf("projects/%s/locations/%s/connectionProfiles/%s", projectID, datastreamCfg.DestinationConnectionConfig.Location, datastreamCfg.DestinationConnectionConfig.Name),
492+
DestinationConnectionProfile: fmt.Sprintf("%s/locations/%s/connectionProfiles/%s", projectNumberResource, datastreamCfg.DestinationConnectionConfig.Location, datastreamCfg.DestinationConnectionConfig.Name),
490493
DestinationStreamConfig: &datastreampb.DestinationConfig_GcsDestinationConfig{GcsDestinationConfig: gcsDstCfg},
491494
}
492495
streamInfo := &datastreampb.Stream{
@@ -497,7 +500,7 @@ func LaunchStream(ctx context.Context, sourceProfile profiles.SourceProfile, dbL
497500
BackfillStrategy: &datastreampb.Stream_BackfillAll{BackfillAll: &datastreampb.Stream_BackfillAllStrategy{}},
498501
}
499502
createStreamRequest := &datastreampb.CreateStreamRequest{
500-
Parent: fmt.Sprintf("projects/%s/locations/%s", projectID, datastreamCfg.StreamLocation),
503+
Parent: fmt.Sprintf("%s/locations/%s", projectNumberResource, datastreamCfg.StreamLocation),
501504
StreamId: datastreamCfg.StreamId,
502505
Stream: streamInfo,
503506
}
@@ -518,7 +521,7 @@ func LaunchStream(ctx context.Context, sourceProfile profiles.SourceProfile, dbL
518521
fmt.Println("Successfully created stream ", datastreamCfg.StreamId)
519522

520523
fmt.Print("Setting stream state to RUNNING...")
521-
streamInfo.Name = fmt.Sprintf("projects/%s/locations/%s/streams/%s", projectID, datastreamCfg.StreamLocation, datastreamCfg.StreamId)
524+
streamInfo.Name = fmt.Sprintf("%s/locations/%s/streams/%s", projectNumberResource, datastreamCfg.StreamLocation, datastreamCfg.StreamId)
522525
updateStreamRequest := &datastreampb.UpdateStreamRequest{
523526
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"state"}},
524527
Stream: streamInfo,
@@ -756,6 +759,36 @@ func CreateStreamingConfig(pl profiles.DataShard) StreamingCfg {
756759
return streamingCfg
757760
}
758761

762+
// Maps Project-Id to ProjectNumber.
763+
var ProjectNumberResourceCache sync.Map
764+
765+
// Returns a string that encodes the project number like `projects/12345`
766+
func GetProjectNumberResource(ctx context.Context, projectID string) string {
767+
projectNumberResource, found := ProjectNumberResourceCache.Load(projectID)
768+
if found {
769+
return projectNumberResource.(string)
770+
}
771+
772+
rmClient, err := resourcemanager.NewProjectsClient(ctx)
773+
if err != nil {
774+
logger.Log.Warn(fmt.Sprintf("Could not create resourcemanager client to query project number. Defaulting to ProjectId=%s. error=%v",
775+
projectID, err))
776+
return projectID
777+
}
778+
defer rmClient.Close()
779+
req := resourcemanagerpb.GetProjectRequest{Name: projectID}
780+
project, err := rmClient.GetProject(ctx, &req)
781+
if err != nil {
782+
logger.Log.Warn(fmt.Sprintf("Could not query resourcemanager to get project number. Defaulting to ProjectId=%s. error=%v",
783+
projectID, err))
784+
return projectID
785+
}
786+
projectNumberResource = project.GetName()
787+
ProjectNumberResourceCache.Store(projectID, projectNumberResource)
788+
return projectNumberResource.(string)
789+
790+
}
791+
759792
func StartDatastream(ctx context.Context, streamingCfg StreamingCfg, sourceProfile profiles.SourceProfile, targetProfile profiles.TargetProfile, schemaDetails map[string]internal.SchemaDetails) (StreamingCfg, error) {
760793
driver := sourceProfile.Driver
761794
var dbList []profiles.LogicalShard

0 commit comments

Comments
 (0)