Skip to content

Commit c3dff01

Browse files
MONGOCRYPT-768 refactor to support multiple schemas (#953)
* add `mc_schema_broker_t` To manage schemas for an auto encryption operation. Supports more than one schema. * improve test runner ** support wildcard test selector ** add `TEST_FILE_AS_BSON` ** add `TMP_BSONF` utility * add missing `name` to collinfo results The schema broker requires the name to identify the collection in the result. The server replies with this field, but some mock data did not include it. * test create does not cache empty schema Catches a regression found when adding the schema broker --------- Co-authored-by: Ezra Chung <[email protected]>
1 parent dd4e1b6 commit c3dff01

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2924
-632
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ set (MONGOCRYPT_SOURCES
120120
src/mc-range-encoding.c
121121
src/mc-rangeopts.c
122122
src/mc-reader.c
123+
src/mc-schema-broker.c
123124
src/mc-str-encode-string-sets.c
124125
src/mc-text-search-str-encode.c
125126
src/mc-tokens.c
@@ -481,6 +482,7 @@ set (TEST_MONGOCRYPT_SOURCES
481482
test/test-mc-rangeopts.c
482483
test/test-mc-reader.c
483484
test/test-mc-text-search-str-encode.c
485+
test/test-mc-schema-broker.c
484486
test/test-mc-tokens.c
485487
test/test-mc-range-encoding.c
486488
test/test-mc-writer.c

src/mc-schema-broker-private.h

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright 2018-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef MC_SCHEMA_BROKER_PRIVATE_H
18+
#define MC_SCHEMA_BROKER_PRIVATE_H
19+
20+
#include "mc-efc-private.h" // mc_EncryptedFieldConfig_t
21+
#include "mongocrypt-cache-collinfo-private.h"
22+
#include "mongocrypt.h"
23+
#include <bson/bson.h>
24+
25+
// mc_schema_broker_t manages schemas for an auto encryption operation.
26+
//
27+
// A schema is either:
28+
// - a JSON Schema for CSFLE operations, or
29+
// - an encryptedFields document for QE operations.
30+
//
31+
typedef struct mc_schema_broker_t mc_schema_broker_t;
32+
33+
mc_schema_broker_t *mc_schema_broker_new(void);
34+
35+
void mc_schema_broker_destroy(mc_schema_broker_t *sb);
36+
37+
// mc_schema_broker_use_rangev2 enables rangev2 behavior. TODO(MONGOCRYPT-711) remove once rangev1 code is removed.
38+
void mc_schema_broker_use_rangev2(mc_schema_broker_t *sb);
39+
40+
// mc_schema_broker_request requests a schema for a collection. Ignores duplicates.
41+
// Returns error if two requests have different databases (not-yet supported).
42+
bool mc_schema_broker_request(mc_schema_broker_t *sb, const char *db, const char *coll, mongocrypt_status_t *status);
43+
44+
// mc_schema_broker_append_listCollections_filter appends a filter to use with the listCollections command.
45+
// Example: { "name": { "$in": [ "coll1", "coll2" ] } }
46+
// The filter matches all not-yet-satisfied collections.
47+
bool mc_schema_broker_append_listCollections_filter(const mc_schema_broker_t *sb,
48+
bson_t *out,
49+
mongocrypt_status_t *status);
50+
51+
// mc_schema_broker_satisfy_from_collinfo satisfies a schema request with a result from listCollections.
52+
// The result is cached.
53+
bool mc_schema_broker_satisfy_from_collinfo(mc_schema_broker_t *sb,
54+
const bson_t *collinfo,
55+
_mongocrypt_cache_t *collinfo_cache,
56+
mongocrypt_status_t *status);
57+
58+
// mc_schema_broker_satisfy_from_schemaMap tries to satisfy schema requests with a schemaMap.
59+
bool mc_schema_broker_satisfy_from_schemaMap(mc_schema_broker_t *sb,
60+
const bson_t *schema_map,
61+
mongocrypt_status_t *status);
62+
63+
// mc_schema_broker_satisfy_from_encryptedFieldsMap tries to satisfy schema requests with an encryptedFieldsMap.
64+
bool mc_schema_broker_satisfy_from_encryptedFieldsMap(mc_schema_broker_t *sb,
65+
const bson_t *ef_map,
66+
mongocrypt_status_t *status);
67+
68+
// mc_schema_broker_satisfy_from_cache tries to satisfy schema requests with the cache of listCollections results.
69+
bool mc_schema_broker_satisfy_from_cache(mc_schema_broker_t *sb,
70+
_mongocrypt_cache_t *collinfo_cache,
71+
mongocrypt_status_t *status);
72+
73+
// mc_schema_broker_satisfy_from_create_or_collMod tries to satisfy a schema request by inspecting the outgoing
74+
// create/collMod commands.
75+
bool mc_schema_broker_satisfy_from_create_or_collMod(mc_schema_broker_t *sb,
76+
const bson_t *cmd,
77+
mongocrypt_status_t *status);
78+
79+
// mc_schema_broker_satisfy_remaining_from_empty_schemas is called when a driver signals all listCollection results
80+
// have been fed. Assumes remaining collections have no schema. If collinfo_cache is passed, the empty result is cached.
81+
bool mc_schema_broker_satisfy_remaining_with_empty_schemas(mc_schema_broker_t *sb,
82+
_mongocrypt_cache_t *collinfo_cache /* may be NULL */,
83+
mongocrypt_status_t *status);
84+
85+
// mc_schema_broker_has_any_qe_schemas returns true if any collection has encryptedFields.
86+
//
87+
// Aborts if any unsatisfied schema requests. `mc_schema_broker_need_more_schemas(sb)` must be false.
88+
//
89+
bool mc_schema_broker_has_any_qe_schemas(const mc_schema_broker_t *sb);
90+
91+
// mc_schema_broker_need_more_schemas returns true if there are unsatisfied schema requests.
92+
bool mc_schema_broker_need_more_schemas(const mc_schema_broker_t *sb);
93+
94+
// mc_schema_broker_get_encryptedFields returns encryptedFields for a collection.
95+
//
96+
// Returns NULL and sets error if `coll` is not found or has no encryptedFields.
97+
//
98+
// Aborts if any unsatisfied schema requests. `mc_schema_broker_need_more_schemas(sb)` must be false.
99+
//
100+
const mc_EncryptedFieldConfig_t *
101+
mc_schema_broker_get_encryptedFields(const mc_schema_broker_t *sb, const char *coll, mongocrypt_status_t *status);
102+
103+
typedef enum {
104+
MC_CMD_SCHEMAS_FOR_CRYPT_SHARED, // target the crypt_shared library.
105+
MC_CMD_SCHEMAS_FOR_MONGOCRYPTD, // target mongocryptd process.
106+
MC_CMD_SCHEMAS_FOR_SERVER // target the server (mongod/mongos).
107+
} mc_cmd_target_t;
108+
109+
// mc_schema_broker_add_schemas_to_cmd adds schema information to a command.
110+
//
111+
// Aborts if any unsatisfied schema requests. `mc_schema_broker_need_more_schemas(sb)` must be false.
112+
//
113+
// Schemas are added with the fields:
114+
// - jsonSchema: for CSFLE with one schema.
115+
// - csfleEncryptionSchemas: for CSFLE with multiple schemas.
116+
// - encryptionInformation: for QE.
117+
//
118+
// Set cmd_target to the intended command destination. This impacts if/how schema information is added.
119+
bool mc_schema_broker_add_schemas_to_cmd(const mc_schema_broker_t *sb,
120+
bson_t *cmd /* in and out */,
121+
mc_cmd_target_t cmd_target,
122+
mongocrypt_status_t *status);
123+
#endif // MC_SCHEMA_BROKER_PRIVATE_H

0 commit comments

Comments
 (0)