Skip to content

Commit 12aa934

Browse files
Fixed NPE on GCSSource when bucket does not exist
1 parent d6dbdb7 commit 12aa934

File tree

1 file changed

+37
-26
lines changed

1 file changed

+37
-26
lines changed

src/main/java/io/cdap/plugin/gcp/gcs/source/GCSSource.java

+37-26
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.cdap.plugin.gcp.gcs.source;
1818

1919
import com.google.auth.Credentials;
20+
import com.google.cloud.storage.Bucket;
2021
import com.google.cloud.storage.Storage;
2122
import com.google.cloud.storage.StorageException;
2223
import com.google.common.base.Strings;
@@ -55,6 +56,7 @@
5556
import java.util.HashMap;
5657
import java.util.List;
5758
import java.util.Map;
59+
import java.util.Objects;
5860
import java.util.regex.Pattern;
5961
import javax.annotation.Nullable;
6062

@@ -95,40 +97,49 @@ public void prepareRun(BatchSourceContext context) throws Exception {
9597
bucketName = GCSPath.from(path).getBucket();
9698
} catch (IllegalArgumentException e) {
9799
collector.addFailure(e.getMessage(), null)
98-
.withStacktrace(e.getStackTrace());
100+
.withStacktrace(e.getStackTrace());
99101
collector.getOrThrowException();
100102
}
101103

102104
Boolean isServiceAccountFilePath = config.connection.isServiceAccountFilePath();
103105
if (isServiceAccountFilePath == null) {
104106
collector.addFailure("Service account type is undefined.",
105-
"Must be `filePath` or `JSON`");
107+
"Must be `filePath` or `JSON`");
106108
collector.getOrThrowException();
107109
}
108110

109111
Credentials credentials = null;
110112
try {
111113
credentials = config.connection.getServiceAccount() == null ?
112-
null : GCPUtils.loadServiceAccountCredentials(config.connection.getServiceAccount(),
113-
isServiceAccountFilePath);
114+
null : GCPUtils.loadServiceAccountCredentials(config.connection.getServiceAccount(),
115+
isServiceAccountFilePath);
114116
} catch (Exception e) {
115117
String errorReason = "Unable to load service account credentials.";
116118
collector.addFailure(String.format("%s %s", errorReason, e.getMessage()), null)
117-
.withStacktrace(e.getStackTrace());
119+
.withStacktrace(e.getStackTrace());
118120
collector.getOrThrowException();
119121
}
120122

121123
Storage storage = GCPUtils.getStorage(config.connection.getProject(), credentials);
122124
String location = null;
123125
try {
124126
// Get location of the source for lineage
125-
location = storage.get(bucketName).getLocation();
127+
Bucket bucket = storage.get(bucketName);
128+
if (Objects.isNull(bucket)) {
129+
String errorReason = String.format("Unable to access GCS bucket '%s'.",
130+
bucketName);
131+
collector.addFailure(
132+
String.format("%s Ensure you entered the correct bucket path.", errorReason),
133+
null);
134+
collector.getOrThrowException();
135+
}
136+
location = bucket.getLocation();
126137
} catch (StorageException e) {
127138
String errorReason = String.format("Error code: %s, Unable to access GCS bucket '%s'. ",
128-
e.getCode(), bucketName);
139+
e.getCode(), bucketName);
129140
collector.addFailure(String.format("%s %s", errorReason, e.getMessage()),
130-
"Ensure you entered the correct bucket path and have permissions for it.")
131-
.withStacktrace(e.getStackTrace());
141+
"Ensure you entered the correct bucket path and have permissions for it.")
142+
.withStacktrace(e.getStackTrace());
132143
collector.getOrThrowException();
133144
}
134145

@@ -142,7 +153,7 @@ public void prepareRun(BatchSourceContext context) throws Exception {
142153

143154
// set error details provider
144155
context.setErrorDetailsProvider(
145-
new ErrorDetailsProviderSpec(GCSErrorDetailsProvider.class.getName()));
156+
new ErrorDetailsProviderSpec(GCSErrorDetailsProvider.class.getName()));
146157

