This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new b9266cee86f0 CAMEL-24348: camel-google-bigquery - report unusable
bodies and missing jobs properly
b9266cee86f0 is described below
commit b9266cee86f0de4be08bfcf10f9e826309b11492
Author: Andrea Cosentino <[email protected]>
AuthorDate: Wed Aug 12 07:15:36 2026 +0200
CAMEL-24348: camel-google-bigquery - report unusable bodies and missing
jobs properly
Fix NullPointerException when the message body is null in
GoogleBigQueryProducer,
and when getJob/waitFor returns null for an expired or unknown job in
GoogleBigQuerySQLProducer. Replace raw Exception throws with
RuntimeCamelException
so routes receive a proper Camel exception type.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
.../google/bigquery/GoogleBigQueryProducer.java | 8 +++-
.../bigquery/sql/GoogleBigQuerySQLProducer.java | 15 +++++--
.../unit/GoogleBigQueryProducerBodyTypeTest.java | 48 ++++++++++++++++++++++
3 files changed, 66 insertions(+), 5 deletions(-)
diff --git
a/components/camel-google/camel-google-bigquery/src/main/java/org/apache/camel/component/google/bigquery/GoogleBigQueryProducer.java
b/components/camel-google/camel-google-bigquery/src/main/java/org/apache/camel/component/google/bigquery/GoogleBigQueryProducer.java
index 4693d7c920c3..6a80d9848944 100644
---
a/components/camel-google/camel-google-bigquery/src/main/java/org/apache/camel/component/google/bigquery/GoogleBigQueryProducer.java
+++
b/components/camel-google/camel-google-bigquery/src/main/java/org/apache/camel/component/google/bigquery/GoogleBigQueryProducer.java
@@ -26,6 +26,7 @@ import com.google.cloud.bigquery.InsertAllRequest;
import com.google.cloud.bigquery.InsertAllResponse;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePropertyKey;
+import org.apache.camel.RuntimeCamelException;
import org.apache.camel.support.DefaultProducer;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
@@ -129,13 +130,16 @@ public class GoogleBigQueryProducer extends
DefaultProducer {
for (Exchange ex : exchanges) {
Object entryObject = ex.getIn().getBody();
if (entryObject instanceof List) {
+ // the insert id header identifies one row, so it is not
applied to the rows of a list: BigQuery
+ // would treat them as duplicates of each other and keep only
one. Use useAsInsertId for those
for (Map<String, Object> entry : (List<Map<String, Object>>)
entryObject) {
apiRequestRows.add(createRowRequest(null, entry));
}
} else if (entryObject instanceof Map) {
apiRequestRows.add(createRowRequest(ex, (Map<String, Object>)
entryObject));
} else {
- ex.setException(new IllegalArgumentException("Cannot handle
body type " + entryObject.getClass()));
+ ex.setException(new IllegalArgumentException(
+ "Cannot handle body type " + (entryObject == null ?
"null" : entryObject.getClass().getName())));
}
}
@@ -160,7 +164,7 @@ public class GoogleBigQueryProducer extends DefaultProducer
{
InsertAllResponse apiResponse = bigquery.insertAll(insertAllRequest);
if (apiResponse.getInsertErrors() != null &&
!apiResponse.getInsertErrors().isEmpty()) {
- throw new Exception("InsertAll into " + tableId + " failed: " +
apiResponse.getInsertErrors());
+ throw new RuntimeCamelException("InsertAll into " + tableId + "
failed: " + apiResponse.getInsertErrors());
}
if (LOG.isTraceEnabled()) {
diff --git
a/components/camel-google/camel-google-bigquery/src/main/java/org/apache/camel/component/google/bigquery/sql/GoogleBigQuerySQLProducer.java
b/components/camel-google/camel-google-bigquery/src/main/java/org/apache/camel/component/google/bigquery/sql/GoogleBigQuerySQLProducer.java
index f8589defc9ef..c17dada760a6 100644
---
a/components/camel-google/camel-google-bigquery/src/main/java/org/apache/camel/component/google/bigquery/sql/GoogleBigQuerySQLProducer.java
+++
b/components/camel-google/camel-google-bigquery/src/main/java/org/apache/camel/component/google/bigquery/sql/GoogleBigQuerySQLProducer.java
@@ -37,6 +37,7 @@ import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.TableResult;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
+import org.apache.camel.RuntimeCamelException;
import org.apache.camel.RuntimeExchangeException;
import org.apache.camel.component.google.bigquery.GoogleBigQueryConstants;
import org.apache.camel.support.DefaultProducer;
@@ -157,10 +158,18 @@ public class GoogleBigQuerySQLProducer extends
DefaultProducer {
var job = ObjectHelper.isNotEmpty(jobId)
? bigquery.getJob(jobId)
: bigquery.create(getJobInfo(queryJobConfiguration));
+ if (job == null) {
+ throw new RuntimeCamelException("BigQuery job " + jobId + "
does not exist");
+ }
- return job.waitFor();
+ Job completed = job.waitFor();
+ if (completed == null) {
+ // waitFor returns null when the job does not exist any more,
for example when it expired
+ throw new RuntimeCamelException("BigQuery job " +
job.getJobId() + " is no longer available");
+ }
+ return completed;
} catch (BigQueryException e) {
- throw new Exception("Query " + translatedQuery + " failed: " +
e.getError(), e);
+ throw new RuntimeCamelException("Query " + translatedQuery + "
failed: " + e.getError(), e);
}
}
@@ -186,7 +195,7 @@ public class GoogleBigQuerySQLProducer extends
DefaultProducer {
QueryResultsOption[] queryResultsOptions =
getQueryResultsOptions(pageSize, pageToken);
return job.getQueryResults(queryResultsOptions);
} catch (BigQueryException e) {
- throw new Exception("Query " + translatedQuery + " failed: " +
e.getError(), e);
+ throw new RuntimeCamelException("Query " + translatedQuery + "
failed: " + e.getError(), e);
}
}
diff --git
a/components/camel-google/camel-google-bigquery/src/test/java/org/apache/camel/component/google/bigquery/unit/GoogleBigQueryProducerBodyTypeTest.java
b/components/camel-google/camel-google-bigquery/src/test/java/org/apache/camel/component/google/bigquery/unit/GoogleBigQueryProducerBodyTypeTest.java
new file mode 100644
index 000000000000..341b9954c6f1
--- /dev/null
+++
b/components/camel-google/camel-google-bigquery/src/test/java/org/apache/camel/component/google/bigquery/unit/GoogleBigQueryProducerBodyTypeTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.google.bigquery.unit;
+
+import org.apache.camel.Exchange;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Verifies what the producer reports for a body it cannot turn into rows.
+ */
+class GoogleBigQueryProducerBodyTypeTest extends BaseBigQueryTest {
+
+ @Test
+ void aBodyThatIsNotAMapOrAListIsReported() throws Exception {
+ Exchange exchange = createExchangeWithBody("not a row");
+ producer.process(exchange);
+
+ assertThat(exchange.getException())
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Cannot handle body type java.lang.String");
+ }
+
+ @Test
+ void aMissingBodyIsReportedInsteadOfFailingWithANullPointer() throws
Exception {
+ Exchange exchange = createExchangeWithBody(null);
+ producer.process(exchange);
+
+ assertThat(exchange.getException())
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Cannot handle body type null");
+ }
+}