Skip to content

Commit 468aa4e

Browse files
authored
Add docs about withQueryFn, logic to detect other functions, and new … (#34127)
* Add docs about withQueryFn, logic to detect other functions, and new FindQueryTest class * switch check logic to expand phase and update test and update doc links * remove exception thrown in split method * revert line change to split * change out exception thrown * fix spotless java failures
1 parent a994291 commit 468aa4e

File tree

3 files changed

+141
-1
lines changed

3 files changed

+141
-1
lines changed

sdks/java/io/mongodb/src/main/java/org/apache/beam/sdk/io/mongodb/MongoDbIO.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.mongodb.client.model.UpdateOptions;
4040
import com.mongodb.client.model.WriteModel;
4141
import java.util.ArrayList;
42+
import java.util.Arrays;
4243
import java.util.Collections;
4344
import java.util.HashMap;
4445
import java.util.List;
@@ -141,6 +142,11 @@ public class MongoDbIO {
141142

142143
private static final Logger LOG = LoggerFactory.getLogger(MongoDbIO.class);
143144

145+
public static final String ERROR_MSG_QUERY_FN =
146+
" class is not supported. "
147+
+ "Please provide one of the predefined classes in the MongoDbIO package "
148+
+ "such as FindQuery or AggregationQuery.";
149+
144150
/** Read data from MongoDB. */
145151
public static Read read() {
146152
return new AutoValue_MongoDbIO_Read.Builder()
@@ -312,9 +318,16 @@ public Read withBucketAuto(boolean bucketAuto) {
312318
return builder().setBucketAuto(bucketAuto).build();
313319
}
314320

315-
/** Sets a queryFn. */
321+
/**
322+
* Sets a queryFn. The provided queryFn must be one of the predefined classes in the MongoDbIO
323+
* package such as {@link FindQuery#FindQuery} or {@link AggregationQuery#AggregationQuery}.
324+
*/
316325
public Read withQueryFn(
317326
SerializableFunction<MongoCollection<Document>, MongoCursor<Document>> queryBuilderFn) {
327+
checkArgument(
328+
Arrays.asList(AutoValue_FindQuery.class, AutoValue_AggregationQuery.class)
329+
.contains(queryBuilderFn.getClass()),
330+
String.format("[%s]" + ERROR_MSG_QUERY_FN, queryBuilderFn.getClass().getName()));
318331
return builder().setQueryFn(queryBuilderFn).build();
319332
}
320333

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.beam.sdk.io.mongodb;
19+
20+
import static org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.base.Preconditions.checkArgument;
21+
22+
import com.google.auto.value.AutoValue;
23+
import com.mongodb.BasicDBObject;
24+
import com.mongodb.MongoClient;
25+
import com.mongodb.client.MongoCollection;
26+
import com.mongodb.client.MongoCursor;
27+
import com.mongodb.client.model.Projections;
28+
import java.util.Collections;
29+
import java.util.List;
30+
import org.apache.beam.sdk.transforms.SerializableFunction;
31+
import org.bson.BsonDocument;
32+
import org.bson.Document;
33+
import org.bson.conversions.Bson;
34+
import org.checkerframework.checker.nullness.qual.Nullable;
35+
import org.checkerframework.dataflow.qual.Pure;
36+
37+
/** Builds a MongoDB FindQueryTest object. */
38+
@AutoValue
39+
public abstract class FindQueryTest
40+
implements SerializableFunction<MongoCollection<Document>, MongoCursor<Document>> {
41+
42+
@Pure
43+
abstract @Nullable BsonDocument filters();
44+
45+
@Pure
46+
abstract int limit();
47+
48+
@Pure
49+
abstract List<String> projection();
50+
51+
private static Builder builder() {
52+
return new AutoValue_FindQueryTest.Builder()
53+
.setLimit(0)
54+
.setProjection(Collections.emptyList())
55+
.setFilters(new BsonDocument());
56+
}
57+
58+
abstract Builder toBuilder();
59+
60+
public static FindQueryTest create() {
61+
return builder().build();
62+
}
63+
64+
@AutoValue.Builder
65+
abstract static class Builder {
66+
abstract Builder setFilters(@Nullable BsonDocument filters);
67+
68+
abstract Builder setLimit(int limit);
69+
70+
abstract Builder setProjection(List<String> projection);
71+
72+
abstract FindQueryTest build();
73+
}
74+
75+
/** Sets the filters to find. */
76+
private FindQueryTest withFilters(BsonDocument filters) {
77+
return toBuilder().setFilters(filters).build();
78+
}
79+
80+
/** Convert the Bson filters into a BsonDocument via default encoding. */
81+
static BsonDocument bson2BsonDocument(Bson filters) {
82+
return filters.toBsonDocument(BasicDBObject.class, MongoClient.getDefaultCodecRegistry());
83+
}
84+
85+
/** Sets the filters to find. */
86+
public FindQueryTest withFilters(Bson filters) {
87+
return withFilters(bson2BsonDocument(filters));
88+
}
89+
90+
/** Sets the limit of documents to find. */
91+
public FindQueryTest withLimit(int limit) {
92+
return toBuilder().setLimit(limit).build();
93+
}
94+
95+
/** Sets the projection. */
96+
public FindQueryTest withProjection(List<String> projection) {
97+
checkArgument(projection != null, "projection can not be null");
98+
return toBuilder().setProjection(projection).build();
99+
}
100+
101+
@Override
102+
public MongoCursor<Document> apply(MongoCollection<Document> collection) {
103+
return collection
104+
.find()
105+
.filter(filters())
106+
.limit(limit())
107+
.projection(Projections.include(projection()))
108+
.iterator();
109+
}
110+
}

sdks/java/io/mongodb/src/test/java/org/apache/beam/sdk/io/mongodb/MongoDbIOTest.java

+17
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.junit.ClassRule;
5858
import org.junit.Rule;
5959
import org.junit.Test;
60+
import org.junit.rules.ExpectedException;
6061
import org.junit.rules.TemporaryFolder;
6162
import org.junit.runner.RunWith;
6263
import org.junit.runners.JUnit4;
@@ -83,6 +84,8 @@ public class MongoDbIOTest {
8384

8485
@Rule public final TestPipeline pipeline = TestPipeline.create();
8586

87+
@Rule public transient ExpectedException thrown = ExpectedException.none();
88+
8689
@BeforeClass
8790
public static void beforeClass() throws Exception {
8891
port = NetworkTestHelper.getAvailableLocalPort();
@@ -422,6 +425,20 @@ public void testUpdate() {
422425
assertEquals("India", out.get("country"));
423426
}
424427

428+
@Test
429+
public void testUnknownQueryFnClass() throws IllegalArgumentException {
430+
thrown.expect(IllegalArgumentException.class);
431+
thrown.expectMessage(
432+
"[org.apache.beam.sdk.io.mongodb.AutoValue_FindQueryTest]" + MongoDbIO.ERROR_MSG_QUERY_FN);
433+
434+
pipeline.apply(
435+
MongoDbIO.read()
436+
.withUri("mongodb://localhost:" + port)
437+
.withDatabase(DATABASE_NAME)
438+
.withCollection(COLLECTION_NAME)
439+
.withQueryFn(FindQueryTest.create().withFilters(Filters.eq("scientist", "Einstein"))));
440+
}
441+
425442
private static List<Document> createDocuments(final int n, boolean addId) {
426443
final String[] scientists =
427444
new String[] {

0 commit comments

Comments
 (0)