147158
// super is called down here to avoid instantiating the lineage recorder with a null asset
148159
super.prepareRun(context);
@@ -151,12 +162,12 @@ public void prepareRun(BatchSourceContext context) throws Exception {
151162
@Override
152163
protected Map<String, String> getFileSystemProperties(BatchSourceContext context) {
153164
Map<String, String> properties = GCPUtils.getFileSystemProperties(config.connection, config.getPath(),
154-
new HashMap<>(config.getFileSystemProperties()));
165+
new HashMap<>(config.getFileSystemProperties()));
155166
if (config.isCopyHeader()) {
156167
properties.put(PathTrackingInputFormat.COPY_HEADER, Boolean.TRUE.toString());
157168
}
158169
if (config.getFileEncoding() != null
159-
&& !config.getFileEncoding().equalsIgnoreCase(AbstractFileSourceConfig.DEFAULT_FILE_ENCODING)) {
170+
&& !config.getFileEncoding().equalsIgnoreCase(AbstractFileSourceConfig.DEFAULT_FILE_ENCODING)) {
160171
properties.put(PathTrackingInputFormat.SOURCE_FILE_ENCODING, config.getFileEncoding());
161172
}
162173
if (config.getMinSplitSize() != null) {
@@ -179,17 +190,17 @@ protected LineageRecorder getLineageRecorder(BatchSourceContext context) {
179190
@Override
180191
protected void recordLineage(LineageRecorder lineageRecorder, List<String> outputFields) {
181192
lineageRecorder.recordRead("Read", String.format("Read %s from Google Cloud Storage.",
182-
config.isEncrypted() ? " and decrypt " : " "), outputFields);
193+
config.isEncrypted() ? " and decrypt " : " "), outputFields);
183194
}
184195

185196
@Override
186197
protected boolean shouldGetSchema() {
187198
return !config.containsMacro(GCPConnectorConfig.NAME_PROJECT) &&
188-
!config.containsMacro(GCSSourceConfig.NAME_PATH) && !config.containsMacro(GCSSourceConfig.NAME_FORMAT) &&
189-
!config.containsMacro(GCSSourceConfig.NAME_DELIMITER) &&
190-
!config.containsMacro(GCSSourceConfig.NAME_FILE_SYSTEM_PROPERTIES) &&
191-
!config.containsMacro(GCPConnectorConfig.NAME_SERVICE_ACCOUNT_FILE_PATH) &&
192-
!config.containsMacro(GCPConnectorConfig.NAME_SERVICE_ACCOUNT_JSON);
199+
!config.containsMacro(GCSSourceConfig.NAME_PATH) && !config.containsMacro(GCSSourceConfig.NAME_FORMAT) &&
200+
!config.containsMacro(GCSSourceConfig.NAME_DELIMITER) &&
201+
!config.containsMacro(GCSSourceConfig.NAME_FILE_SYSTEM_PROPERTIES) &&
202+
!config.containsMacro(GCPConnectorConfig.NAME_SERVICE_ACCOUNT_FILE_PATH) &&
203+
!config.containsMacro(GCPConnectorConfig.NAME_SERVICE_ACCOUNT_JSON);
193204
}
194205

195206
/**
@@ -225,19 +236,19 @@ public static class GCSSourceConfig extends AbstractFileSourceConfig implements
225236
@Macro
226237
@Nullable
227238
@Description("Whether the data file is encrypted. If it is set to 'true', a associated metadata file needs to be "
228-
+ "provided for each data file. Please refer to the Documentation for the details of the metadata file content.")
239+
+ "provided for each data file. Please refer to the Documentation for the details of the metadata file content.")
229240
private Boolean encrypted;
230241

231242
@Macro
232243
@Nullable
233244
@Description("The file name suffix for the metadata file of the encrypted data file. "
234-
+ "The default is '" + DEFAULT_ENCRYPTED_METADATA_SUFFIX + "'.")
245+
+ "The default is '" + DEFAULT_ENCRYPTED_METADATA_SUFFIX + "'.")
235246
private String encryptedMetadataSuffix;
236247

237248
@Macro
238249
@Nullable
239250
@Description("A list of columns with the corresponding data types for whom the automatic data type detection gets" +
240-
" skipped.")
251+
" skipped.")
241252
private String override;
242253

243254
@Macro
@@ -270,23 +281,23 @@ public void validate(FailureCollector collector) {
270281
GCSPath.from(path);
271282
} catch (IllegalArgumentException e) {
272283
collector.addFailure(e.getMessage(), null).withConfigProperty(NAME_PATH)
273-
.withStacktrace(e.getStackTrace());
284+
.withStacktrace(e.getStackTrace());
274285
}
275286
}
276287
if (!containsMacro(NAME_FILE_SYSTEM_PROPERTIES)) {
277288
try {
278289
getFileSystemProperties();
279290
} catch (Exception e) {
280291
collector.addFailure("File system properties must be a valid json.", null)
281-
.withConfigProperty(NAME_FILE_SYSTEM_PROPERTIES).withStacktrace(e.getStackTrace());
292+
.withConfigProperty(NAME_FILE_SYSTEM_PROPERTIES).withStacktrace(e.getStackTrace());
282293
}
283294
}
284295
if (!containsMacro(NAME_FILE_REGEX)) {
285296
try {
286297
getFilePattern();
287298
} catch (IllegalArgumentException e) {
288299
collector.addFailure(e.getMessage(), null).withConfigProperty(NAME_FILE_REGEX)
289-
.withStacktrace(e.getStackTrace());
300+
.withStacktrace(e.getStackTrace());
290301
}
291302
}
292303
}
@@ -320,7 +331,7 @@ public boolean isEncrypted() {
320331

321332
public String getEncryptedMetadataSuffix() {
322333
return Strings.isNullOrEmpty(encryptedMetadataSuffix) ?
323-
DEFAULT_ENCRYPTED_METADATA_SUFFIX : encryptedMetadataSuffix;
334+
DEFAULT_ENCRYPTED_METADATA_SUFFIX : encryptedMetadataSuffix;
324335
}
325336

326337
Map<String, String> getFileSystemProperties() {
@@ -330,4 +341,4 @@ Map<String, String> getFileSystemProperties() {
330341
return GSON.fromJson(fileSystemProperties, MAP_STRING_STRING_TYPE);
331342
}
332343
}
333-
}
344+
}

0 commit comments

Comments
 (0)