@@ -87,30 +87,43 @@ public static String getOrCreateBucket(Configuration configuration,
8787 // By default, this option is false, meaning the job can not delete the bucket. So enable it only when bucket name
8888 // is not provided.
8989 configuration .setBoolean ("fs.gs.bucket.delete.enable" , true );
90- GCPUtils . createBucket (storage , bucket , dataset . getLocation () , cmekKeyName );
90+ createBucket (storage , bucket , dataset , cmekKeyName );
9191 } else if (storage != null && storage .get (bucket ) == null ) {
92- try {
93- GCPUtils .createBucket (storage , bucket , dataset .getLocation (), cmekKeyName );
94- } catch (StorageException e ) {
95- if (e .getCode () == 409 ) {
96- // A conflict means the bucket already exists
97- // This most likely means multiple stages in the same pipeline are trying to create the same bucket.
98- // Ignore this and move on, since all that matters is that the bucket exists.
99- return bucket ;
100- }
101- String errorMessage = String .format ("Unable to create Cloud Storage bucket '%s' in the same "
102- + "location ('%s') as BigQuery dataset '%s'. " + "Please use a bucket "
103- + "that is in the same location as the dataset. For more details, see %s" ,
104- bucket , dataset .getLocation (), dataset .getDatasetId ().getDataset (),
105- GCPUtils .GCS_SUPPORTED_DOC_URL );
106- throw ErrorUtils .getProgramFailureException (new ErrorCategory (ErrorCategory .ErrorCategoryEnum .PLUGIN ),
107- errorMessage , e .getMessage (), ErrorType .USER , true , ErrorCodeType .HTTP ,
108- String .valueOf (e .getCode ()), GCPUtils .GCS_SUPPORTED_DOC_URL , e );
109- }
92+ createBucket (storage , bucket , dataset , cmekKeyName );
11093 }
11194 return bucket ;
11295 }
11396
97+ private static void createBucket (@ Nullable Storage storage ,
98+ String bucket ,
99+ Dataset dataset ,
100+ @ Nullable CryptoKeyName cmekKeyName ) {
101+ if (storage == null ) {
102+ return ;
103+ }
104+ try {
105+ GCPUtils .createBucket (storage , bucket , dataset .getLocation (), cmekKeyName );
106+ } catch (StorageException e ) {
107+ if (e .getCode () == 409 ) {
108+ // A conflict means the bucket already exists.
109+ // This most likely means multiple stages in the same pipeline are trying to create the same bucket,
110+ // or a retry occurred after a successful bucket creation.
111+ // Ignore this and move on, since all that matters is that the bucket exists.
112+ LOG .debug ("Bucket '{}' already exists, ignoring 409 Conflict: {}" , bucket , e .getMessage ());
113+ return ;
114+ }
115+ String datasetName = dataset .getDatasetId () != null ? dataset .getDatasetId ().getDataset () : "" ;
116+ String errorMessage = String .format ("Unable to create Cloud Storage bucket '%s' in the same "
117+ + "location ('%s') as BigQuery dataset '%s'. " + "Please use a bucket "
118+ + "that is in the same location as the dataset. For more details, see %s" ,
119+ bucket , dataset .getLocation (), datasetName ,
120+ GCPUtils .GCS_SUPPORTED_DOC_URL );
121+ throw ErrorUtils .getProgramFailureException (new ErrorCategory (ErrorCategory .ErrorCategoryEnum .PLUGIN ),
122+ errorMessage , e .getMessage (), ErrorType .USER , true , ErrorCodeType .HTTP ,
123+ String .valueOf (e .getCode ()), GCPUtils .GCS_SUPPORTED_DOC_URL , e );
124+ }
125+ }
126+
114127 /**
115128 * Sets up service account credentials into supplied Hadoop configuration.
116129 *
0 commit comments