├── .evg.yml ├── .github └── CODEOWNERS ├── .gitignore ├── LICENSE ├── README.md ├── RELEASE.md ├── build.gradle ├── demo ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── mongodb │ │ └── jdbc │ │ └── demo │ │ └── Main.java │ └── test │ └── java │ └── com │ └── mongodb │ └── jdbc │ └── utils │ ├── MongoSQLTestUtils.java │ ├── PrintUtils.java │ └── TestUtils.java ├── docs └── overview.md ├── evergreen └── make_docs.sh ├── gradle.properties ├── gradle ├── deploy.gradle ├── publish.gradle ├── publish.sh └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mongo-jdbc-downloads_template.json ├── resources ├── authentication_test │ └── X509 │ │ ├── ca.crt │ │ ├── client-encrypted.pem │ │ ├── client-unencrypted.pem │ │ ├── server.pem │ │ └── truststore.jks ├── integration_test │ ├── README.md │ ├── testdata │ │ ├── adf_db_config.json │ │ ├── dbmd_variable_result_set_data.yml │ │ └── integration.yml │ └── tests │ │ ├── dbmd_constant_result_sets.yml │ │ ├── dbmd_empty_result_sets.yml │ │ ├── dbmd_variable_result_sets_data_methods.yml │ │ ├── dbmd_variable_result_sets_function_methods.yml │ │ ├── dbmd_variable_result_sets_index_methods.yml │ │ └── query.yaml ├── license_header.txt ├── media │ └── MongoDBAtlasJDBC.png ├── release │ └── mongo_jdbc_compliance_report_template.md ├── run_adf.sh ├── start_local_mdb.sh ├── tdvt_test │ ├── calcs.yml │ ├── logical_calcs.yml │ └── logical_staples.yml └── third_party_header.txt ├── settings.gradle ├── smoketest ├── build.gradle └── src │ └── test │ └── java │ └── com │ └── mongodb │ └── jdbc │ └── smoketest │ └── SmokeTest.java └── src ├── integration-test └── java │ └── com │ └── mongodb │ └── jdbc │ └── integration │ ├── ADFIntegrationTest.java │ ├── AuthX509IntegrationTest.java │ ├── DCIntegrationTest.java │ └── testharness │ ├── DataLoader.java │ ├── IntegrationTestUtils.java │ ├── README.md │ ├── TestGenerator.java │ ├── TestTypeInfo.java │ └── models │ ├── TestData.java │ ├── TestDataEntry.java │ ├── TestEntry.java │ └── Tests.java ├── main ├── java │ └── com │ │ └── mongodb │ │ └── jdbc │ │ ├── BsonExplicitCursor.java │ │ ├── BsonTypeInfo.java │ │ ├── BuildInfo.java │ │ ├── DataLake.java │ │ ├── JsonSchema.java │ │ ├── MongoBsonValue.java │ │ ├── MongoColumnInfo.java │ │ ├── MongoConnection.java │ │ ├── MongoConnectionProperties.java │ │ ├── MongoDatabaseMetaData.java │ │ ├── MongoDriver.java │ │ ├── MongoFunctions.java │ │ ├── MongoJsonSchema.java │ │ ├── MongoJsonSchemaResult.java │ │ ├── MongoListTablesResult.java │ │ ├── MongoPreparedStatement.java │ │ ├── MongoResultSet.java │ │ ├── MongoResultSetMetaData.java │ │ ├── MongoRunCmdListTablesResult.java │ │ ├── MongoSerializationException.java │ │ ├── MongoStatement.java │ │ ├── MongoVersionedJsonSchema.java │ │ ├── NoCheckStateJsonWriter.java │ │ ├── Pair.java │ │ ├── SortableBsonDocument.java │ │ ├── logging │ │ ├── AutoLoggable.java │ │ ├── DisableAutoLogging.java │ │ ├── LoggingAspect.aj │ │ ├── MongoLogger.java │ │ ├── MongoSimpleFormatter.java │ │ └── QueryDiagnostics.java │ │ ├── mongosql │ │ ├── CheckDriverVersionResult.java │ │ ├── GetMongosqlTranslateVersionResult.java │ │ ├── GetNamespacesResult.java │ │ ├── MongoSQLException.java │ │ ├── MongoSQLTranslate.java │ │ └── TranslateResult.java │ │ ├── oidc │ │ ├── JdbcIdpInfo.java │ │ ├── JdbcOidcCallback.java │ │ ├── JdbcOidcCallbackContext.java │ │ ├── OidcAuthFlow.java │ │ ├── OidcResponse.java │ │ ├── OidcTimeoutException.java │ │ ├── RFC8252HttpServer.java │ │ └── manualtests │ │ │ ├── TestOidcAuthFlow.java │ │ │ ├── TestOidcAuthFlowAndRefresh.java │ │ │ ├── TestOidcCallback.java │ │ │ ├── TestOidcCallbackWithBadRefreshToken.java │ │ │ ├── TestOidcCallbackWithShortTimeout.java │ │ │ ├── TestOidcUtils.java │ │ │ └── TestRFC8252Server.java │ │ └── utils │ │ ├── BsonUtils.java │ │ ├── NativeLoader.java │ │ └── X509Authentication.java └── resources │ ├── META-INF │ └── services │ │ └── java.sql.Driver │ └── templates │ ├── OIDCAcceptedTemplate.html │ ├── OIDCErrorTemplate.html │ └── OIDCNotFoundTemplate.html └── test ├── java └── com │ └── mongodb │ └── jdbc │ ├── BsonTypeInfoTest.java │ ├── BsonUtilsTest.java │ ├── MongoConnectionTest.java │ ├── MongoDatabaseMetaDataTest.java │ ├── MongoDriverTest.java │ ├── MongoJsonSchemaTest.java │ ├── MongoMock.java │ ├── MongoResultSetMetaDataTest.java │ ├── MongoResultSetTest.java │ ├── MongoSQLTranslateLibTest.java │ ├── MongoStatementTest.java │ ├── TestConnectionString.java │ └── oidc │ └── RFC8252HttpServerTest.java └── resources ├── MongoSqlLibraryTest └── libmongosqltranslate.so └── mongoJsonSchemaTest ├── expectedOutput ├── bsonTypeAsSetAndAnyOfToMergeWith.json ├── bsonTypeAsSetOfOneElem.json ├── bsonTypeAsSetOfSimpleTypes.json ├── bsonTypeAsSingleType.json ├── flattenAnyOf.json ├── flattenedAnyOfReducedToOneType.json ├── polymorphicAdditionalProperties.json ├── polymorphicItems.json └── simpleSchema.json └── input ├── bsonTypeAsSetAndAnyOfToMergeWith.json ├── bsonTypeAsSetOfOneElem.json ├── bsonTypeAsSetOfSimpleTypes.json ├── bsonTypeAsSingleType.json ├── flattenAnyOf.json ├── flattenedAnyOfReducedToOneType.json ├── polymorphicAdditionalProperties.json ├── polymorphicItems.json └── simpleSchema.json /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # File: ./github/CODEOWNERS 2 | /**/* @mongodb/sql-engines-team 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | # Ignore Gradle build output directory 5 | build 6 | 7 | # Ignore debugging helpers 8 | demo/src/test/ 9 | 10 | # Ignore local ADF directory 11 | # Still retaining old "adl" name in gitignore for older setups 12 | local_adl 13 | local_adf 14 | 15 | # Ignore generated tests 16 | resources/generated_test 17 | 18 | # Ignore mongosqltranslate libraries 19 | src/main/resources/**/libmongosqltranslate.* 20 | src/main/resources/**/mongosqltranslate.* 21 | .library_cache/ 22 | 23 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Versioning 2 | 3 | ## Versioning 4 | 5 | Versions will follow the [semantic versioning](https://semver.org/) system. 6 | 7 | The following guidelines will be used to determine when each version component will be updated: 8 | - **major**: backwards-breaking changes 9 | - **minor**: functionality added in a backwards compatible manner 10 | - **patch**: backwards compatible bug fixes. 11 | - **pre-release**: The pre-release version, used for preview builds and when updating a preview version of `libmongosqltranslate` 12 | - **libv**: to specify which version of `libmongosqltranslate` gets bundled with the driver during a release 13 | - Our build system will fetch *exactly* the version of `libmongosqltranslate` specified after `libv` and bundle it with the driver. If you are unsure 14 | what version to use, check the [releases](https://jira.mongodb.org/projects/SQL?selectedItem=com.atlassian.jira.jira-projects-plugin:release-page&status=released&contains=libv) page and use the latest **released** tag. 15 | 16 | ### The following applies to non-eap releases 17 | 18 | Version number policy could be referred from here: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855 19 | 20 | Among all the version standards Maven supports, we will use MajorVersion, IncrementalVersion and Qualifier inside this project. 21 | 22 | ## Release Process 23 | 24 | ### Snapshot Versions 25 | 26 | Every successful untagged build in evergreen will release the artifacts to the Sonatype SNAPSHOT repo in https://oss.sonatype.org/#view-repositories;snapshots~browsestorage 27 | 28 | ### Release Versions 29 | 30 | Follow these instructions for creating a Release Version. 31 | 32 | ### Pre-Release Tasks 33 | 34 | #### Determine the correct version to be released 35 | 36 | Go to the [SQL releases page](https://jira.mongodb.org/projects/SQL?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&status=unreleased), and check the content of the tickets that are included in the current release. The fix version by default is a patch version. If there is a backwards incompatible API change in the tickets that are set to be released, we should instead update the major version; if there are new features added in the tickets set to be released, we should instead update the minor version. To do so, update the version on the [SQL releases page](https://jira.mongodb.org/projects/SQL?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&status=unreleased) under "Actions". This will update the fix version on all of the tickets as well. 37 | 38 | To determine which version of `libmongosqltranslate` to bundle, go to the [releases](https://jira.mongodb.org/projects/SQL?selectedItem=com.atlassian.jira.jira-projects-plugin:release-page&status=released&contains=libv) page 39 | and choose the latest **released** version. Add this fix version to the release ticket in JIRA. 40 | 41 | #### Start Release Ticket 42 | Move the JIRA ticket for the release to the "In Progress" state. 43 | Ensure that its fixVersion matches the version being released, and update it if it changed in the previous step. 44 | 45 | #### Ensure Evergreen Passing 46 | Ensure that the build you are releasing is passing the tests on the evergreen waterfall. 47 | 48 | #### Complete the Release in JIRA 49 | Go to the [SQL releases page](https://jira.mongodb.org/projects/SQL?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&status=unreleased), and ensure that all the tickets in the fixVersion to be released are closed. 50 | Ensure that all the tickets have the correct type. 51 | The only uncompleted ticket in the release should be the release ticket. 52 | If there are any remaining tickets that will not be included in this release, remove the fixVersion and assign them a new one if appropriate. 53 | Close the release on JIRA, adding the current date (you may need to ask the SQL project manager to do this). 54 | 55 | ### Release Tasks 56 | 57 | #### Ensure master up to date 58 | Ensure you have the `master` branch checked out, and that you have pulled the latest commit from `mongodb/mongo-jdbc-driver`. 59 | 60 | #### Create the tag and push 61 | 62 | The tag is formatted as follows: 63 | 64 | `..[-]-libv..[-]` 65 | 66 | To specify which version of [`libmongosqltranslate`](https://github.com/10gen/mongosql-rs) should be built with the release, the version 67 | of `libmongosqltranslate` must be annotated in the git tag with `libv`. This version was obtained previously when updating the release ticket. 68 | 69 | Create an annotated tag and push it (using the correct versions): 70 | 71 | ```sh 72 | # git tag -a -m X.Y.Z[--libvXX.YY.ZZ[-]] 73 | git tag -am 3.0.0-alpha-2-libv1.0.0-alpha-3 74 | git push --tags 75 | ``` 76 | 77 | This should trigger an Evergreen version that can be viewed on the [mongo-jdbc-driver waterfall](https://evergreen.mongodb.com/waterfall/mongo-jdbc-driver). 78 | If it does not, you may have to ask the project manager to give you the right permissions to do so. 79 | Make sure to run the 'release' task, if it is not run automatically. 80 | 81 | #### Set Evergreen Priorities 82 | Some evergreen variants may have a long schedule queue. 83 | To speed up release tasks, you can set the task priority for any variant to 101 for release candidates and 200 for actual releases. 84 | If you do not have permissions to set priority above 100, ask the project manager to set the 85 | priority. 86 | 87 | ### Post-Release Tasks 88 | 89 | #### Wait for evergreen 90 | Wait for the evergreen version to finish, and ensure that the release task completes successfully. 91 | 92 | #### Verify release artifacts (ignore for EAP) 93 | Check that the version just released is available in the [Sonatype Nexus Repo Manager](https://oss.sonatype.org/#nexus-search;quick~mongodb-jdbc). 94 | The release artifacts should appear on [Maven Central](https://search.maven.org/search?q=g:org.mongodb%20AND%20a:mongodb-jdbc) after a while. 95 | 96 | #### Notify the Web team about the new release (ignore for EAP) 97 | Create a ticket through the [service desk](https://jira.mongodb.org/plugins/servlet/desk/portal/61/create/926) and request the link for the `Download from Maven` button on the Download Center page `https://www.mongodb.com/try/download/jdbc-driver` to be updated. 98 | You can find the new link in the [json feed](https://translators-connectors-releases.s3.amazonaws.com/mongo-jdbc-driver/mongo-jdbc-downloads.json) under `versions[0].download_link`. Include this link in your ticket. 99 | 100 | #### Close Release Ticket 101 | Move the JIRA ticket tracking this release to the "Closed" state. 102 | 103 | #### Ensure next release ticket and fixVersion created 104 | Ensure that a JIRA ticket tracking the next release has been created 105 | and is assigned the appropriate fixVersion. 106 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'application' 3 | } 4 | 5 | application { 6 | mainClassName = 'com.mongodb.jdbc.demo.Main' 7 | } 8 | 9 | dependencies { 10 | 11 | implementation 'org.junit.jupiter:junit-jupiter:5.7.0' 12 | compile rootProject 13 | } 14 | 15 | test { 16 | exclude 'com/mongodb/jdbc/utils/**' 17 | } -------------------------------------------------------------------------------- /demo/src/main/java/com/mongodb/jdbc/demo/Main.java: -------------------------------------------------------------------------------- 1 | package com.mongodb.jdbc.demo; 2 | 3 | import java.sql.*; 4 | import java.util.TimeZone; 5 | import java.util.Calendar; 6 | import java.util.GregorianCalendar; 7 | 8 | public class Main { 9 | // JDBC driver name and database URL 10 | static final String JDBC_DRIVER = "com.mongodb.jdbc.MongoDriver"; 11 | static final String URL = "jdbc:mongodb://mhuser:pencil@localhost:27017/admin"; 12 | private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); 13 | 14 | // Data used for test, in the test.test and test2.test collections: 15 | // 16 | //{ "values" : [ 17 | // { "database" : "myDB", "table" : "foo", "tableAlias" : "foo", "column" : "a", "columnAlias" : "a", "value" : 1 }, 18 | // { "database" : "myDB", "table" : "foo", "tableAlias" : "foo", "column" : "b", "columnAlias" : "b", "value" : "hello" } ] 19 | // } 20 | //{ "values" : [ 21 | // { "database" : "myDB", "table" : "foo", "tableAlias" : "foo", "column" : "a", "columnAlias" : "a", "value" : 42 }, 22 | // { "database" : "myDB", "table" : "foo", "tableAlias" : "foo", "column" : "b", "columnAlias" : "b", "value" : "hello 2" } ] 23 | // } 24 | // 25 | public static void main(String[] args) { 26 | 27 | try{ 28 | java.util.Properties p = new java.util.Properties(); 29 | // These properties will be added to the URI. 30 | // Uncomment if you wish to specify user and password. 31 | // p.setProperty("user", "user"); 32 | // p.setProperty("password", "foo"); 33 | p.setProperty("database", "test"); 34 | System.out.println("Connecting to database test..."); 35 | Connection conn = DriverManager.getConnection(URL, p); 36 | 37 | DatabaseMetaData dbmd = conn.getMetaData(); 38 | System.out.println(dbmd.getDriverVersion()); 39 | System.out.println(dbmd.getDriverMajorVersion()); 40 | System.out.println(dbmd.getDriverMinorVersion()); 41 | // System.out.println("Creating statement..."); 42 | // Statement stmt = conn.createStatement(); 43 | // ResultSet rs = stmt.executeQuery("select * from foo"); 44 | // System.out.println("++++++ Showing contents for test.foo ++++++++"); 45 | // displayResultSet(rs); 46 | } catch (Exception e) { 47 | throw new RuntimeException(e); 48 | } 49 | } 50 | 51 | public static void displayResultSet(ResultSet rs) throws java.sql.SQLException { 52 | Calendar c = new GregorianCalendar(); 53 | c.setTimeZone(UTC); 54 | while(rs.next()){ 55 | //Retrieve by column name 56 | double a = rs.getDouble("a"); 57 | String as = rs.getString("a"); 58 | String b = rs.getString("b"); 59 | java.sql.Timestamp bd; 60 | try { 61 | bd = rs.getTimestamp("b", c); 62 | System.out.println("b as a Timestamp is: " + bd); 63 | } catch (SQLException e) { 64 | System.out.println(e); 65 | } catch (Exception e) { 66 | throw new RuntimeException(e); 67 | } 68 | ResultSetMetaData metaData = rs.getMetaData(); 69 | System.out.println("a is: " + a + " as double" 70 | + " b is: " + b + " as string"); 71 | System.out.println("a as a string is: " + as); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /demo/src/test/java/com/mongodb/jdbc/utils/MongoSQLTestUtils.java: -------------------------------------------------------------------------------- 1 | package com.mongodb.jdbc.utils; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.Statement; 6 | 7 | public class MongoSQLTestUtils extends TestUtils { 8 | static final String URL = "jdbc:mongodb://localhost"; 9 | public static final String TEST_DB = "integration_test"; 10 | public static final String DEFAULT_TEST_COLLECTION = "test_collection"; 11 | 12 | @Override 13 | protected Connection connect() throws Exception { 14 | // Connects to local ADF instance 15 | java.util.Properties p = new java.util.Properties(); 16 | p.setProperty("user", System.getenv("ADF_TEST_LOCAL_USER")); 17 | p.setProperty("password", System.getenv("ADF_TEST_LOCAL_PWD")); 18 | p.setProperty("authSource", System.getenv("ADF_TEST_LOCAL_AUTH_DB")); 19 | p.setProperty("database", TEST_DB); 20 | p.setProperty("ssl", "false"); 21 | Connection conn = DriverManager.getConnection(URL, p); 22 | try { 23 | Statement stmt = conn.createStatement(); 24 | stmt.executeQuery("select 1 from " + DEFAULT_TEST_COLLECTION); 25 | } catch (Exception e) { 26 | e.printStackTrace(); 27 | throw e; 28 | } 29 | 30 | return conn; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /demo/src/test/java/com/mongodb/jdbc/utils/PrintUtils.java: -------------------------------------------------------------------------------- 1 | package com.mongodb.jdbc.utils; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.ResultSetMetaData; 5 | import java.sql.SQLException; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public class PrintUtils { 11 | private static final String NULL_STR = "null"; 12 | private static int MAX_RS_META_COL_WIDTH = 12; 13 | public static int MAX_COL_WIDTH = 20; 14 | 15 | public static void printResultSetMetadata(ResultSetMetaData rsMeta) throws SQLException { 16 | try { 17 | int columnCount = rsMeta.getColumnCount(); 18 | StringBuilder sb = new StringBuilder(); 19 | List colNames = new ArrayList(); 20 | colNames.add("TABLE_CAT"); 21 | colNames.add("TABLE_SCHEMA"); 22 | colNames.add("TABLE_NAME"); 23 | colNames.add("COLUMN_NAME"); 24 | colNames.add("DATA_TYPE"); 25 | colNames.add("TYPE_NAME"); 26 | colNames.add("DISPLAY_SIZE"); 27 | colNames.add("PRECISION"); 28 | colNames.add("SCALE"); 29 | colNames.add("CLASS_NAME"); 30 | colNames.add("LABEL"); 31 | 32 | printRowSeparator(sb, colNames.size(), MAX_RS_META_COL_WIDTH); 33 | for (int i = 0; i < colNames.size(); i++) { 34 | sb.append(String.format(getFormat(MAX_RS_META_COL_WIDTH), colNames.get(i))); 35 | } 36 | sb.append("|\n"); 37 | printRowSeparator(sb, colNames.size(), MAX_RS_META_COL_WIDTH); 38 | 39 | for (int i = 1; i <= columnCount; i++) { 40 | boolean hasMoreData = true; 41 | String[] row = new String[11]; 42 | row[0] = rsMeta.getCatalogName(i); 43 | row[1] = rsMeta.getSchemaName(i); 44 | row[2] = rsMeta.getTableName(i); 45 | row[3] = rsMeta.getColumnName(i); 46 | row[4] = String.valueOf(rsMeta.getColumnType(i)); 47 | row[5] = rsMeta.getColumnTypeName(i); 48 | row[6] = String.valueOf(rsMeta.getColumnDisplaySize(i)); 49 | row[7] = String.valueOf(rsMeta.getPrecision(i)); 50 | row[8] = String.valueOf(rsMeta.getScale(i)); 51 | row[9] = rsMeta.getColumnClassName(i); 52 | row[10] = rsMeta.getColumnLabel(i); 53 | 54 | while (hasMoreData) { 55 | hasMoreData = false; 56 | for (int j = 0; j < row.length; j++) { 57 | String data = row[j]; 58 | int cutIndex = Math.min(data.length(), MAX_RS_META_COL_WIDTH); 59 | sb.append(String.format(getFormat(MAX_RS_META_COL_WIDTH), data.substring(0, cutIndex))); 60 | if (cutIndex == MAX_RS_META_COL_WIDTH) { 61 | row[j] = data.substring(cutIndex); 62 | hasMoreData = true; 63 | } 64 | else 65 | { 66 | row[j] = ""; 67 | } 68 | } 69 | sb.append("|\n"); 70 | } 71 | } 72 | printRowSeparator(sb, colNames.size(), MAX_RS_META_COL_WIDTH); 73 | 74 | System.out.println(sb.toString()); 75 | } 76 | catch (Exception e) { 77 | e.printStackTrace(); 78 | throw e; 79 | } 80 | } 81 | 82 | public static void printResultSet(ResultSet rs) throws SQLException { 83 | try { 84 | // Get the metadata of this rs. 85 | ResultSetMetaData rsMeta; 86 | rsMeta = rs.getMetaData(); 87 | int columnCount = rsMeta.getColumnCount(); 88 | StringBuilder sb = new StringBuilder(); 89 | int[] maxColsWidth = printRsHeader(sb, columnCount, rsMeta); 90 | printRsContents(sb, columnCount, rs, maxColsWidth); 91 | 92 | System.out.println(sb.toString()); 93 | } 94 | catch (Exception e) { 95 | e.printStackTrace(); 96 | throw e; 97 | } 98 | } 99 | 100 | private static String getFormat(int maxColWidth) { 101 | return "| %-" + maxColWidth + "s "; 102 | } 103 | 104 | private static void printRsContents(StringBuilder sb, int columnCount, ResultSet rs, int[] maxColsWidth) throws SQLException { 105 | String data = null; 106 | String cellValue; 107 | while (rs.next()) { 108 | String[] row = new String[columnCount]; 109 | 110 | boolean hasMoreData; 111 | do { 112 | hasMoreData = false; 113 | for (int i = 0; i < columnCount; i++) { 114 | if (row[i] == null) { 115 | cellValue = rs.getString(i + 1); 116 | row[i] = (cellValue == null ? NULL_STR : cellValue); 117 | } 118 | int cutIndex = Math.min(row[i].length(), maxColsWidth[i]); 119 | data = row[i].substring(0, cutIndex); 120 | if (cutIndex == maxColsWidth[i]) { 121 | row[i] = row[i].substring(cutIndex); 122 | hasMoreData = true; 123 | } 124 | else { 125 | row[i] = ""; 126 | } 127 | sb.append(String.format(getFormat(maxColsWidth[i]), data)); 128 | } 129 | sb.append("|\n"); 130 | } while (hasMoreData); 131 | } 132 | printRowSeparator(sb, columnCount, maxColsWidth); 133 | } 134 | 135 | private static int[] printRsHeader(StringBuilder sb, int columnCount, ResultSetMetaData rsMeta) throws SQLException { 136 | String[] col_names = new String[columnCount]; 137 | int[] maxColWidth = new int[columnCount]; 138 | for (int i = 0; i < columnCount; i++) { 139 | maxColWidth[i] = MAX_COL_WIDTH; 140 | col_names[i] = rsMeta.getColumnName(i+1); 141 | if (col_names[i].length() > maxColWidth[i]) { 142 | maxColWidth[i] = col_names[i].length(); 143 | } 144 | } 145 | 146 | printRowSeparator(sb, columnCount, maxColWidth); 147 | for (int i = 0; i < columnCount; i++) { 148 | sb.append(String.format(getFormat(maxColWidth[i]), col_names[i])); 149 | } 150 | sb.append("|\n"); 151 | printRowSeparator(sb, columnCount, maxColWidth); 152 | 153 | return maxColWidth; 154 | } 155 | 156 | private static void printRowSeparator(StringBuilder sb, int columnCount, int[] maxColsWidth) { 157 | sb.append("+"); 158 | for (int i = 0; i < columnCount; i++) { 159 | sb.append(new String(new char[maxColsWidth[i] + 2]).replace("\0", "-")); 160 | sb.append("|"); 161 | } 162 | sb.replace(sb.length() - 1, sb.length(), "+\n"); 163 | } 164 | 165 | private static void printRowSeparator(StringBuilder sb, int columnCount, int maxColsWidth) { 166 | sb.append("+"); 167 | for (int i = 0; i < columnCount; i++) { 168 | sb.append(new String(new char[maxColsWidth + 2]).replace("\0", "-")); 169 | sb.append("|"); 170 | } 171 | sb.replace(sb.length() - 1, sb.length(), "+\n"); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /evergreen/make_docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$PWD" 4 | 5 | if [[ $(lsb_release -is 2>/dev/null) == "Ubuntu" ]]; then 6 | sudo apt install texlive texlive-latex-extra texlive-fonts-recommended -y 7 | else 8 | echo "skipping installation of deps for non-Ubuntu OS" 9 | fi 10 | 11 | MDFILE="$DIR/docs/overview.md" 12 | 13 | # Define the output PDF file name 14 | OUTPUT_PDF="MongoDB_JDBC_Guide.pdf" 15 | 16 | # Use pandoc to convert the markdown file to a PDF 17 | pandoc -f gfm -V geometry:a4paper -V geometry:margin=2cm --toc -s -o "$DIR/docs/$OUTPUT_PDF" $MDFILE 18 | 19 | # Inform the user of the output file 20 | echo "PDF generated: $OUTPUT_PDF" 21 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | group = org.mongodb 2 | artifactId = adf-java-driver 3 | mongodbDriverVersion = 5.+ 4 | junitJupiterVersion = 5.5.+ 5 | mockitoVersion = 3.0.+ 6 | googleLintVersion = 1.+ 7 | bouncyCastleVersion = 1.+ 8 | guavaVersion = 32.0.1-jre 9 | lang3Version=3.+ 10 | commonsTextVersion=1.+ 11 | nexusDomain = http://localhost:8081/nexus 12 | oauth2OIDCVersion = 11.+ 13 | snakeYamlVersion = 2.+ 14 | thymeLeafVersion = 3.1.2.RELEASE 15 | # to disable publication of both SHA-256 and SHA-512 checksums which causes error in maven release 16 | systemProp.org.gradle.internal.publish.checksums.insecure = true 17 | cyclonedxBomName = sbom_without_team_name 18 | cyclonedxBomDestination = artifacts/ssdlc 19 | thirdpartyNoticeDir = reports/licenses 20 | thirdpartyNoticeName = THIRD-PARTY-LICENSE.txt 21 | -------------------------------------------------------------------------------- /gradle/deploy.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | task publishMaven { 3 | group = 'publishing' 4 | dependsOn ':generateLicenseReport' 5 | 6 | if (releaseVersion.endsWith('-SNAPSHOT')) { 7 | description = 'Publishes snapshots to Sonatype' 8 | println("Will publish snapshots to Sonatype") 9 | dependsOn ':publishToSonatype' 10 | } else { 11 | description = 'Publishes a release and uploads to Sonatype / Maven Central' 12 | println("Will publish a release and uploads to Sonatype / Maven Central") 13 | if (project.name == rootProject.name) { 14 | dependsOn ':closeAndReleaseRepository' 15 | dependsOn ':publishToSonatype' 16 | // Make sure we publish to staging first 17 | project.tasks.getByName('publishToSonatype').finalizedBy( 18 | project.tasks.getByName('closeAndReleaseRepository'), 19 | ) 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gradle/publish.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'signing' 2 | apply plugin: 'io.codearte.nexus-staging' 3 | 4 | publishing { 5 | publications { 6 | mavenJava(MavenPublication) { 7 | from components.java 8 | artifact sourceJar { 9 | classifier 'sources' 10 | } 11 | artifact shadowJar 12 | artifact javadocJar 13 | artifact("$buildDir/"+thirdpartyNoticeDir+"/"+thirdpartyNoticeName) { 14 | classifier = 'license' 15 | } 16 | artifact("$rootDir/artifacts/ssdlc/mongodb-jdbc.sbom.json") { 17 | classifier = 'sbom' 18 | } 19 | 20 | pom { 21 | name = 'JDBC Driver' 22 | description = 'JDBC Driver for MongoDB Atlas SQL interface' 23 | url = 'https://github.com/mongodb/mongo-jdbc-driver' 24 | licenses { 25 | license { 26 | name = 'The Apache License, Version 2.0' 27 | url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 28 | } 29 | } 30 | developers { 31 | developer { 32 | organization = 'MongoDB, Inc.' 33 | } 34 | } 35 | scm { 36 | url = 'https://github.com/mongodb/mongo-jdbc-driver' 37 | connection = 'scm:git@github.com:mongodb/mongo-jdbc-driver.git' 38 | developerConnection = 'scm:git@github.com:mongodb/mongo-jdbc-driver.git' 39 | } 40 | 41 | withXml { 42 | // Clear the existing dependencies 43 | def pomNode = asNode() 44 | pomNode.remove(pomNode.dependencies) 45 | 46 | // Add custom dependencies 47 | def newDependenciesNode = asNode().appendNode('dependencies') 48 | println("${configurations.runtimeClasspath.name} depedencies") 49 | // Get the resolved configuration 50 | // Collect direct dependencies 51 | configurations.runtimeClasspath.resolvedConfiguration.firstLevelModuleDependencies.each { resolvedDependency -> 52 | resolvedDependency.moduleArtifacts.each { artifact -> 53 | println " - ${artifact.moduleVersion.id.group}:${artifact.moduleVersion.id.name}:${artifact.moduleVersion.id.version}" 54 | def dependencyNode = newDependenciesNode.appendNode('dependency') 55 | dependencyNode.appendNode('groupId', artifact.moduleVersion.id.group) 56 | dependencyNode.appendNode('artifactId', artifact.name) 57 | dependencyNode.appendNode('version', artifact.moduleVersion.id.version) 58 | dependencyNode.appendNode('scope', "runtime") 59 | } 60 | } 61 | } 62 | } 63 | } 64 | } 65 | } 66 | 67 | nexusStaging { 68 | def nexusUrl = project.hasProperty('nexus_url') ? project.getProperty('nexus_url') : nexusDomain 69 | serverUrl "$nexusUrl/service/local/" 70 | username project.hasProperty('nexus_token_name') ? project.getProperty('nexus_token_name') : "" 71 | password project.hasProperty('nexus_token') ? project.getProperty('nexus_token') : "" 72 | packageGroup project.getGroup() 73 | stagingProfileId project.hasProperty('nexus_profile_id') ? project.getProperty('nexus_profile_id') : '' 74 | numberOfRetries 40 75 | } 76 | 77 | nexusPublishing { 78 | repositories { 79 | sonatype { 80 | def domain = project.hasProperty('nexus_url') ? project.getProperty('nexus_url') : nexusDomain 81 | nexusUrl = uri(nexusStaging.serverUrl) 82 | snapshotRepositoryUrl = uri("$domain/content/repositories/snapshots/") 83 | } 84 | } 85 | } 86 | 87 | javadoc { 88 | if(JavaVersion.current().isJava9Compatible()) { 89 | options.addBooleanOption('html5', true) 90 | } 91 | } 92 | 93 | afterEvaluate { 94 | signing { 95 | if (project.hasProperty('signing_key_id') && project.hasProperty('signing_password') && project.hasProperty('signing_secretKeyRingFile')) { 96 | sign publishing.publications.mavenJava 97 | } 98 | } 99 | } 100 | 101 | task listFirstLevelDependencies { 102 | doLast { 103 | println("First-level dependencies:") 104 | 105 | // For each configuration you are interested in, list the first-level dependencies 106 | configurations.all { configuration -> 107 | if (configuration.canBeResolved) { 108 | println("Configuration: ${configuration.name}") 109 | configuration.allDependencies.each { dependency -> 110 | // Print only the first-level dependencies (declared in build.gradle) 111 | println " - ${dependency.group}:${dependency.name}:${dependency.version}" 112 | } 113 | } 114 | } 115 | } 116 | } 117 | 118 | task listResolvedFirstLevelDependencies { 119 | doLast { 120 | println("Resolved first-level dependencies:") 121 | def configuration = configurations.runtimeClasspath 122 | if (configuration.canBeResolved) { 123 | println("Configuration: ${configuration.name}") 124 | // Get the resolved configuration 125 | def resolvedConfiguration = configuration.resolvedConfiguration 126 | // Collect direct dependencies 127 | resolvedConfiguration.firstLevelModuleDependencies.each { resolvedDependency -> 128 | resolvedDependency.moduleArtifacts.each { artifact -> 129 | println " - ${artifact.moduleVersion.id.group}:${artifact.moduleVersion.id.name}:${artifact.moduleVersion.id.version}" 130 | } 131 | } 132 | } 133 | } 134 | } 135 | 136 | 137 | 138 | /* 139 | For security we allow the signing-related project properties to be passed in as environment variables, which 140 | Gradle enables if they are prefixed with "ORG_GRADLE_PROJECT_". But since environment variables can not contain 141 | the '.' character and the signing-related properties contain '.', here we map signing-related project properties with '_' 142 | to ones with '.' that are expected by the signing plugin. 143 | */ 144 | gradle.taskGraph.whenReady { taskGraph -> 145 | if (taskGraph.allTasks.any { it instanceof Sign }) { 146 | if (project.hasProperty("signing_key_id")) { 147 | allprojects { ext."signing.keyId" = project.property("signing_key_id") } 148 | } 149 | if (project.hasProperty("signing_secretKeyRingFile")) { 150 | allprojects { ext."signing.secretKeyRingFile" = project.property("signing_secretKeyRingFile") } 151 | } 152 | if (project.hasProperty("signing_password")) { 153 | allprojects { ext."signing.password" = project.property("signing_password") } 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /gradle/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # DO NOT ECHO COMMANDS AS THEY CONTAIN SECRETS! 4 | 5 | set -o errexit # Exit the script with error if any of the commands fail 6 | set +o verbose # Command echoing off. 7 | set +o xtrace # Disable command traces before executing them. 8 | 9 | ############################################ 10 | # Main Program # 11 | ############################################ 12 | echo "${RING_FILE_GPG_BASE64}" | base64 --decode >${PROJECT_DIRECTORY}/secring.gpg 13 | 14 | trap "rm ${PROJECT_DIRECTORY}/secring.gpg; exit" EXIT HUP 15 | 16 | export ORG_GRADLE_PROJECT_nexus_token_name=${NEXUS_TOKEN_NAME} 17 | export ORG_GRADLE_PROJECT_nexus_token=${NEXUS_TOKEN} 18 | export ORG_GRADLE_PROJECT_signing_key_id=${SIGNING_KEY_ID} 19 | export ORG_GRADLE_PROJECT_signing_password=${SIGNING_PASSWORD} 20 | export ORG_GRADLE_PROJECT_signing_secretKeyRingFile=${PROJECT_DIRECTORY}/secring.gpg 21 | export ORG_GRADLE_PROJECT_nexus_url=${NEXUS_URL} 22 | export ORG_GRADLE_PROJECT_nexus_profile_id=${NEXUS_PROFILE_ID} 23 | 24 | set -o verbose # Command echoing on. 25 | set -o xtrace # Enable command traces before executing them. 26 | echo "Publishing snapshot or release" 27 | 28 | ./gradlew ${IS_RELEASE_PROP} -version 29 | ./gradlew ${IS_RELEASE_PROP} publishMaven --info 30 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mongodb/mongo-jdbc-driver/db847ccea7131cb0bae802a3b3313731a9cf6c2f/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://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 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /mongo-jdbc-downloads_template.json: -------------------------------------------------------------------------------- 1 | { 2 | "manual_link": "https://www.mongodb.com/docs/atlas/data-federation/query/query-with-sql/", 3 | "release_notes_link": "https://www.mongodb.com/docs/atlas/release-notes/sql/", 4 | "versions": [ 5 | { 6 | "version": "{RELEASE_VERSION}", 7 | "download_link": "https://repo1.maven.org/maven2/org/mongodb/mongodb-jdbc/{RELEASE_VERSION}" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /resources/authentication_test/X509/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFbzCCA1egAwIBAgIUT3yukZ0lf7w0Fh2up+pDcGe+jU4wDQYJKoZIhvcNAQEL 3 | BQAwRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQswCQYDVQQHDAJOWTEQMA4G 4 | A1UECgwHbW9uZ29kYjEMMAoGA1UECwwDZW5nMB4XDTI0MTEyNTE3MzU0NVoXDTI1 5 | MTEyNTE3MzU0NVowRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQswCQYDVQQH 6 | DAJOWTEQMA4GA1UECgwHbW9uZ29kYjEMMAoGA1UECwwDZW5nMIICIjANBgkqhkiG 7 | 9w0BAQEFAAOCAg8AMIICCgKCAgEA1mPXnBSRDrVGV+liN6LsxwWk7oqeNbq8VFsh 8 | 9Hw6IzcxoO7YTp0M3oSJUxbvA6YWzAXIyjagCvHhCAPa113CRHXhmo7zW/YSOpqj 9 | rubq6c0iCOod4CSgtmcdLDE9H3WUrOBkZ2IfWn0Lqk+FV9Ft2KKqDJ1jsOMb4eMH 10 | YT3xerUMwQM+UD0wDZeJwKwu0UbpzF+p06khkxljmz2MdHATh+Qv3/qBTpED3Rqr 11 | RsqGekZhMp7+NwBfUdZdholN12SwtwAaFI8s7AIXR3C8LQYmSCr13b2uyVtIEUbV 12 | 6nSpNNJGPt0sYfA+PzynD1KT6Hpbb/2j50kwXW4IlZ2RL+MgIsu54S5UsuZiO/2a 13 | r7/Ie4HdlJOcB0tnhkxT/jbk87yriSdabuG2blpFTig94H2fQHnONpt8B49z8/Iz 14 | ZrkqHm8tyeIFs8w7xQKC9W7Wp+wqRFKLnwg++DZKQ1UrkvUrGtZ6S2P4wrRabWqx 15 | gEP1L5mbdRlJBEETq1LQNkr5OVzLY2RRHgwq8Mv2ejUJagegZSYtTaUqU91inm2G 16 | bCKskfQ7Ojee2Ya82YaN/zMM0JSQv1tF8eEJ5X8nyZ9YHhlCH/Z7dPETILfokHBV 17 | oBRfCr7GKj+JplFUsQXaUf1xEL3NStzkPq8XbThXJw/0vbd/bEwFZ19gH3tEjdCV 18 | uYf7cj0CAwEAAaNTMFEwHQYDVR0OBBYEFGGi0J1Cws/ZD4kTzoVCa+lJWe+jMB8G 19 | A1UdIwQYMBaAFGGi0J1Cws/ZD4kTzoVCa+lJWe+jMA8GA1UdEwEB/wQFMAMBAf8w 20 | DQYJKoZIhvcNAQELBQADggIBAFXXHefGNoN6cEwcR6Nkquarc0yVUgbboSJcoKkd 21 | q7UWcmIMPg9WFKTDIU08m+jZHOY4ILqbfqzStPuz9hi6BXZKCrUkhO3uhWgRmFDS 22 | 7+oZfHdRXG18KkSjE2l4NCoflXoFSQePjQ7C6n2NJgXZJcluzCUsNiFQ9ShrRnC/ 23 | BLWbvOmw6FArzVYV+roQD26w9jXnTpZUFs3qVdXthM16Gydf87DZ8BdDl9LQfUQ9 24 | i9nQIaL3U1mPeD7p2fKgBuyToKDlcxS8VRGhTYD+njSoqBUGxWQC94fMfqVYdRo4 25 | kByDS7inOE0KN+hQStndX3ki5LY10RhDVD/c1Xz9sRki5Gr//WzYRDlBEVxsZ0fj 26 | lJbbel7WO0bSEX92ZPRfNgLNlGjq9Z1KilTuf7yLlvU0RSN8seOvFMv2rUNJqnuP 27 | l22Dtt3WvWu+InyPmYJl/kDoDpNHmX3bvVH4DaAuobswZBpNVJ3QOo3A5jO/aL8z 28 | zyCtk/cg7d2AjngOagat4qwdvmNuoCkfHUcx3LjxelaoAMVptqH5ebPqmUCjHjuQ 29 | 5zDmTrRTvcMv6kaYdo4NzO0eHS/4NnprdbAH2Njlh5QioCRCrINiMIG/M53FAvEY 30 | 2WUr5n/EVveVXyNceFpWUBgAYK4zhz1l/DFGel131bFGbz76DVzwS9Y4UjkfpvWO 31 | JTBF 32 | -----END CERTIFICATE----- 33 | -------------------------------------------------------------------------------- /resources/authentication_test/X509/client-encrypted.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN ENCRYPTED PRIVATE KEY----- 2 | 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 54 | -----END ENCRYPTED PRIVATE KEY----- 55 | -----BEGIN CERTIFICATE----- 56 | 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 85 | -----END CERTIFICATE----- 86 | 87 | -------------------------------------------------------------------------------- /resources/authentication_test/X509/client-unencrypted.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCvLusF36+ts32G 3 | 6khPpJSwHTBBZjPyD0MYlWulsrJLXmew4JJRklbbZFZZ6kkVJEd6weEMdGSmLtaN 4 | RavqU8FSrPajBFSk2fMmtfcbtDHbUXLpF/ji7q920nOx1XxbhJuktNFMP4DqbQty 5 | 0B6VQQsaeZtLtpV4zrwemEZdMBMh3DKUXGYpBhu4+DepXyU9cDHDZs5Ew2XsRBBP 6 | O27U58oOpP7oMKpjqDfKoHnJQmP0Q1qqxRF3jfuH6Sq5i4zGYnu5OfBYJYAM5O4T 7 | XYAmXiJR1dnybznzHMribTTKAshirnow3AtNuwBvJ1c7vW2hFSZYBaOpl+hUDcP2 8 | xxH33ApDqiO/2wnTMPJ042hnhR4+I79koRQue+sqjM3rcXwderwkp+p+NtSMzmgT 9 | 5VoXJKveYffazI5kdk66hwALrw02dhfj22LerrWLuPUuRjDaBWf1n5xO2ymsjx8L 10 | ErEVk+hhlwO53HwGKHzbuOv023uxHbMr1x9sIR8u96N6j+im4iw8BgJmcDhu2T5e 11 | AOO17xjr37n/E9kbWiUqvGPFCg9k4u8+ylDPmcVUWCs9eE3ZhV5zT+eD6qd0kQoa 12 | lWWdBg2szbLRPMixERqJ1bPWt+14tOUJyaCJORY+he+bkLV70uE09ixFcjjI6onT 13 | jqu0qmK6JwQ0deEi4BySH2Z/nlOKUQIDAQABAoICACS/vuW4iu3xXT/UHd83M0nO 14 | lbTib7szoGujzLUxy10sLKxaL9eUz0uuvL6X+0TIG4aQ7Vjjgcmqwa9ZEjtR3pgt 15 | WH/SBL+gSPWx7miNYHgVmflz4e4ZDA3tEAAaPMAmDVB77fwExlJnFaO8LO46es3O 16 | /NjhMHHrTGNOplQeJaVQv/uHdpbchSxERcjuAK3mv0myY0rhgpwRmypD2XgoN6bi 17 | zeZ/bv8A5tNG3sVte/JdvsNcG9Hsovtb2m6Z66oiNroggV68XyRVUewWDS//R0vL 18 | hLDqzElHnPfq2MwX0VmCKHffcS+ZLvoiUpZhooHMIgMNC8wj5cTcLmOyVv6b1jsK 19 | Gs2FAbZRzTqHuIQzWmUdgDdtY4H/OIv4jr9Ya8fMpV2ERImQgWdR1RA6/o0b3o6V 20 | 8oriXTFKIwU48zus7W2LIOFg7zVoG7Cxuu4bDb4s3JmWiBOimNF3GKeUJ9S6hGWJ 21 | 1eg3/T+FwXu6DrCiVEpYg3qC+P6coMa5bksbHM6cAXfcm2i8s/WG6a6h9IEvjEBU 22 | BmV4nTHTsZGOHrhwKZlHn49XmnWwjDnDw/cH2Oij9iucOqQULy117I2s/nBk6aPy 23 | j8BzSC03VXLUQFpn+6weGMSQNeUoZj5U52gCH8WMd6yJR8Qqc2Tjo+hnpFGWYgpB 24 | +WnlJc4ez5ok7A544YrBAoIBAQDuN4cBmsXqD10YlcXtZ9Zh0zgTglWL1qndoJQj 25 | LfOsIkuEdnMwQM1X1np5wSKFMZ6USxCqf9a7uS+ed037pFkpoWaIq3iMmCgI57lg 26 | vlaP+WgN0TFmf4/mQnwGW2KF011VA2BiQyw8Huf+I+vygsa/XNLBSxUbOoqm4OgK 27 | u48q8MLW6epmkIfHV0Q3aClVJTqKWA2h1TcyHXQTUkzSAKp48Dutbbf5tUbwiTjA 28 | Bopnjzycr+z1v7IdSMIbRsBPQb7e+CALqd1H2FG+mr2ajhMxHq0RLnntx0GeE/w2 29 | 2dzfohp9ndGaDHE4XN6IqMo3Ptlm5948qDkxLzq0VeE5j6ldAoIBAQC8QsdqGF2U 30 | SK6tpJoSfNIfOcTEe+LeKBtdt0lRhj7Nr3uOhbxtFfLL63ZpdcwiIL+uqzW+scDp 31 | WqNW6QlfhUVqlWQKFYCpgWfoJUtfOxMp2pVB6oG8PBk8JouubActfkLITjiYST8q 32 | Pn4N3CtzkasxBG8pR2M1Rqyd1OKjawfo/GNlaGFe2iMy/PhZxflrvs/KytzU9Eda 33 | GCawgu9WyAQ0WjMFdzdMmv7hdK4sZkj+GgDNxA9YDojuKzG3fize1LPU45oethgY 34 | wesK5eDflkn/U5ukENVNoPGGjM1HY9uAOJrJz/ibejCvQYOE1+p5VEfCzFgJtRcu 35 | aTCaPxuVQPGFAoIBAHZ+Clqi+SVnBQDQp0Zi60F3xiH2J8VKPu5uDKG/HsEVwgie 36 | vsdWxI2Xsw5TIm+scdwDxsN4mYCBKg2h/Jlac7uAfDcpS+prWSas1QopQ3eUMM0G 37 | rJL2isaXdYfX9xboPzmlV1EpZpx1JyLEDX5wzJmte2wIg/QqV4OQxftotls+rTwn 38 | 2J+x7sgaQWVqG30t6oOcLxO7shvsiKt/uZSQHjvQC29F70h3glTtfNwPpNLEbfrm 39 | i3DmLJvicCMPO2NxKZdRRudmVBqDoI21/PAfEa7SOnYcbyv2fE48VK2YCwT2ZkTr 40 | trHw1HSbxVmm1AdM7OkCFwqHBwPPIV1IhqKSMkUCggEAWsDyctHGItqa4nhsEad8 41 | f7MQiQuTxTaeYqIdxSArHGqQ7JbJy+h9wBIFZjd0LauN2/0LDp+P+K5J+XajnxmW 42 | 6heUP0w4Vv5cAcwgtoq65T1LIJiU7BIotBd81JudJjAsr3UN0VPWEF5J1BKkG7VI 43 | Snvxvnt8ds1YH0nl65OIH6eznsofzmLn/wd2DYjjgS5d60u6AyqzTto/pG2qRTJs 44 | 3HPzDpp23QYHAtaFtD+mxl/wrUDriK6REgdeky9PICh3fJQv0shDe4PX88v3iLFh 45 | gKVkbUX0HdUNOaicuOKJiRlAfTM1jHXuDD5P0XVowg5//YcWla9numbZGDJ98Ih7 46 | JQKCAQEAxdsQ3Wlmb+DX78/ofPgHL+R5Arszv+yI05IcmRno+MiSj0bvYiO5+/jN 47 | 1X/CaSRm9UviG6o+7vrMpw2/xq1UAC7P8JPTLWWyShW7yHX9H6nU87yhpxO4oOm+ 48 | hTONsaDut87lbBn3quvMMfeBt71BZ8Ie01Mszh9sWXwHVCEWgDomo2Dg7scRF7Ew 49 | E9Q+bPv0ylnkBEry/XVomGMBzlcQ7OBrMCGCxWZQnPW+1cWDApEPufXjKoalGIIl 50 | vrd+Gc6BZKoL4Cfp9hszEyz18uWgzcP78K/emmZWgLhyStsJDeZ3xCCaGvlaxIFu 51 | yXKgJVgDPxD3qXjY6VMMoudnihbV6Q== 52 | -----END PRIVATE KEY----- 53 | -----BEGIN CERTIFICATE----- 54 | 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 83 | -----END CERTIFICATE----- 84 | -------------------------------------------------------------------------------- /resources/authentication_test/X509/server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | 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 51 | T7klrEJ8hBzC0J77eZfIqnjbsw50rg== 52 | -----END PRIVATE KEY----- 53 | -----BEGIN CERTIFICATE----- 54 | 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 84 | -----END CERTIFICATE----- 85 | -------------------------------------------------------------------------------- /resources/authentication_test/X509/truststore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mongodb/mongo-jdbc-driver/db847ccea7131cb0bae802a3b3313731a9cf6c2f/resources/authentication_test/X509/truststore.jks -------------------------------------------------------------------------------- /resources/integration_test/README.md: -------------------------------------------------------------------------------- 1 | ## Integration Tests Specifications 2 | 3 | 4 | For the integration tests, a specific pattern is being used to test each function. Essentially, one test is used to 5 | check the metadata results of the function. Additional tests are used to check the result sets. For 6 | example, in `dbmd_constant_result_sets.yml`, `getTypeInfo_resultset_metadata_validation` is checking the metadata of 7 | the `getTypeInfo()` function, and `getTypeInfo_returns_constant_result_set` is checking the actual results against the 8 | expected result set of the `getTypeInfo()` function. -------------------------------------------------------------------------------- /resources/integration_test/testdata/adf_db_config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name" : "integration_test", 4 | "collections" : [ 5 | { 6 | "name": "*", 7 | "dataSources" : [ 8 | { 9 | "storeName" : "localmongo", 10 | "database" : "integration_test" 11 | } 12 | ] 13 | } 14 | ], 15 | "views" : [ 16 | { 17 | "name": "baz", 18 | "source": "bar", 19 | "pipeline": "[{\"$project\": {\"a\": \"$a\", \"a_type\": {\"$type\": \"$a\"}, \"a_string\": {\"$toString\": \"$a\"}}}]" 20 | } 21 | ] 22 | }, 23 | { 24 | "name" : "db2", 25 | "collections" : [ 26 | { 27 | "name": "*", 28 | "dataSources" : [ 29 | { 30 | "storeName" : "localmongo", 31 | "database" : "db2" 32 | } 33 | ] 34 | } 35 | ], 36 | "views" : null 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /resources/integration_test/testdata/dbmd_variable_result_set_data.yml: -------------------------------------------------------------------------------- 1 | dataset: 2 | - db: integration_test 3 | collection: foo 4 | docs: 5 | - {"_id": 0, "a": 1} 6 | - {"_id": 1, "a": 2} 7 | nonuniqueIndexes: 8 | - {"a": 1} 9 | 10 | - db: integration_test 11 | collection: bar 12 | docs: 13 | - {"_id": 0, "a": 1, "b": true, "xyz": "hello"} 14 | - {"_id": 1, "a": 2, "b": null} 15 | 16 | - db: db2 17 | collection: foo 18 | docs: 19 | - {"_id": 1, "b": 100} 20 | - {"_id": 2, "b": 200} 21 | nonuniqueIndexes: 22 | - {"b": -1} 23 | -------------------------------------------------------------------------------- /resources/integration_test/testdata/integration.yml: -------------------------------------------------------------------------------- 1 | dataset: 2 | - db: integration_test 3 | collection: class 4 | docs: 5 | - {_id: 0, studentid: 10329, name: "John", enrolled: true, startdate: 2000-01-01 } 6 | - {_id: 1, studentid: 342, name: "Jane", enrolled: false, startdate: 2000-02-01} 7 | - {_id: 2, studentid: 303, name: "Mike", enrolled: true, startdate: 2000-01-01} 8 | - {_id: 3, studentid: 204323, name: "Mary", enrolled: false, startdate: 2000-03-01} 9 | - {_id: 4, studentid: 10, name: "Pete", enrolled: false, startdate: 2000-01-01} 10 | 11 | - db: integration_test 12 | collection: grades 13 | docs: 14 | - {_id: 0, studentid: 303, testid: 3, score: 84.5} 15 | - {_id: 1, studentid: 10329, testid: 3, score: 97.4} 16 | - {_id: 2, studentid: 342, testid: 3, score: 89.3} 17 | - {_id: 3, studentid: 204323, testid: 3, score: 91.9} 18 | - {_id: 4, studentid: 303, testid: 5, score: 87.5} 19 | - {_id: 5, studentid: 10329, testid: 5, score: 74.4} 20 | - {_id: 6, studentid: 342, testid: 5, score: 80.1} 21 | - {_id: 7, studentid: 204323, testid: 5, score: 83.3} 22 | - {_id: 8, studentid: 200, testid: 5, score: 78.5} 23 | 24 | - db: integration_test 25 | collection: anyof_collection 26 | docs: 27 | - { _id: 0, a: 3 } 28 | - { _id: 1, a: 3000000000 } 29 | - { _id: 2, a: 4.5 } 30 | schema: { 31 | "bsonType":[ 32 | "object" 33 | ], 34 | "properties":{ 35 | "a":{ 36 | "bsonType":[ 37 | "long", 38 | "double", 39 | "int" 40 | ] 41 | }, 42 | "_id":{ 43 | "bsonType":[ 44 | "int" 45 | ] 46 | } 47 | } 48 | } 49 | 50 | - db: integration_test 51 | collection: any_collection 52 | docs: 53 | - { _id: 0, b: 3 } 54 | - { _id: 1, b: "b" } 55 | - { _id: 2, b: 4.5 } 56 | schema: { 57 | "bsonType":[ 58 | "object" 59 | ], 60 | "required":[ 61 | "b" 62 | ], 63 | "properties":{ 64 | "_id":{ 65 | "bsonType":[ 66 | "int" 67 | ] 68 | } 69 | } 70 | } 71 | 72 | - db: integration_test 73 | collection: null_and_missing 74 | docs: 75 | - { _id: 0, "a": !!org.bson.BsonTimestamp 1} 76 | - { _id: 1, "a": null } 77 | - { _id: 2 } 78 | 79 | - db: integration_test 80 | collection: a_non_lexicographic_field_order 81 | docs: 82 | - { _id: 4, "c": 7, "b": 6, "a":5, "A":1, "B": 2, "C": 3 } 83 | 84 | - db: integration_test 85 | collection: b_non_lexicographic_field_order 86 | docs: 87 | - { "a": 9, _id: 8 } 88 | 89 | - db: integration_test 90 | collection: types_other 91 | docsExtJson: 92 | - { 93 | _id: 0, 94 | array: [ 1, 2, 3, "$oid": "000000000000000000000003", "$timestamp": { "t": 200, "i": 0 }], 95 | dbPointer: { "$dbPointer": { "$ref": "namespace", "$id": { "$oid": "000000000000000000000001" }}}, 96 | javascript: { "$code": "function(){ }" }, 97 | javascriptWithScope: { "$code": "function(){ }", "$scope": { "foo": "bar" }}, 98 | maxKey: { "$maxKey": 1 }, 99 | minKey: { "$minKey": 1 }, 100 | object: { "foo": "bar", "objId": { "$oid": "000000000000000000000002" }, "value": 3, 101 | "time": { "$timestamp": { "t": 200, "i": 0 }}}, 102 | objectId: { "$oid": "000000000000000000000001" }, 103 | regularExpression: { "$regularExpression": { pattern: "a(bc)*", "options": "" }}, 104 | symbol: { "$symbol": "symbol" }, 105 | timestamp: { "$timestamp": { "t": 100, "i": 0 }} 106 | # Skip reason: SQL-395 107 | # undefined: {"$undefined":true}, 108 | } 109 | 110 | - db: integration_test 111 | collection: uuid 112 | docsExtJson: 113 | - _id: 0 114 | uuid: { "$uuid": "71bf369b-2c60-4e6f-b23f-f9e88167cc96" } 115 | type: "standard" 116 | - _id: 1 117 | uuid: { "$binary": { "base64": "b05gLJs2v3GWzGeB6Pk/sg==", "subType": "03" } } 118 | type: "javalegacy" 119 | - _id: 2 120 | uuid: { "$binary": { "base64": "mza/cWAsb06yP/nogWfMlg==", "subType": "03" } } 121 | type: "csharplegacy" 122 | - _id: 3 123 | uuid: { "$binary": { "base64": "cb82myxgTm+yP/nogWfMlg==", "subType": "03" } } 124 | type: "pythonlegacy" 125 | 126 | - db: integration_test 127 | view: baz 128 | -------------------------------------------------------------------------------- /resources/license_header.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright $YEAR-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 | -------------------------------------------------------------------------------- /resources/media/MongoDBAtlasJDBC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mongodb/mongo-jdbc-driver/db847ccea7131cb0bae802a3b3313731a9cf6c2f/resources/media/MongoDBAtlasJDBC.png -------------------------------------------------------------------------------- /resources/release/mongo_jdbc_compliance_report_template.md: -------------------------------------------------------------------------------- 1 | 2 | # Mongo JDBC Driver SSDLC Compliance Report - %VERSION% 3 | 4 | **Release Creator** 5 | %AUTHOR% - %AUTHOR_EMAIL% 6 | 7 | **Process Document** 8 | https://www.mongodb.com/resources/products/capabilities/supply-chain-security-in-mongodb-s-software-development-lifecycle 9 | 10 | **Tool used to track third party vulnerabilities** 11 | Silk Security 12 | 13 | **Third-Party Dependency Information** 14 | See SBOM at URL: %SBOM_URL% 15 | 16 | **Static Analysis Findings** 17 | See report at URL: %SARIF_URL% 18 | 19 | **Signature Information** 20 | Product is signed with signatures available which can be verified by following the instructions from our [README](https://github.com/mongodb/mongo-jdbc-driver#). 21 | 22 | **Known Vulnerabilities** 23 | Any vulnerabilities that may be shown in the links referenced above have been reviewed and accepted by the appropriate reviewers. 24 | -------------------------------------------------------------------------------- /resources/start_local_mdb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Usage start_local_mdb.sh [x509_cert_dir] [--x509] 4 | 5 | # architecture: "arm64" or "x64" 6 | # 7 | # This script will download each version of mongodb, start a mongod 8 | # for each, and create a user for each. With --x509 flag, it will 9 | # set up X.509 authentication. 10 | 11 | # Usage: download_and_extract_tgz 12 | download_and_extract_tgz() { 13 | tgz_file="$2.tgz" 14 | full_url="$1$tgz_file" 15 | 16 | echo "downloading $3 from $full_url" 17 | curl -O $full_url 18 | 19 | echo "extracting $tgz_file" 20 | tar zxvf $tgz_file 21 | } 22 | 23 | # Usage: download_mongod 24 | # type: "community" or "enterprise" 25 | download_mongod() { 26 | root_url="https://$1/linux/" 27 | download_and_extract_tgz $root_url $2 $3 28 | } 29 | 30 | # Usage: download_mongosh 31 | # architecture: "arm64" or "x64" 32 | download_mongosh() { 33 | root_url="https://downloads.mongodb.com/compass/" 34 | file_name="mongosh-2.3.0-linux-$1" 35 | download_and_extract_tgz $root_url $file_name "mongosh" 36 | 37 | # copy mongosh to the current directory and ensure it is executable 38 | cp $file_name/bin/mongosh . 39 | chmod +x mongosh 40 | } 41 | 42 | # Usage: start_mdb_and_create_user 43 | # type: "community" or "enterprise" 44 | start_mdb_and_create_user() { 45 | echo "starting mongodb $1 on port $2" 46 | db_path="$1_db" 47 | mkdir -p $db_path 48 | $5/bin/mongod --dbpath $db_path --port $2 & 49 | 50 | echo "waiting 5 seconds to allow mongod to finish starting before connecting" 51 | sleep 5 52 | 53 | echo "creating user for $1" 54 | ./mongosh test --port $2 --eval "db.createUser({user: '$3', pwd: '$4', roles: ['readWrite']})" 55 | } 56 | 57 | # Usage: start_mdb_with_x509 <$x509_cert_dir> 58 | start_mdb_with_x509() { 59 | local type=$1 60 | local port=$2 61 | local mongod_dir=$3 62 | local x509_cert_dir="$4" 63 | local db_path="${type}_db" 64 | 65 | echo "Starting MongoDB $type with initial configuration on port $port" 66 | mkdir -p $db_path 67 | $mongod_dir/bin/mongod --dbpath $db_path --port $port & 68 | 69 | echo "Waiting 5 seconds for MongoDB to start..." 70 | sleep 5 71 | 72 | echo "Creating X.509 user..." 73 | ./mongosh --port $port \ 74 | --eval 'db.getSiblingDB("$external").runCommand({ 75 | createUser: "OU=eng,O=mongodb,L=NY,ST=NY,C=US", 76 | roles: [ 77 | { role: "readWrite", db: "test" }, 78 | { role: "userAdminAnyDatabase", db: "admin" } 79 | ] 80 | })' 81 | 82 | echo "Stopping MongoDB to restart with auth..." 83 | $mongod_dir/bin/mongod --dbpath $db_path --shutdown 84 | sleep 5 85 | 86 | echo "Starting MongoDB with X.509 authentication enabled..." 87 | $mongod_dir/bin/mongod \ 88 | --dbpath $db_path \ 89 | --port $port \ 90 | --tlsMode requireTLS \ 91 | --tlsCertificateKeyFile "$x509_cert_dir/server.pem" \ 92 | --tlsCAFile "$x509_cert_dir/ca.crt" \ 93 | --bind_ip localhost & 94 | 95 | echo "MongoDB started with X.509 authentication enabled on port $port" 96 | } 97 | 98 | # Parse command line arguments 99 | community_mdb_version="$1" 100 | enterprise_mdb_version="$2" 101 | arch="$3" 102 | x509_cert_dir="$4" 103 | x509_mode=false 104 | 105 | if [ "$5" = "--x509" ]; then 106 | x509_mode=true 107 | fi 108 | 109 | community_base_url="fastdl.mongodb.org" 110 | enterprise_base_url="downloads.mongodb.com" 111 | 112 | download_mongod $community_base_url $community_mdb_version "community" 113 | download_mongod $enterprise_base_url $enterprise_mdb_version "enterprise" 114 | 115 | download_mongosh $arch 116 | 117 | if [ "$x509_mode" = true ]; then 118 | start_mdb_with_x509 "enterprise" $LOCAL_MDB_PORT_ENT $enterprise_mdb_version $x509_cert_dir 119 | else 120 | start_mdb_and_create_user "community" $LOCAL_MDB_PORT_COM $LOCAL_MDB_USER $LOCAL_MDB_PWD $community_mdb_version 121 | start_mdb_and_create_user "enterprise" $LOCAL_MDB_PORT_ENT $LOCAL_MDB_USER $LOCAL_MDB_PWD $enterprise_mdb_version 122 | fi 123 | -------------------------------------------------------------------------------- /resources/third_party_header.txt: -------------------------------------------------------------------------------- 1 | MongoDB uses third-party libraries or other resources that may 2 | be distributed under licenses different from the MongoDB software. 3 | 4 | In the event that we accidentally fail to list a required notice, 5 | please bring it to our attention through our JIRA system at: 6 | 7 | https://jira.mongodb.org 8 | 9 | The attached notices are provided for information only. 10 | 11 | 12 | -------------------------- 13 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/5.6.2/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = 'mongodb-jdbc' 11 | 12 | include 'demo' 13 | include 'smoketest' 14 | 15 | -------------------------------------------------------------------------------- /smoketest/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | } 4 | 5 | dependencies { 6 | runtimeOnly fileTree('../build/libs/') { include '*-all.jar' } 7 | testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: junitJupiterVersion 8 | } 9 | 10 | test { 11 | useJUnitPlatform() 12 | } 13 | test.onlyIf { project.hasProperty("smoketest") } 14 | -------------------------------------------------------------------------------- /smoketest/src/test/java/com/mongodb/jdbc/smoketest/SmokeTest.java: -------------------------------------------------------------------------------- 1 | package com.mongodb.jdbc.smoketest; 2 | 3 | import org.junit.jupiter.api.AfterEach; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | 8 | import java.sql.Connection; 9 | import java.sql.DatabaseMetaData; 10 | import java.sql.DriverManager; 11 | import java.sql.ResultSet; 12 | import java.sql.SQLException; 13 | import java.sql.Statement; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | import java.util.Properties; 17 | 18 | /** 19 | * SmokeTest runs a test on built artifacts to verify that connection, 20 | * metadata retrieval, and querying is successful 21 | */ 22 | public class SmokeTest { 23 | static final String URL = "jdbc:mongodb://localhost"; 24 | static final String DB = "integration_test"; 25 | 26 | // Connection and simple query to use for sanity check. 27 | private Map connections = new HashMap<>(); 28 | 29 | public static Connection getADFInstanceConnection(String url, String db) 30 | throws SQLException { 31 | Properties p = new java.util.Properties(); 32 | p.setProperty("user", System.getenv("ADF_TEST_LOCAL_USER")); 33 | p.setProperty("password", System.getenv("ADF_TEST_LOCAL_PWD")); 34 | p.setProperty("authSource", System.getenv("ADF_TEST_LOCAL_AUTH_DB")); 35 | p.setProperty("ssl", "false"); 36 | p.setProperty("database", db); 37 | return DriverManager.getConnection(URL, p); 38 | } 39 | 40 | private Connection getDirectRemoteInstanceConnection() throws SQLException { 41 | String mongoHost = System.getenv("SRV_TEST_HOST"); 42 | String mongoURI = 43 | "mongodb+srv://" 44 | + mongoHost 45 | + "/?readPreference=secondaryPreferred&connectTimeoutMS=300000"; 46 | String fullURI = "jdbc:" + mongoURI; 47 | 48 | String user = System.getenv("SRV_TEST_USER"); 49 | String pwd = System.getenv("SRV_TEST_PWD"); 50 | String authSource = System.getenv("SRV_TEST_AUTH_DB"); 51 | 52 | Properties p = new java.util.Properties(); 53 | p.setProperty("user", user); 54 | p.setProperty("password", pwd); 55 | p.setProperty("authSource", authSource); 56 | p.setProperty("database", "test"); 57 | 58 | return DriverManager.getConnection(fullURI, p); 59 | } 60 | 61 | @BeforeEach 62 | public void setupConnection() throws SQLException { 63 | String buildType = System.getenv("BUILD_TYPE"); 64 | boolean isEapBuild = "eap".equalsIgnoreCase(buildType); 65 | System.out.println("Read environment variable BUILD_TYPE: '" + buildType + "', Detected EAP build: " + isEapBuild); 66 | 67 | connections.put(getADFInstanceConnection(URL, DB), "SELECT * from class"); 68 | 69 | if (isEapBuild) { 70 | try { 71 | Connection directConnection = getDirectRemoteInstanceConnection(); 72 | connections.put(directConnection, "Select * from accounts limit 5"); 73 | } catch (SQLException e) { 74 | System.err.println("Failed to connect to direct remote instance: " + e.getMessage()); 75 | throw e; 76 | } 77 | } else { 78 | try { 79 | Connection directConnection = getDirectRemoteInstanceConnection(); 80 | directConnection.close(); 81 | throw new AssertionError("Expected direct remote connection to fail for non-EAP build"); 82 | } catch (SQLException e) { 83 | if (!"Connection failed.".equals(e.getMessage())) { 84 | throw new AssertionError("Expected 'Connection failed.' but got: " + e.getMessage()); 85 | } 86 | } 87 | } 88 | } 89 | 90 | @AfterEach 91 | protected void cleanupTest() throws SQLException { 92 | for (Connection conn : connections.keySet()) { 93 | conn.close(); 94 | } 95 | } 96 | 97 | @Test 98 | public void databaseMetadataTest() throws SQLException { 99 | System.out.println("Running databaseMetadataTest"); 100 | for (Connection conn : connections.keySet()) { 101 | DatabaseMetaData dbMetadata = conn.getMetaData(); 102 | System.out.println(dbMetadata.getDriverName()); 103 | System.out.println(dbMetadata.getDriverVersion()); 104 | 105 | ResultSet rs = dbMetadata.getColumns(null, "%", "%", "%"); 106 | rowsReturnedCheck(rs); 107 | } 108 | } 109 | 110 | @Test 111 | public void queryTest() throws SQLException { 112 | System.out.println("Running queryTest"); 113 | for (Map.Entry entry : connections.entrySet()) { 114 | try (Statement stmt = entry.getKey().createStatement()) { 115 | ResultSet rs = stmt.executeQuery(entry.getValue()); 116 | rowsReturnedCheck(rs); 117 | } 118 | } 119 | } 120 | 121 | public static void rowsReturnedCheck(ResultSet rs) throws SQLException { 122 | int actualCount = 0; 123 | while (rs.next()) { 124 | actualCount++; 125 | } 126 | System.out.println("Rows returned count: " + actualCount); 127 | assertTrue(actualCount >= 1, "No rows returned in result set"); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/integration-test/java/com/mongodb/jdbc/integration/testharness/README.md: -------------------------------------------------------------------------------- 1 | ### Test Generator 2 | Included in the test harness is a test generator that will generate baseline configurations for test cases based on 3 | the `description`, `db`, and either `query` or `meta_function` fields for all test cases in the 4 | `resources/integration_test/tests` directory. 5 | #### Initial Tests 6 | Create a yaml file in the `resources/integration_test/tests` directory in the following format. The required fields 7 | are `description`, `db`, and one of either `sql` or `meta_function`. 8 | ``` 9 | # test.yaml 10 | tests: 11 | - description: test_case_description 12 | db: database_to_use 13 | sql: SQL Query 14 | 15 | - description: test_case_description 16 | db: database_to_use 17 | # meta_function takes an array. Function name followed by arguments. 18 | meta_function: [Function name, arg1, arg2, ..., argn] 19 | ``` 20 | #### Running 21 | ``` 22 | ./gradlew runTestGenerator 23 | ``` 24 | Generated files will be written to the `resources/generated_test` directory with the description as the 25 | filename prefix, one file per test case. 26 | 27 | To test the generated test cases, copy the file(s) to the `resources/integration_test/tests` directory and verify it 28 | passes the integration test. Once verified, commit the file in the `resources/integration_test/tests` directory to 29 | add it to the integration test. 30 | 31 | ### Data Loader 32 | #### Running 33 | ``` 34 | ./gradlew runDataloader 35 | ``` 36 | #### YAML Fields 37 | `db`: Database to use 38 | `collection`: Collection to use 39 | `docs`: Uses standard JSON to represent collection data. This is useful for simple types such as int and string. 40 | `docsExtJson`: uses extended JSON to represent collection data. This is useful for complex types such as binData and objectid. 41 | 42 | -------------------------------------------------------------------------------- /src/integration-test/java/com/mongodb/jdbc/integration/testharness/TestTypeInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc.integration.testharness; 18 | 19 | import java.lang.reflect.Field; 20 | import java.sql.DatabaseMetaData; 21 | import java.sql.Types; 22 | 23 | public class TestTypeInfo { 24 | private static final String COLUMN_NO_NULLS = "columnNoNulls"; 25 | private static final String COLUMN_NULLABLE = "columnNullable"; 26 | private static final String COLUMN_NULLABLE_UNKNOWN = "columnNullableUnknown"; 27 | 28 | public static int typesStringToInt(String type) throws IllegalAccessException { 29 | for (Field field : Types.class.getFields()) { 30 | if (field.getName().equalsIgnoreCase(type)) { 31 | return (field.getInt(new Object())); 32 | } 33 | } 34 | throw new IllegalArgumentException("unknown type: " + type); 35 | } 36 | 37 | public static String typesIntToString(int type) throws IllegalAccessException { 38 | for (Field field : Types.class.getFields()) { 39 | if (type == field.getInt(new Object())) { 40 | return (field.getName()); 41 | } 42 | } 43 | throw new IllegalArgumentException("unknown type: " + type); 44 | } 45 | 46 | public static int nullableStringToInt(String type) { 47 | if (type.toUpperCase().equals(COLUMN_NO_NULLS.toUpperCase())) { 48 | return DatabaseMetaData.columnNoNulls; 49 | } else if (type.toUpperCase().equals(COLUMN_NULLABLE.toUpperCase())) { 50 | return DatabaseMetaData.columnNullable; 51 | } else if (type.toUpperCase().equals(COLUMN_NULLABLE_UNKNOWN.toUpperCase())) { 52 | return DatabaseMetaData.columnNullableUnknown; 53 | } 54 | throw new IllegalArgumentException("unknown nullable type: " + type); 55 | } 56 | 57 | public static String nullableIntToString(int type) { 58 | switch (type) { 59 | case DatabaseMetaData.columnNoNulls: 60 | return COLUMN_NO_NULLS; 61 | case DatabaseMetaData.columnNullable: 62 | return COLUMN_NULLABLE; 63 | case DatabaseMetaData.columnNullableUnknown: 64 | return COLUMN_NULLABLE_UNKNOWN; 65 | } 66 | throw new IllegalArgumentException("unknown nullable type: " + type); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/integration-test/java/com/mongodb/jdbc/integration/testharness/models/TestData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc.integration.testharness.models; 18 | 19 | import java.util.List; 20 | 21 | public class TestData { 22 | public List dataset; 23 | } 24 | -------------------------------------------------------------------------------- /src/integration-test/java/com/mongodb/jdbc/integration/testharness/models/TestDataEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc.integration.testharness.models; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | public class TestDataEntry { 23 | public String db; 24 | public String collection; 25 | public String view; 26 | public List> docs; 27 | public List> docsExtJson; 28 | public Map schema; 29 | public List> nonuniqueIndexes; 30 | } 31 | -------------------------------------------------------------------------------- /src/integration-test/java/com/mongodb/jdbc/integration/testharness/models/TestEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc.integration.testharness.models; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | public class TestEntry { 23 | public String description; 24 | public String db; 25 | public String sql; 26 | public List meta_function; 27 | public String skip_reason; 28 | public Integer row_count; 29 | public Boolean row_count_gte; 30 | public Boolean ordered; 31 | public List duplicated_columns_names; 32 | public List expected_result; 33 | public List> expected_result_extended_json; 34 | public List expected_sql_type; 35 | public List expected_bson_type; 36 | public List expected_catalog_name; 37 | public List expected_column_class_name; 38 | public List expected_column_label; 39 | public List expected_column_display_size; 40 | public List expected_precision; 41 | public List expected_scale; 42 | public List expected_schema_name; 43 | public List expected_is_auto_increment; 44 | public List expected_is_case_sensitive; 45 | public List expected_is_currency; 46 | public List expected_is_definitely_writable; 47 | public List expected_is_nullable; 48 | public List expected_is_read_only; 49 | public List expected_is_searchable; 50 | public List expected_is_signed; 51 | public List expected_is_writable; 52 | } 53 | -------------------------------------------------------------------------------- /src/integration-test/java/com/mongodb/jdbc/integration/testharness/models/Tests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc.integration.testharness.models; 18 | 19 | import java.util.List; 20 | 21 | public class Tests { 22 | public List tests; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/BsonExplicitCursor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import com.mongodb.ServerAddress; 20 | import com.mongodb.ServerCursor; 21 | import com.mongodb.client.MongoCursor; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | import org.bson.BsonDocument; 25 | 26 | /** 27 | * BsonExplicitCursor allows for creating an instance of MongoCursor from an explicit list of BSON 28 | * docs. Useful for testing or for any place static results are necessary. 29 | */ 30 | public class BsonExplicitCursor implements MongoCursor { 31 | private List docs; 32 | private int rowNum = 0; 33 | 34 | public static final BsonExplicitCursor EMPTY_CURSOR = new BsonExplicitCursor(new ArrayList<>()); 35 | 36 | public BsonExplicitCursor(List docs) { 37 | this.docs = docs; 38 | } 39 | 40 | @Override 41 | public void close() {} 42 | 43 | @Override 44 | public ServerAddress getServerAddress() { 45 | return new ServerAddress("127.0.0.1"); 46 | } 47 | 48 | @Override 49 | public ServerCursor getServerCursor() { 50 | return null; 51 | } 52 | 53 | @Override 54 | public boolean hasNext() { 55 | return rowNum < docs.size(); 56 | } 57 | 58 | @Override 59 | public BsonDocument next() { 60 | return docs.get(rowNum++); 61 | } 62 | 63 | @Override 64 | public int available() { 65 | return docs.size() - rowNum; 66 | } 67 | 68 | @Override 69 | public BsonDocument tryNext() { 70 | if (hasNext()) { 71 | return next(); 72 | } 73 | return null; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/BuildInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc; 18 | 19 | import java.util.List; 20 | import java.util.Set; 21 | import org.bson.codecs.pojo.annotations.BsonCreator; 22 | import org.bson.codecs.pojo.annotations.BsonProperty; 23 | 24 | public class BuildInfo { 25 | private String fullVersion; 26 | private List versionArray; 27 | public Set modules; 28 | public int ok; 29 | 30 | public DataLake dataLake; 31 | 32 | @BsonCreator 33 | public BuildInfo( 34 | @BsonProperty("version") String version, 35 | @BsonProperty("versionArray") List versionArray, 36 | @BsonProperty("modules") Set modules, 37 | @BsonProperty("ok") int ok, 38 | @BsonProperty("dataLake") DataLake dataLake) 39 | throws IndexOutOfBoundsException { 40 | this.fullVersion = version; 41 | this.versionArray = versionArray; 42 | if (dataLake != null) { 43 | this.fullVersion += "." + dataLake.version + "." + dataLake.mongoSQLVersion; 44 | } 45 | this.dataLake = dataLake; 46 | this.ok = ok; 47 | this.modules = modules; 48 | } 49 | 50 | public String getFullVersion() { 51 | return this.fullVersion; 52 | } 53 | 54 | public int getMajorVersion() throws IndexOutOfBoundsException { 55 | return this.versionArray.get(0); 56 | } 57 | 58 | public int getMinorVersion() throws IndexOutOfBoundsException { 59 | return this.versionArray.get(1); 60 | } 61 | 62 | // Override toString for logging 63 | @Override 64 | public String toString() { 65 | return "BuildInfo{" 66 | + "fullVersion='" 67 | + fullVersion 68 | + '\'' 69 | + ", versionArray=" 70 | + versionArray 71 | + ", majorVersion=" 72 | + this.getMajorVersion() 73 | + ", minorVersion=" 74 | + this.getMinorVersion() 75 | + ", modules=" 76 | + modules 77 | + ", ok=" 78 | + ok 79 | + ", dataLake=" 80 | + dataLake 81 | + '}'; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/DataLake.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc; 18 | 19 | public class DataLake { 20 | public String version; 21 | public String mongoSQLVersion; 22 | 23 | // Override toString for logging 24 | @Override 25 | public String toString() { 26 | return "DataLake{" 27 | + "version='" 28 | + version 29 | + '\'' 30 | + ", mongoSQLVersion=" 31 | + mongoSQLVersion 32 | + '}'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/JsonSchema.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import java.util.Map; 20 | import java.util.Objects; 21 | import java.util.Set; 22 | import org.bson.BsonValue; 23 | 24 | // Simple POJO for deserializing jsonschema. 25 | // For more details on jsonSchema, see https://docs.mongodb.com/manual/reference/operator/query/jsonSchema/. 26 | public class JsonSchema { 27 | 28 | public BsonValue bsonType; 29 | public Map properties; 30 | public Set anyOf; 31 | public Set required; 32 | public BsonValue items; 33 | public BsonValue additionalProperties; 34 | 35 | @Override 36 | public boolean equals(Object obj) { 37 | if (!(obj instanceof MongoJsonSchema)) { 38 | return false; 39 | } 40 | MongoJsonSchema other = (MongoJsonSchema) obj; 41 | return Objects.equals(bsonType, other.bsonType) 42 | && Objects.equals(properties, other.properties) 43 | && Objects.equals(anyOf, other.anyOf) 44 | && Objects.equals(required, other.required) 45 | && Objects.equals(items, other.items) 46 | && Objects.equals(additionalProperties, other.additionalProperties); 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | return Objects.hash(bsonType, properties, anyOf, required, items, additionalProperties); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/MongoColumnInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import org.apache.commons.lang3.builder.ToStringBuilder; 20 | import org.apache.commons.lang3.builder.ToStringStyle; 21 | import org.bson.BsonType; 22 | 23 | public class MongoColumnInfo { 24 | private final String datasource; 25 | private final String field; 26 | private final BsonTypeInfo bsonTypeInfo; 27 | private final boolean isPolymorphic; 28 | private final int nullable; 29 | 30 | MongoColumnInfo(String datasource, String field, BsonTypeInfo bsonTypeInfo, int nullability) { 31 | this.datasource = datasource; 32 | this.field = field; 33 | this.bsonTypeInfo = bsonTypeInfo; 34 | this.nullable = nullability; 35 | this.isPolymorphic = bsonTypeInfo == BsonTypeInfo.BSON_BSON; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); 41 | } 42 | 43 | public boolean isPolymorphic() { 44 | return isPolymorphic; 45 | } 46 | 47 | public BsonType getBsonTypeEnum() { 48 | return bsonTypeInfo.getBsonType(); 49 | } 50 | 51 | public String getBsonTypeName() { 52 | return bsonTypeInfo.getBsonName(); 53 | } 54 | 55 | public int getJDBCType() { 56 | return bsonTypeInfo.getJdbcType(); 57 | } 58 | 59 | public int getNullability() { 60 | return nullable; 61 | } 62 | 63 | public String getColumnName() { 64 | return field; 65 | } 66 | 67 | public String getColumnAlias() { 68 | return field; 69 | } 70 | 71 | public String getTableName() { 72 | return datasource; 73 | } 74 | 75 | public String getTableAlias() { 76 | return datasource; 77 | } 78 | 79 | public String getDatabase() { 80 | return ""; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/MongoConnectionProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import com.mongodb.ConnectionString; 20 | import java.io.File; 21 | import java.util.logging.Level; 22 | 23 | public class MongoConnectionProperties { 24 | private ConnectionString connectionString; 25 | private String database; 26 | private Level logLevel; 27 | private File logDir; 28 | private String clientInfo; 29 | private boolean extJsonMode; 30 | private String x509PemPath; 31 | 32 | public MongoConnectionProperties( 33 | ConnectionString connectionString, 34 | String database, 35 | Level logLevel, 36 | File logDir, 37 | String clientInfo, 38 | boolean extJsonMode, 39 | String x509PemPath) { 40 | this.connectionString = connectionString; 41 | this.database = database; 42 | this.logLevel = logLevel; 43 | this.logDir = logDir; 44 | this.clientInfo = clientInfo; 45 | this.extJsonMode = extJsonMode; 46 | this.x509PemPath = x509PemPath; 47 | } 48 | 49 | public ConnectionString getConnectionString() { 50 | return connectionString; 51 | } 52 | 53 | public String getDatabase() { 54 | return database; 55 | } 56 | 57 | public Level getLogLevel() { 58 | return logLevel; 59 | } 60 | 61 | public File getLogDir() { 62 | return logDir; 63 | } 64 | 65 | public String getClientInfo() { 66 | return clientInfo; 67 | } 68 | 69 | public boolean getExtJsonMode() { 70 | return extJsonMode; 71 | } 72 | 73 | public String getX509PemPath() { 74 | return x509PemPath; 75 | } 76 | 77 | /* 78 | * Generate a unique key for the connection properties. This key is used to identify the connection properties in the 79 | * connection cache. Properties that do not differentiate a specific client such as the log level are not included in the key. 80 | */ 81 | public Integer generateKey() { 82 | StringBuilder keyBuilder = new StringBuilder(); 83 | keyBuilder.append(connectionString.toString()); 84 | if (clientInfo != null) { 85 | keyBuilder.append(":clientInfo=").append(clientInfo); 86 | } 87 | return keyBuilder.toString().hashCode(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/MongoJsonSchemaResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | public class MongoJsonSchemaResult { 23 | public int ok; 24 | public Map metadata; 25 | public MongoVersionedJsonSchema schema; 26 | public List> selectOrder; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/MongoListTablesResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | public class MongoListTablesResult { 20 | public static final String TABLE = "table"; 21 | public static final String COLLECTION = "collection"; 22 | 23 | public String name; 24 | public String type; 25 | 26 | public void setType(String type) { 27 | // If mongodb type is COLLECTION, map it as TABLE. 28 | // Otherwise, keep the type as is. 29 | this.type = type.equalsIgnoreCase(COLLECTION) ? TABLE : type; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/MongoRunCmdListTablesResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-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 | package com.mongodb.jdbc; 18 | 19 | import java.util.ArrayList; 20 | 21 | public class MongoRunCmdListTablesResult { 22 | public CursorInfo cursor; 23 | 24 | public CursorInfo getCursor() { 25 | return cursor; 26 | } 27 | 28 | public static class CursorInfo { 29 | public long id; 30 | public String ns; 31 | public ArrayList firstBatch; 32 | 33 | public long getId() { 34 | return id; 35 | } 36 | 37 | public String getNs() { 38 | return ns; 39 | } 40 | 41 | public ArrayList getFirstBatch() { 42 | return firstBatch; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/MongoSerializationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc; 18 | 19 | public class MongoSerializationException extends Exception { 20 | public MongoSerializationException(String message) { 21 | super(message); 22 | } 23 | 24 | public MongoSerializationException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/MongoVersionedJsonSchema.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import org.bson.codecs.pojo.annotations.BsonCreator; 20 | import org.bson.codecs.pojo.annotations.BsonProperty; 21 | 22 | public class MongoVersionedJsonSchema { 23 | public Integer version; 24 | public MongoJsonSchema mongoJsonSchema; 25 | 26 | /** Empty Json schema. */ 27 | public MongoVersionedJsonSchema() {} 28 | 29 | /** 30 | * Deserialized json schema from a 'sqlgetschema' command. 31 | * 32 | * @param version The schema version. 33 | * @param schema The schema. 34 | */ 35 | @BsonCreator 36 | public MongoVersionedJsonSchema( 37 | @BsonProperty("version") final Integer version, 38 | @BsonProperty("jsonSchema") JsonSchema schema) { 39 | this.version = version; 40 | this.mongoJsonSchema = MongoJsonSchema.toSimplifiedMongoJsonSchema(schema); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/NoCheckStateJsonWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import java.io.Writer; 20 | import org.bson.json.JsonWriter; 21 | import org.bson.json.JsonWriterSettings; 22 | 23 | /** 24 | * NoCheckStateJsonWriter will allow writing of any Json value. It does not validate it is 25 | * constructing a valid document. Useful for writing Bson Values such as a BsonArray. 26 | */ 27 | public class NoCheckStateJsonWriter extends JsonWriter { 28 | 29 | public NoCheckStateJsonWriter(Writer writer, JsonWriterSettings settings) { 30 | super(writer, settings); 31 | } 32 | 33 | @Override 34 | protected boolean checkState(State[] validStates) { 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/Pair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import java.util.Objects; 20 | 21 | public class Pair { 22 | private L left; 23 | private R right; 24 | 25 | public Pair(L left, R right) { 26 | this.left = left; 27 | this.right = right; 28 | } 29 | 30 | public L left() { 31 | return left; 32 | } 33 | 34 | public R right() { 35 | return right; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) return true; 41 | if (o == null || getClass() != o.getClass()) return false; 42 | Pair pair = (Pair) o; 43 | return Objects.equals(left, pair.left) && Objects.equals(right, pair.right); 44 | } 45 | 46 | @Override 47 | public int hashCode() { 48 | return Objects.hash(left, right); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/SortableBsonDocument.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import java.util.List; 20 | import org.bson.BsonDocument; 21 | 22 | public class SortableBsonDocument extends BsonDocument implements Comparable { 23 | 24 | static class SortSpec { 25 | String key; 26 | ValueType type; 27 | 28 | SortSpec(String key, ValueType type) { 29 | this.key = key; 30 | this.type = type; 31 | } 32 | } 33 | 34 | enum ValueType { 35 | String, 36 | Int, 37 | Boolean, 38 | } 39 | 40 | List sortSpecs; 41 | BsonDocument nestedDocValue; 42 | 43 | SortableBsonDocument(List sortSpecs, String key, BsonDocument docValue) { 44 | super(key, docValue); 45 | 46 | this.sortSpecs = sortSpecs; 47 | this.nestedDocValue = docValue; 48 | } 49 | 50 | @Override 51 | public int compareTo(SortableBsonDocument o) { 52 | int r = 0; 53 | for (SortSpec sortSpec : this.sortSpecs) { 54 | switch (sortSpec.type) { 55 | case String: 56 | r = 57 | this.nestedDocValue 58 | .getString(sortSpec.key) 59 | .compareTo(o.nestedDocValue.getString(sortSpec.key)); 60 | break; 61 | case Int: 62 | r = 63 | this.nestedDocValue 64 | .getInt32(sortSpec.key) 65 | .compareTo(o.nestedDocValue.getInt32(sortSpec.key)); 66 | break; 67 | case Boolean: 68 | r = 69 | this.nestedDocValue 70 | .getBoolean(sortSpec.key) 71 | .compareTo(o.nestedDocValue.getBoolean(sortSpec.key)); 72 | break; 73 | } 74 | 75 | if (r != 0) { 76 | return r; 77 | } 78 | } 79 | 80 | return r; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/logging/AutoLoggable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc.logging; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * Annotation for identifying all classes which should log their public method entries. Used in 26 | * conjunction with LoggingAspect to provide auto-logging of public methods entry. 27 | */ 28 | @Retention(RetentionPolicy.CLASS) 29 | @Target({ElementType.TYPE, ElementType.METHOD}) 30 | public @interface AutoLoggable {} 31 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/logging/DisableAutoLogging.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc.logging; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * Annotation for identifying all methods which should be excluded from autologging the method 26 | * entry. Used in conjunction with LoggingAspect to provide auto-logging of public methods entry. 27 | */ 28 | @Retention(RetentionPolicy.CLASS) 29 | @Target({ElementType.TYPE, ElementType.METHOD}) 30 | public @interface DisableAutoLogging {} 31 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/logging/LoggingAspect.aj: -------------------------------------------------------------------------------- 1 | package com.mongodb.jdbc.logging; 2 | 3 | import com.mongodb.MongoException; 4 | import java.sql.SQLException; 5 | import java.util.Locale; 6 | import java.util.Properties; 7 | import java.util.logging.Level; 8 | import org.aspectj.lang.JoinPoint; 9 | import org.bson.BsonValue; 10 | 11 | public aspect LoggingAspect perthis(execution(com.mongodb.jdbc.*.new(..))) 12 | { 13 | private MongoLogger logger = null; 14 | 15 | pointcut setLogger(MongoLogger logger): set(MongoLogger *.*) && args(logger) && !within(LoggingAspect) ; 16 | 17 | // Around setLogger() advice 18 | Object around(MongoLogger arg): setLogger(arg) { 19 | this.logger = arg; 20 | return proceed(arg); 21 | } 22 | 23 | before() : (execution(public * @AutoLoggable com.mongodb.jdbc.*.*(..))|| 24 | execution(@AutoLoggable public * com.mongodb.jdbc.*.*(..))) && 25 | !@annotation(com.mongodb.jdbc.logging.DisableAutoLogging) && 26 | !within(LoggingAspect) { 27 | if (null != logger) { 28 | final StringBuilder b = new StringBuilder(thisJoinPoint.getSignature().getName()); 29 | Object[] params = thisJoinPoint.getArgs(); 30 | if (params.length > 0) { 31 | b.append("("); 32 | for (int i = 0; i < params.length; i++) { 33 | // Obfuscate String and BsonValue parameters 34 | if (params[i] instanceof String) { 35 | b.append("***"); 36 | } 37 | else if (params[i] instanceof BsonValue) { 38 | b.append("Bson"); 39 | char bsonTypeName[] = 40 | ((BsonValue)params[i]).getBsonType().toString().toLowerCase().toCharArray(); 41 | bsonTypeName[0] = Character.toUpperCase(bsonTypeName[0]); 42 | b.append(bsonTypeName.toString()); 43 | b.append("{***}"); 44 | } 45 | else if (params[i] instanceof Properties) { 46 | b.append(((Properties)params[i]).stringPropertyNames()); 47 | } 48 | else 49 | { 50 | b.append(params[i]); 51 | } 52 | b.append(", "); 53 | } 54 | b.delete(b.length()-2, b.length()); 55 | b.append(")"); 56 | } 57 | else 58 | { 59 | b.append("()"); 60 | } 61 | logger.logMethodEntry(thisJoinPoint.getSignature().getDeclaringTypeName(), b.toString()); 62 | } 63 | } 64 | 65 | after () throwing (Exception e) : execution(* *.*(..)) && !within(LoggingAspect) 66 | { 67 | if (null != logger) { 68 | logger.logError( 69 | thisJoinPoint.getSignature().getDeclaringTypeName(), 70 | "Error in " + thisJoinPoint.getSignature().toShortString(), 71 | e); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/logging/MongoSimpleFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023-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 | package com.mongodb.jdbc.logging; 18 | 19 | import java.io.PrintWriter; 20 | import java.io.StringWriter; 21 | import java.util.Date; 22 | import java.util.logging.Formatter; 23 | import java.util.logging.LogRecord; 24 | 25 | public class MongoSimpleFormatter extends Formatter { 26 | private final String format = "[%1$tF %1$tT.%1$tL] [%4$s] %2$s: %5$s %6$s %n"; 27 | private final Date date = new Date(); 28 | 29 | @Override 30 | public String format(LogRecord record) { 31 | date.setTime(record.getMillis()); 32 | String source; 33 | if (record.getSourceClassName() != null) { 34 | source = record.getSourceClassName(); 35 | if (record.getSourceMethodName() != null) { 36 | source += " " + record.getSourceMethodName(); 37 | } 38 | } else { 39 | source = record.getLoggerName(); 40 | } 41 | String message = formatMessage(record); 42 | String throwable = ""; 43 | if (record.getThrown() != null) { 44 | StringWriter sw = new StringWriter(); 45 | PrintWriter pw = new PrintWriter(sw); 46 | pw.println(); 47 | record.getThrown().printStackTrace(pw); 48 | pw.close(); 49 | throwable = sw.toString(); 50 | } 51 | return String.format( 52 | format, 53 | date, 54 | source, 55 | record.getLoggerName(), 56 | record.getLevel().getLocalizedName(), 57 | message, 58 | throwable); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/logging/QueryDiagnostics.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025-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 | package com.mongodb.jdbc.logging; 18 | 19 | import static com.mongodb.jdbc.utils.BsonUtils.JSON_WRITER_NO_INDENT_SETTINGS; 20 | 21 | import com.mongodb.jdbc.MongoDriver; 22 | import com.mongodb.jdbc.MongoJsonSchema; 23 | import com.mongodb.jdbc.utils.BsonUtils; 24 | import org.bson.BsonArray; 25 | import org.bson.BsonDocument; 26 | import org.bson.codecs.Codec; 27 | import org.bson.codecs.pojo.annotations.BsonProperty; 28 | 29 | public class QueryDiagnostics { 30 | private static final Codec CODEC = 31 | MongoDriver.getCodecRegistry().get(QueryDiagnostics.class); 32 | 33 | @BsonProperty private String sqlQuery; 34 | @BsonProperty private BsonDocument queryCatalog; 35 | @BsonProperty private MongoJsonSchema resultSetSchema; 36 | @BsonProperty private BsonArray pipeline; 37 | 38 | public void setSqlQuery(String sqlQuery) { 39 | this.sqlQuery = sqlQuery; 40 | } 41 | 42 | public void setQueryCatalog(BsonDocument queryCatalog) { 43 | this.queryCatalog = queryCatalog; 44 | } 45 | 46 | public void setResultSetSchema(MongoJsonSchema resultSetSchema) { 47 | this.resultSetSchema = resultSetSchema; 48 | } 49 | 50 | public void setPipeline(BsonArray pipeline) { 51 | this.pipeline = pipeline; 52 | } 53 | 54 | public String getSqlQuery() { 55 | return sqlQuery; 56 | } 57 | 58 | public BsonDocument getQueryCatalog() { 59 | return queryCatalog; 60 | } 61 | 62 | public MongoJsonSchema getResultSetSchema() { 63 | return resultSetSchema; 64 | } 65 | 66 | public BsonArray getPipeline() { 67 | return pipeline; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return BsonUtils.toString(CODEC, this, JSON_WRITER_NO_INDENT_SETTINGS); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/mongosql/CheckDriverVersionResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.mongosql; 18 | 19 | import static com.mongodb.jdbc.utils.BsonUtils.JSON_WRITER_NO_INDENT_SETTINGS; 20 | 21 | import com.mongodb.jdbc.MongoDriver; 22 | import com.mongodb.jdbc.utils.BsonUtils; 23 | import org.bson.codecs.Codec; 24 | import org.bson.codecs.pojo.annotations.BsonCreator; 25 | import org.bson.codecs.pojo.annotations.BsonProperty; 26 | 27 | public class CheckDriverVersionResult { 28 | 29 | private static final Codec CODEC = 30 | MongoDriver.getCodecRegistry().get(CheckDriverVersionResult.class); 31 | 32 | @BsonProperty("compatible") 33 | public final Boolean compatible; 34 | 35 | @BsonCreator 36 | public CheckDriverVersionResult(@BsonProperty("compatible") Boolean compatible) { 37 | this.compatible = (compatible != null) ? compatible : false; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return BsonUtils.toString(CODEC, this, JSON_WRITER_NO_INDENT_SETTINGS); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/mongosql/GetMongosqlTranslateVersionResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.mongosql; 18 | 19 | import static com.mongodb.jdbc.utils.BsonUtils.JSON_WRITER_NO_INDENT_SETTINGS; 20 | 21 | import com.mongodb.jdbc.MongoDriver; 22 | import com.mongodb.jdbc.utils.BsonUtils; 23 | import org.bson.codecs.Codec; 24 | import org.bson.codecs.pojo.annotations.BsonCreator; 25 | import org.bson.codecs.pojo.annotations.BsonProperty; 26 | 27 | public class GetMongosqlTranslateVersionResult { 28 | 29 | private static final Codec CODEC = 30 | MongoDriver.getCodecRegistry().get(GetMongosqlTranslateVersionResult.class); 31 | 32 | @BsonProperty("version") 33 | public final String version; 34 | 35 | @BsonCreator 36 | public GetMongosqlTranslateVersionResult(@BsonProperty("version") String version) { 37 | this.version = version; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return BsonUtils.toString(CODEC, this, JSON_WRITER_NO_INDENT_SETTINGS); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/mongosql/GetNamespacesResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.mongosql; 18 | 19 | import static com.mongodb.jdbc.utils.BsonUtils.JSON_WRITER_NO_INDENT_SETTINGS; 20 | 21 | import com.mongodb.jdbc.MongoDriver; 22 | import com.mongodb.jdbc.utils.BsonUtils; 23 | import java.util.List; 24 | import org.bson.codecs.Codec; 25 | import org.bson.codecs.pojo.annotations.BsonCreator; 26 | import org.bson.codecs.pojo.annotations.BsonProperty; 27 | 28 | public class GetNamespacesResult { 29 | 30 | private static final Codec CODEC = 31 | MongoDriver.getCodecRegistry().get(GetNamespacesResult.class); 32 | 33 | @BsonProperty("namespaces") 34 | public final List namespaces; 35 | 36 | @BsonCreator 37 | public GetNamespacesResult(@BsonProperty("namespaces") List namespaces) { 38 | this.namespaces = namespaces; 39 | } 40 | 41 | public static class Namespace { 42 | private static final Codec CODEC = 43 | MongoDriver.getCodecRegistry().get(Namespace.class); 44 | 45 | @BsonProperty("database") 46 | public final String database; 47 | 48 | @BsonProperty("collection") 49 | public final String collection; 50 | 51 | @BsonCreator 52 | public Namespace( 53 | @BsonProperty("database") String database, 54 | @BsonProperty("collection") String collection) { 55 | this.database = database; 56 | this.collection = collection; 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return BsonUtils.toString(CODEC, this, JSON_WRITER_NO_INDENT_SETTINGS); 62 | } 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return BsonUtils.toString(CODEC, this, JSON_WRITER_NO_INDENT_SETTINGS); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/mongosql/MongoSQLException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.mongosql; 18 | 19 | public class MongoSQLException extends Exception { 20 | public MongoSQLException(String message) { 21 | super(message); 22 | } 23 | 24 | public MongoSQLException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/mongosql/TranslateResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.mongosql; 18 | 19 | import static com.mongodb.jdbc.utils.BsonUtils.JSON_WRITER_NO_INDENT_SETTINGS; 20 | 21 | import com.mongodb.jdbc.JsonSchema; 22 | import com.mongodb.jdbc.MongoDriver; 23 | import com.mongodb.jdbc.MongoJsonSchema; 24 | import com.mongodb.jdbc.utils.BsonUtils; 25 | import java.util.List; 26 | import org.bson.BsonDocument; 27 | import org.bson.codecs.Codec; 28 | import org.bson.codecs.pojo.annotations.BsonCreator; 29 | import org.bson.codecs.pojo.annotations.BsonProperty; 30 | 31 | public class TranslateResult { 32 | 33 | private static final Codec CODEC = 34 | MongoDriver.getCodecRegistry().get(TranslateResult.class); 35 | 36 | public final String targetDb; 37 | public final String targetCollection; 38 | public final List pipeline; 39 | public final MongoJsonSchema resultSetSchema; 40 | public final List> selectOrder; 41 | 42 | @BsonCreator 43 | public TranslateResult( 44 | @BsonProperty("target_db") String targetDb, 45 | @BsonProperty("target_collection") String targetCollection, 46 | @BsonProperty("pipeline") List pipeline, 47 | @BsonProperty("result_set_schema") JsonSchema resultSetSchema, 48 | @BsonProperty("select_order") List> selectOrder) { 49 | this.targetDb = targetDb; 50 | this.targetCollection = targetCollection; 51 | this.pipeline = pipeline; 52 | this.resultSetSchema = 53 | (resultSetSchema != null) 54 | ? MongoJsonSchema.toSimplifiedMongoJsonSchema(resultSetSchema) 55 | : null; 56 | this.selectOrder = selectOrder; 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return BsonUtils.toString(CODEC, this, JSON_WRITER_NO_INDENT_SETTINGS); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/JdbcIdpInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc; 18 | 19 | import com.mongodb.MongoCredential; 20 | import com.mongodb.lang.Nullable; 21 | import java.util.List; 22 | 23 | public class JdbcIdpInfo implements MongoCredential.IdpInfo { 24 | private final String issuer; 25 | 26 | @Nullable private final String clientId; 27 | private final List requestScopes; 28 | 29 | public JdbcIdpInfo(String issuer, String clientId, List requestScopes) { 30 | this.issuer = issuer; 31 | this.clientId = clientId; 32 | this.requestScopes = requestScopes; 33 | } 34 | 35 | public String getIssuer() { 36 | return this.issuer; 37 | } 38 | 39 | @Nullable 40 | public String getClientId() { 41 | return this.clientId; 42 | } 43 | 44 | public List getRequestScopes() { 45 | return this.requestScopes; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/JdbcOidcCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc; 18 | 19 | import com.mongodb.MongoCredential.OidcCallback; 20 | import com.mongodb.MongoCredential.OidcCallbackContext; 21 | import com.mongodb.MongoCredential.OidcCallbackResult; 22 | import com.mongodb.jdbc.logging.MongoLogger; 23 | import javax.security.auth.RefreshFailedException; 24 | 25 | public class JdbcOidcCallback implements OidcCallback { 26 | private final OidcAuthFlow oidcAuthFlow; 27 | 28 | public JdbcOidcCallback() { 29 | this.oidcAuthFlow = new OidcAuthFlow(); 30 | } 31 | 32 | public JdbcOidcCallback(MongoLogger parentLogger) { 33 | this.oidcAuthFlow = new OidcAuthFlow(parentLogger); 34 | } 35 | 36 | public OidcCallbackResult onRequest(OidcCallbackContext callbackContext) { 37 | String refreshToken = callbackContext.getRefreshToken(); 38 | if (refreshToken != null && !refreshToken.isEmpty()) { 39 | try { 40 | return oidcAuthFlow.doRefresh(callbackContext); 41 | } catch (RefreshFailedException e) { 42 | throw new RuntimeException(e); 43 | } 44 | } else { 45 | try { 46 | return oidcAuthFlow.doAuthCodeFlow(callbackContext); 47 | } catch (OidcTimeoutException e) { 48 | throw new RuntimeException(e); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/JdbcOidcCallbackContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc; 18 | 19 | import com.mongodb.MongoCredential.IdpInfo; 20 | import com.mongodb.MongoCredential.OidcCallbackContext; 21 | import java.time.Duration; 22 | 23 | public class JdbcOidcCallbackContext implements OidcCallbackContext { 24 | private Duration timeout; 25 | private int version; 26 | private String refreshToken; 27 | private IdpInfo idpInfo; 28 | private String userName; 29 | 30 | public JdbcOidcCallbackContext( 31 | Duration timeout, int version, String refreshToken, IdpInfo idpInfo, String userName) { 32 | this.timeout = timeout; 33 | this.version = version; 34 | this.refreshToken = refreshToken; 35 | this.idpInfo = idpInfo; 36 | this.userName = userName; 37 | } 38 | 39 | public String getUserName() { 40 | return this.userName; 41 | } 42 | 43 | public Duration getTimeout() { 44 | return this.timeout; 45 | } 46 | 47 | public int getVersion() { 48 | return this.version; 49 | } 50 | 51 | public String getRefreshToken() { 52 | return this.refreshToken; 53 | } 54 | 55 | public IdpInfo getIdpInfo() { 56 | return this.idpInfo; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/OidcResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc; 18 | 19 | public class OidcResponse { 20 | private String code; 21 | private String state; 22 | private String error; 23 | private String errorDescription; 24 | 25 | public String getCode() { 26 | return code; 27 | } 28 | 29 | public String getState() { 30 | return state; 31 | } 32 | 33 | public String getError() { 34 | return error; 35 | } 36 | 37 | public String getErrorDescription() { 38 | return errorDescription; 39 | } 40 | 41 | public void setCode(String code) { 42 | this.code = code; 43 | } 44 | 45 | public void setState(String state) { 46 | this.state = state; 47 | } 48 | 49 | public void setError(String error) { 50 | this.error = error; 51 | } 52 | 53 | public void setErrorDescription(String errorDescription) { 54 | this.errorDescription = errorDescription; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | StringBuilder sb = new StringBuilder(); 60 | if (code != null) { 61 | sb.append("Code: ").append(code).append("\n"); 62 | } 63 | if (state != null) { 64 | sb.append("State: ").append(state).append("\n"); 65 | } 66 | if (error != null) { 67 | sb.append("Error: ").append(error).append("\n"); 68 | } 69 | if (errorDescription != null) { 70 | sb.append("Error Description: ").append(errorDescription).append("\n"); 71 | } 72 | return sb.toString(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/OidcTimeoutException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc; 18 | 19 | public class OidcTimeoutException extends Exception { 20 | public OidcTimeoutException(String message) { 21 | super(message); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/manualtests/TestOidcAuthFlow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc.manualtests; 18 | 19 | import com.mongodb.MongoCredential.OidcCallbackContext; 20 | import com.mongodb.jdbc.oidc.JdbcOidcCallbackContext; 21 | import com.mongodb.jdbc.oidc.OidcAuthFlow; 22 | import java.time.Duration; 23 | 24 | public class TestOidcAuthFlow { 25 | public static void main(String[] args) { 26 | OidcAuthFlow authFlow = new OidcAuthFlow(); 27 | 28 | Duration timeout = Duration.ofMinutes(5); 29 | OidcCallbackContext callbackContext = 30 | new JdbcOidcCallbackContext(timeout, 1, null, TestOidcUtils.IDP_INFO, null); 31 | 32 | TestOidcUtils.testAuthCodeFlow(callbackContext, authFlow); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/manualtests/TestOidcAuthFlowAndRefresh.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc.manualtests; 18 | 19 | import com.mongodb.MongoCredential.OidcCallbackContext; 20 | import com.mongodb.MongoCredential.OidcCallbackResult; 21 | import com.mongodb.jdbc.oidc.JdbcOidcCallbackContext; 22 | import com.mongodb.jdbc.oidc.OidcAuthFlow; 23 | import java.time.Duration; 24 | 25 | public class TestOidcAuthFlowAndRefresh { 26 | public static void main(String[] args) { 27 | OidcAuthFlow authFlow = new OidcAuthFlow(); 28 | 29 | Duration timeout = Duration.ofMinutes(5); 30 | OidcCallbackContext callbackContext = 31 | new JdbcOidcCallbackContext(timeout, 1, null, TestOidcUtils.IDP_INFO, null); 32 | 33 | OidcCallbackResult result = TestOidcUtils.testAuthCodeFlow(callbackContext, authFlow); 34 | if (result != null) { 35 | // get refresh token from the AuthCodeFLow result 36 | OidcCallbackContext refreshContext = 37 | new JdbcOidcCallbackContext( 38 | timeout, 1, result.getRefreshToken(), TestOidcUtils.IDP_INFO, null); 39 | try { 40 | OidcCallbackResult refreshResult = authFlow.doRefresh(refreshContext); 41 | if (refreshResult != null) { 42 | System.out.println("Refreshed Access Token: " + refreshResult.getAccessToken()); 43 | System.out.println( 44 | "Refreshed Refresh Token: " + refreshResult.getRefreshToken()); 45 | } else { 46 | System.out.println("Refresh token flow failed."); 47 | } 48 | } catch (Exception e) { 49 | System.err.println( 50 | "An error occurred while running the refresh token flow: " 51 | + e.getMessage()); 52 | e.printStackTrace(); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/manualtests/TestOidcCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc.manualtests; 18 | 19 | import com.mongodb.MongoCredential.OidcCallback; 20 | import com.mongodb.MongoCredential.OidcCallbackContext; 21 | import com.mongodb.MongoCredential.OidcCallbackResult; 22 | import com.mongodb.jdbc.oidc.JdbcOidcCallback; 23 | import com.mongodb.jdbc.oidc.JdbcOidcCallbackContext; 24 | 25 | public class TestOidcCallback { 26 | 27 | public static void main(String[] args) { 28 | OidcCallback oidcCallback = new JdbcOidcCallback(); 29 | 30 | OidcCallbackContext initialContext = 31 | new JdbcOidcCallbackContext(null, 1, null, TestOidcUtils.IDP_INFO, null); 32 | try { 33 | OidcCallbackResult initialResult = oidcCallback.onRequest(initialContext); 34 | if (initialResult != null) { 35 | System.out.println("Access Token: " + initialResult.getAccessToken()); 36 | System.out.println("Refresh Token: " + initialResult.getRefreshToken()); 37 | } else { 38 | System.out.println("Authentication failed."); 39 | } 40 | OidcCallbackContext refreshContext = 41 | new JdbcOidcCallbackContext( 42 | null, 1, initialResult.getRefreshToken(), TestOidcUtils.IDP_INFO, null); 43 | OidcCallbackResult refreshResult = oidcCallback.onRequest(refreshContext); 44 | if (refreshResult != null) { 45 | System.out.println("Refreshed Access Token: " + refreshResult.getAccessToken()); 46 | System.out.println("Refreshed Refresh Token: " + refreshResult.getRefreshToken()); 47 | } else { 48 | System.out.println("Refresh token flow failed."); 49 | } 50 | } catch (Exception e) { 51 | System.err.println("Error during OIDC callback test: " + e.getMessage()); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/manualtests/TestOidcCallbackWithBadRefreshToken.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc.manualtests; 18 | 19 | import com.mongodb.MongoCredential.OidcCallback; 20 | import com.mongodb.MongoCredential.OidcCallbackContext; 21 | import com.mongodb.MongoCredential.OidcCallbackResult; 22 | import com.mongodb.jdbc.oidc.JdbcOidcCallback; 23 | import com.mongodb.jdbc.oidc.JdbcOidcCallbackContext; 24 | import javax.security.auth.RefreshFailedException; 25 | 26 | public class TestOidcCallbackWithBadRefreshToken { 27 | 28 | public static void main(String[] args) { 29 | OidcCallback oidcCallback = new JdbcOidcCallback(); 30 | 31 | String badRefreshToken = "bad-refresh-token"; 32 | OidcCallbackContext context = 33 | new JdbcOidcCallbackContext(null, 1, badRefreshToken, TestOidcUtils.IDP_INFO, null); 34 | 35 | try { 36 | OidcCallbackResult result = oidcCallback.onRequest(context); 37 | System.out.println("This should not print, bad refresh token expected to fail."); 38 | System.out.println(result); 39 | } catch (Exception e) { 40 | if (e.getCause() instanceof RefreshFailedException) { 41 | System.err.println( 42 | "Expected RefreshFailedException occurred: " + e.getCause().getMessage()); 43 | } else { 44 | System.err.println("Unexpected error: " + e.getMessage()); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/manualtests/TestOidcCallbackWithShortTimeout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc.manualtests; 18 | 19 | import com.mongodb.MongoCredential.OidcCallback; 20 | import com.mongodb.MongoCredential.OidcCallbackContext; 21 | import com.mongodb.MongoCredential.OidcCallbackResult; 22 | import com.mongodb.jdbc.oidc.JdbcOidcCallback; 23 | import com.mongodb.jdbc.oidc.JdbcOidcCallbackContext; 24 | import com.mongodb.jdbc.oidc.OidcTimeoutException; 25 | import java.time.Duration; 26 | 27 | public class TestOidcCallbackWithShortTimeout { 28 | 29 | public static void main(String[] args) { 30 | OidcCallback oidcCallback = new JdbcOidcCallback(); 31 | 32 | Duration shortTimeout = Duration.ofSeconds(2); // intentionally short to trigger timeout 33 | OidcCallbackContext context = 34 | new JdbcOidcCallbackContext(shortTimeout, 1, null, TestOidcUtils.IDP_INFO, null); 35 | 36 | try { 37 | OidcCallbackResult result = oidcCallback.onRequest(context); 38 | // Timeout is expected when user input is required as it should take longer than 2 second. 39 | // It may pass if the user is already signed in and credentials are saved in the browser. 40 | System.out.println( 41 | "This should not print, timeout expected. Sign out of the IdP or clear the browser cache " 42 | + "to trigger a timeout."); 43 | System.out.println(result); 44 | } catch (Exception e) { 45 | if (e.getCause() instanceof OidcTimeoutException) { 46 | System.err.println( 47 | "Expected OidcTimeoutException occurred: " + e.getCause().getMessage()); 48 | } else { 49 | System.err.println("Unexpected error: " + e.getMessage()); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/manualtests/TestOidcUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc.manualtests; 18 | 19 | import com.mongodb.MongoCredential.IdpInfo; 20 | import com.mongodb.MongoCredential.OidcCallbackContext; 21 | import com.mongodb.MongoCredential.OidcCallbackResult; 22 | import com.mongodb.jdbc.oidc.JdbcIdpInfo; 23 | import com.mongodb.jdbc.oidc.OidcAuthFlow; 24 | import java.util.Collections; 25 | import java.util.List; 26 | 27 | public class TestOidcUtils { 28 | 29 | public static String OIDC_ISSUER = "https://mongodb-dev.okta.com/oauth2/ausqrxbcr53xakaRR357"; 30 | public static String OIDC_CLIENT_ID = "0oarvap2r7PmNIBsS357"; 31 | public static final List OPENID_SCOPE = Collections.singletonList("openid"); 32 | 33 | public static final IdpInfo IDP_INFO = 34 | new JdbcIdpInfo(OIDC_ISSUER, OIDC_CLIENT_ID, OPENID_SCOPE); 35 | 36 | public static OidcCallbackResult testAuthCodeFlow( 37 | OidcCallbackContext callbackContext, OidcAuthFlow authFlow) { 38 | 39 | try { 40 | OidcCallbackResult result = authFlow.doAuthCodeFlow(callbackContext); 41 | if (result != null) { 42 | System.out.println("Access Token: " + result.getAccessToken()); 43 | System.out.println("Refresh Token: " + result.getRefreshToken()); 44 | return result; 45 | } else { 46 | System.out.println("Authentication failed."); 47 | } 48 | } catch (Exception e) { 49 | System.err.println( 50 | "An error occurred while running the OIDC authentication flow: " 51 | + e.getMessage()); 52 | e.printStackTrace(); 53 | } 54 | return null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/oidc/manualtests/TestRFC8252Server.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc.manualtests; 18 | 19 | import com.mongodb.jdbc.oidc.OidcResponse; 20 | import com.mongodb.jdbc.oidc.OidcTimeoutException; 21 | import com.mongodb.jdbc.oidc.RFC8252HttpServer; 22 | import java.io.IOException; 23 | /** 24 | * Main class to start the RFC8252HttpServer and wait for the OIDC response Used for testing the 25 | * serving of the HTML pages and the OIDC response 26 | */ 27 | public class TestRFC8252Server { 28 | public static void main(String[] args) { 29 | int port = RFC8252HttpServer.DEFAULT_REDIRECT_PORT; 30 | RFC8252HttpServer server = new RFC8252HttpServer(); 31 | try { 32 | server.start(); 33 | System.out.println("Server started on port " + port); 34 | 35 | // Wait for the OIDC response 36 | OidcResponse oidcResponse = server.getOidcResponse(); 37 | System.out.println("Server Result:\n" + oidcResponse.toString()); 38 | 39 | Thread.sleep(2000); 40 | } catch (IOException | OidcTimeoutException | InterruptedException e) { 41 | e.printStackTrace(); 42 | } finally { 43 | server.stop(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/utils/BsonUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.utils; 18 | 19 | import com.mongodb.jdbc.MongoSerializationException; 20 | import com.mongodb.jdbc.NoCheckStateJsonWriter; 21 | import java.io.IOException; 22 | import java.io.StringWriter; 23 | import java.nio.ByteBuffer; 24 | import org.bson.BsonBinaryReader; 25 | import org.bson.BsonBinaryWriter; 26 | import org.bson.BsonDocument; 27 | import org.bson.BsonDocumentWriter; 28 | import org.bson.codecs.*; 29 | import org.bson.io.BasicOutputBuffer; 30 | import org.bson.json.JsonMode; 31 | import org.bson.json.JsonWriter; 32 | import org.bson.json.JsonWriterSettings; 33 | 34 | /** Utility class for BSON serialization and deserialization. */ 35 | public class BsonUtils { 36 | public static final JsonWriterSettings JSON_WRITER_SETTINGS = 37 | JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).indent(true).build(); 38 | 39 | public static final JsonWriterSettings JSON_WRITER_NO_INDENT_SETTINGS = 40 | JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).indent(false).build(); 41 | 42 | /** 43 | * Serializes a BsonDocument into a BSON byte array. 44 | * 45 | * @param doc The BsonDocument to serialize. 46 | * @return BSON byte array. 47 | * @throws MongoSerializationException If serialization fails. 48 | */ 49 | public static byte[] serialize(BsonDocument doc) throws MongoSerializationException { 50 | if (doc == null) { 51 | throw new MongoSerializationException("Cannot serialize a null BsonDocument."); 52 | } 53 | try (BasicOutputBuffer buffer = new BasicOutputBuffer(); 54 | BsonBinaryWriter writer = new BsonBinaryWriter(buffer)) { 55 | BsonDocumentCodec codec = new BsonDocumentCodec(); 56 | codec.encode(writer, doc, EncoderContext.builder().build()); 57 | writer.flush(); 58 | return buffer.toByteArray(); 59 | } catch (RuntimeException e) { 60 | throw new MongoSerializationException("Failed to serialize BSON.", e); 61 | } 62 | } 63 | 64 | /** 65 | * Deserializes a BSON byte array into a BsonDocument. 66 | * 67 | * @param bytes The BSON byte array. 68 | * @return The deserialized BsonDocument. 69 | * @throws MongoSerializationException If deserialization fails. 70 | */ 71 | public static BsonDocument deserialize(byte[] bytes) throws MongoSerializationException { 72 | try (BsonBinaryReader reader = new BsonBinaryReader(ByteBuffer.wrap(bytes))) { 73 | BsonDocumentCodec codec = new BsonDocumentCodec(); 74 | return codec.decode(reader, DecoderContext.builder().build()); 75 | } catch (RuntimeException e) { 76 | throw new MongoSerializationException("Failed to deserialize BSON.", e); 77 | } 78 | } 79 | 80 | public static String toString(Codec codec, T val, JsonWriterSettings settings) { 81 | try (StringWriter writer = new StringWriter(); 82 | JsonWriter jsonWriter = new NoCheckStateJsonWriter(writer, settings)) { 83 | codec.encode(jsonWriter, val, EncoderContext.builder().build()); 84 | writer.flush(); 85 | 86 | return writer.toString(); 87 | } catch (IOException e) { 88 | throw new RuntimeException(e); 89 | } 90 | } 91 | 92 | public static String toString(Codec codec, T val) { 93 | return toString(codec, val, JSON_WRITER_SETTINGS); 94 | } 95 | 96 | public static BsonDocument toBsonDocument(Codec codec, T val) { 97 | BsonDocument doc = new BsonDocument(); 98 | try (BsonDocumentWriter writer = new BsonDocumentWriter(doc); ) { 99 | codec.encode(writer, val, EncoderContext.builder().build()); 100 | writer.flush(); 101 | } 102 | return doc; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/mongodb/jdbc/utils/X509Authentication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.utils; 18 | 19 | import com.mongodb.jdbc.logging.MongoLogger; 20 | import java.io.FileReader; 21 | import java.security.*; 22 | import java.security.cert.Certificate; 23 | import java.util.logging.Level; 24 | import javax.net.ssl.KeyManagerFactory; 25 | import javax.net.ssl.SSLContext; 26 | import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 27 | import org.bouncycastle.cert.X509CertificateHolder; 28 | import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; 29 | import org.bouncycastle.jce.provider.BouncyCastleProvider; 30 | import org.bouncycastle.openssl.PEMParser; 31 | import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; 32 | import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; 33 | import org.bouncycastle.pkcs.jcajce.JcePKCSPBEInputDecryptorProviderBuilder; 34 | 35 | public class X509Authentication { 36 | private static final BouncyCastleProvider BC_PROVIDER = new BouncyCastleProvider(); 37 | private final MongoLogger logger; 38 | 39 | public X509Authentication(MongoLogger logger) { 40 | this.logger = logger; 41 | } 42 | 43 | public void configureX509Authentication( 44 | com.mongodb.MongoClientSettings.Builder settingsBuilder, 45 | String pemPath, 46 | char[] passphrase) { 47 | 48 | logger.log(Level.FINE, "Using client certificate for X509 authentication: " + pemPath); 49 | if (passphrase != null && passphrase.length > 0) { 50 | logger.log(Level.FINE, "Client certificate passphrase has been specified"); 51 | } 52 | try { 53 | SSLContext sslContext = createSSLContext(pemPath, passphrase); 54 | 55 | settingsBuilder.applyToSslSettings( 56 | sslSettings -> { 57 | sslSettings.enabled(true); 58 | sslSettings.context(sslContext); 59 | }); 60 | } catch (Exception e) { 61 | throw new RuntimeException("SSL setup failed", e); 62 | } 63 | } 64 | 65 | private SSLContext createSSLContext(String pemPath, char[] passphrase) throws Exception { 66 | PrivateKey privateKey = null; 67 | Certificate cert = null; 68 | 69 | try (PEMParser pemParser = new PEMParser(new FileReader(pemPath))) { 70 | Object pemObj; 71 | 72 | // Iterate through PEM objects found in the PEM file and process them based on type: 73 | // - Encrypted/unencrypted private keys 74 | // - X.509 certificates 75 | while ((pemObj = pemParser.readObject()) != null) { 76 | try { 77 | if (passphrase != null 78 | && passphrase.length > 0 79 | && pemObj instanceof PKCS8EncryptedPrivateKeyInfo) { 80 | privateKey = 81 | new JcaPEMKeyConverter() 82 | .setProvider(BC_PROVIDER) 83 | .getPrivateKey( 84 | ((PKCS8EncryptedPrivateKeyInfo) pemObj) 85 | .decryptPrivateKeyInfo( 86 | new JcePKCSPBEInputDecryptorProviderBuilder() 87 | .setProvider(BC_PROVIDER) 88 | .build(passphrase))); 89 | } else if (pemObj instanceof PrivateKeyInfo) { 90 | privateKey = 91 | new JcaPEMKeyConverter() 92 | .setProvider(BC_PROVIDER) 93 | .getPrivateKey((PrivateKeyInfo) pemObj); 94 | } 95 | } catch (Exception e) { 96 | throw new GeneralSecurityException( 97 | "Failed to process private key from PEM file", e); 98 | } 99 | 100 | if (pemObj instanceof X509CertificateHolder) { 101 | cert = 102 | new JcaX509CertificateConverter() 103 | .setProvider(BC_PROVIDER) 104 | .getCertificate((X509CertificateHolder) pemObj); 105 | } 106 | } 107 | } 108 | 109 | if (privateKey == null) { 110 | throw new IllegalStateException( 111 | "Failed to read private key from PEM file (encrypted or unencrypted)"); 112 | } 113 | if (cert == null) { 114 | throw new IllegalStateException("Failed to read certificate from PEM file"); 115 | } 116 | 117 | return createSSLContextFromKeyAndCert(privateKey, cert); 118 | } 119 | 120 | private SSLContext createSSLContextFromKeyAndCert(PrivateKey privateKey, Certificate cert) 121 | throws Exception { 122 | KeyStore keyStore = KeyStore.getInstance("PKCS12"); 123 | keyStore.load(null, null); 124 | keyStore.setKeyEntry("mongodb-cert", privateKey, null, new Certificate[] {cert}); 125 | 126 | KeyManagerFactory kmf = 127 | KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 128 | 129 | // Passphrase not needed for in memory keystore 130 | kmf.init(keyStore, null); 131 | 132 | SSLContext sslContext = SSLContext.getInstance("TLS"); 133 | // Initialize sslContext and use default trust managers 134 | sslContext.init(kmf.getKeyManagers(), null, new SecureRandom()); 135 | 136 | return sslContext; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/java.sql.Driver: -------------------------------------------------------------------------------- 1 | com.mongodb.jdbc.MongoDriver 2 | -------------------------------------------------------------------------------- /src/test/java/com/mongodb/jdbc/BsonTypeInfoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_ARRAY; 20 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_BINDATA; 21 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_BOOL; 22 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_DATE; 23 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_DBPOINTER; 24 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_DECIMAL; 25 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_DOUBLE; 26 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_INT; 27 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_JAVASCRIPT; 28 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_JAVASCRIPTWITHSCOPE; 29 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_LONG; 30 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_MAXKEY; 31 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_MINKEY; 32 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_NULL; 33 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_OBJECT; 34 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_OBJECTID; 35 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_REGEX; 36 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_STRING; 37 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_SYMBOL; 38 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_TIMESTAMP; 39 | import static com.mongodb.jdbc.BsonTypeInfo.BSON_UNDEFINED; 40 | import static com.mongodb.jdbc.BsonTypeInfo.getBsonTypeInfoByName; 41 | import static com.mongodb.jdbc.BsonTypeInfo.getBsonTypeInfoFromBsonValue; 42 | import static org.junit.jupiter.api.Assertions.assertEquals; 43 | import static org.junit.jupiter.api.Assertions.assertThrows; 44 | 45 | import java.nio.charset.StandardCharsets; 46 | import java.sql.SQLException; 47 | import org.bson.BsonArray; 48 | import org.bson.BsonBinary; 49 | import org.bson.BsonBoolean; 50 | import org.bson.BsonDateTime; 51 | import org.bson.BsonDbPointer; 52 | import org.bson.BsonDecimal128; 53 | import org.bson.BsonDocument; 54 | import org.bson.BsonDouble; 55 | import org.bson.BsonInt32; 56 | import org.bson.BsonInt64; 57 | import org.bson.BsonJavaScript; 58 | import org.bson.BsonJavaScriptWithScope; 59 | import org.bson.BsonMaxKey; 60 | import org.bson.BsonMinKey; 61 | import org.bson.BsonNull; 62 | import org.bson.BsonObjectId; 63 | import org.bson.BsonRegularExpression; 64 | import org.bson.BsonString; 65 | import org.bson.BsonSymbol; 66 | import org.bson.BsonTimestamp; 67 | import org.bson.BsonUndefined; 68 | import org.bson.types.Decimal128; 69 | import org.bson.types.ObjectId; 70 | import org.junit.jupiter.api.Test; 71 | 72 | public class BsonTypeInfoTest { 73 | @Test 74 | void testGetBsonTypeInfoByName() throws SQLException { 75 | assertEquals(BSON_ARRAY, getBsonTypeInfoByName("array")); 76 | assertEquals(BSON_BOOL, getBsonTypeInfoByName("bool")); 77 | assertEquals(BSON_BINDATA, getBsonTypeInfoByName("binData")); 78 | assertEquals(BSON_DATE, getBsonTypeInfoByName("date")); 79 | assertEquals(BSON_DBPOINTER, getBsonTypeInfoByName("dbPointer")); 80 | assertEquals(BSON_DECIMAL, getBsonTypeInfoByName("decimal")); 81 | assertEquals(BSON_DOUBLE, getBsonTypeInfoByName("double")); 82 | assertEquals(BSON_INT, getBsonTypeInfoByName("int")); 83 | assertEquals(BSON_JAVASCRIPT, getBsonTypeInfoByName("javascript")); 84 | assertEquals(BSON_JAVASCRIPTWITHSCOPE, getBsonTypeInfoByName("javascriptWithScope")); 85 | assertEquals(BSON_LONG, getBsonTypeInfoByName("long")); 86 | assertEquals(BSON_MAXKEY, getBsonTypeInfoByName("maxKey")); 87 | assertEquals(BSON_MINKEY, getBsonTypeInfoByName("minKey")); 88 | assertEquals(BSON_NULL, getBsonTypeInfoByName("null")); 89 | assertEquals(BSON_OBJECT, getBsonTypeInfoByName("object")); 90 | assertEquals(BSON_OBJECTID, getBsonTypeInfoByName("objectId")); 91 | assertEquals(BSON_REGEX, getBsonTypeInfoByName("regex")); 92 | assertEquals(BSON_STRING, getBsonTypeInfoByName("string")); 93 | assertEquals(BSON_SYMBOL, getBsonTypeInfoByName("symbol")); 94 | assertEquals(BSON_TIMESTAMP, getBsonTypeInfoByName("timestamp")); 95 | assertEquals(BSON_UNDEFINED, getBsonTypeInfoByName("undefined")); 96 | 97 | // Test invalid type name 98 | assertThrows( 99 | SQLException.class, 100 | () -> getBsonTypeInfoByName("invalid"), 101 | "invalid BSON type name expected to throw exception"); 102 | } 103 | 104 | @Test 105 | void testGetBsonTypeInfoFromBsonValue() throws SQLException { 106 | assertEquals(BSON_ARRAY, getBsonTypeInfoFromBsonValue(new BsonArray())); 107 | assertEquals(BSON_BOOL, getBsonTypeInfoFromBsonValue(new BsonBoolean(true))); 108 | assertEquals( 109 | BSON_BINDATA, 110 | getBsonTypeInfoFromBsonValue(new BsonBinary("a".getBytes(StandardCharsets.UTF_8)))); 111 | assertEquals(BSON_DATE, getBsonTypeInfoFromBsonValue(new BsonDateTime(1))); 112 | assertEquals( 113 | BSON_DBPOINTER, 114 | getBsonTypeInfoFromBsonValue(new BsonDbPointer("test", new ObjectId()))); 115 | assertEquals( 116 | BSON_DECIMAL, getBsonTypeInfoFromBsonValue(new BsonDecimal128(new Decimal128(1)))); 117 | assertEquals(BSON_DOUBLE, getBsonTypeInfoFromBsonValue(new BsonDouble(2.2))); 118 | assertEquals(BSON_INT, getBsonTypeInfoFromBsonValue(new BsonInt32(1))); 119 | assertEquals(BSON_JAVASCRIPT, getBsonTypeInfoFromBsonValue(new BsonJavaScript(""))); 120 | assertEquals( 121 | BSON_JAVASCRIPTWITHSCOPE, 122 | getBsonTypeInfoFromBsonValue(new BsonJavaScriptWithScope("", new BsonDocument()))); 123 | assertEquals(BSON_LONG, getBsonTypeInfoFromBsonValue(new BsonInt64(1))); 124 | assertEquals(BSON_MAXKEY, getBsonTypeInfoFromBsonValue(new BsonMaxKey())); 125 | assertEquals(BSON_MINKEY, getBsonTypeInfoFromBsonValue(new BsonMinKey())); 126 | assertEquals(BSON_NULL, getBsonTypeInfoFromBsonValue(new BsonNull())); 127 | assertEquals(BSON_OBJECTID, getBsonTypeInfoFromBsonValue(new BsonObjectId())); 128 | assertEquals(BSON_REGEX, getBsonTypeInfoFromBsonValue(new BsonRegularExpression(""))); 129 | assertEquals(BSON_STRING, getBsonTypeInfoFromBsonValue(new BsonString(""))); 130 | assertEquals(BSON_SYMBOL, getBsonTypeInfoFromBsonValue(new BsonSymbol(""))); 131 | assertEquals(BSON_TIMESTAMP, getBsonTypeInfoFromBsonValue(new BsonTimestamp())); 132 | assertEquals(BSON_UNDEFINED, getBsonTypeInfoFromBsonValue(new BsonUndefined())); 133 | assertEquals(BSON_OBJECT, getBsonTypeInfoFromBsonValue(new BsonDocument())); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/test/java/com/mongodb/jdbc/BsonUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc; 18 | 19 | import static org.junit.jupiter.api.Assertions.*; 20 | 21 | import com.mongodb.jdbc.utils.BsonUtils; 22 | import org.bson.BsonDocument; 23 | import org.bson.BsonInt32; 24 | import org.bson.BsonString; 25 | import org.junit.jupiter.api.Test; 26 | 27 | class BsonUtilsTest { 28 | 29 | @Test 30 | void testSerializeDeserialize() throws MongoSerializationException { 31 | BsonDocument originalDoc = 32 | new BsonDocument("name", new BsonString("Test")) 33 | .append("value", new BsonInt32(123)) 34 | .append("nested", new BsonDocument("key", new BsonString("value"))); 35 | 36 | byte[] serialized = BsonUtils.serialize(originalDoc); 37 | assertNotNull(serialized, "Serialized byte array should not be null"); 38 | assertTrue(serialized.length > 0, "Serialized byte array should have content"); 39 | 40 | BsonDocument deserializedDoc = BsonUtils.deserialize(serialized); 41 | assertNotNull(deserializedDoc, "Deserialized document should not be null"); 42 | assertEquals( 43 | originalDoc, 44 | deserializedDoc, 45 | "Original and deserialized documents should be equal"); 46 | } 47 | 48 | @Test 49 | void testSerializeNullDocument() { 50 | assertThrows( 51 | MongoSerializationException.class, 52 | () -> BsonUtils.serialize(null), 53 | "Serializing a null document should throw MongoSerializationException"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/mongodb/jdbc/MongoJsonSchemaTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022-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 | package com.mongodb.jdbc; 18 | 19 | import static org.bson.codecs.configuration.CodecRegistries.fromProviders; 20 | import static org.junit.jupiter.api.Assertions.assertEquals; 21 | import static org.junit.jupiter.api.Assertions.assertTrue; 22 | 23 | import java.io.File; 24 | import java.io.FileNotFoundException; 25 | import java.io.FileReader; 26 | import java.io.StringReader; 27 | import java.sql.SQLException; 28 | import java.util.ArrayList; 29 | import java.util.Collection; 30 | import java.util.List; 31 | import org.bson.BsonDocument; 32 | import org.bson.BsonDocumentWriter; 33 | import org.bson.BsonWriter; 34 | import org.bson.codecs.BsonValueCodecProvider; 35 | import org.bson.codecs.Codec; 36 | import org.bson.codecs.DecoderContext; 37 | import org.bson.codecs.EncoderContext; 38 | import org.bson.codecs.ValueCodecProvider; 39 | import org.bson.codecs.configuration.CodecRegistry; 40 | import org.bson.codecs.pojo.PojoCodecProvider; 41 | import org.bson.json.JsonReader; 42 | import org.bson.json.JsonWriterSettings; 43 | import org.junit.jupiter.api.DynamicTest; 44 | import org.junit.jupiter.api.Test; 45 | import org.junit.jupiter.api.TestFactory; 46 | 47 | /** Test the deserialization and simplifacation of JsonSchema returned by a sqlgetschema command. */ 48 | public class MongoJsonSchemaTest { 49 | static final CodecRegistry REGISTRY = 50 | fromProviders( 51 | new BsonValueCodecProvider(), 52 | new ValueCodecProvider(), 53 | PojoCodecProvider.builder().automatic(true).build()); 54 | static final Codec MONGO_JSON_SCHEMA_CODEC = 55 | REGISTRY.get(MongoJsonSchema.class); 56 | static final Codec MONGO_VERSIONED_JSON_SCHEMA_CODEC = 57 | REGISTRY.get(MongoVersionedJsonSchema.class); 58 | static final Codec JSON_SCHEMA_CODEC = REGISTRY.get(JsonSchema.class); 59 | 60 | @TestFactory 61 | Collection runIntegrationTests() throws SQLException { 62 | ClassLoader classLoader = getClass().getClassLoader(); 63 | File input = new File(classLoader.getResource("mongoJsonSchemaTest/input").getFile()); 64 | assertTrue(input.isDirectory(), input.getPath() + " is not a directory."); 65 | File expectedOutput = 66 | new File(classLoader.getResource("mongoJsonSchemaTest/expectedOutput").getFile()); 67 | assertTrue(expectedOutput.isDirectory(), expectedOutput.getPath() + " is not a directory."); 68 | List dynamicTests = new ArrayList<>(); 69 | for (File testEntry : input.listFiles()) { 70 | File output = new File(expectedOutput.getAbsoluteFile() + "/" + testEntry.getName()); 71 | dynamicTests.add( 72 | DynamicTest.dynamicTest( 73 | testEntry.getName(), 74 | () -> { 75 | System.out.println( 76 | "Comparing " 77 | + testEntry.getName() 78 | + " with " 79 | + output.getName()); 80 | testDeserializeAndSimplifySchema(testEntry, output); 81 | })); 82 | } 83 | return dynamicTests; 84 | } 85 | 86 | @Test 87 | public void testEmptySchema() throws Exception { 88 | JsonWriterSettings settings = JsonWriterSettings.builder().indent(true).build(); 89 | 90 | // Deserializes empty documents 91 | Codec[] schemaCodecs = { 92 | JSON_SCHEMA_CODEC, MONGO_JSON_SCHEMA_CODEC, MONGO_VERSIONED_JSON_SCHEMA_CODEC 93 | }; 94 | for (Codec codec : schemaCodecs) { 95 | Class encoderClass = codec.getEncoderClass(); 96 | // Encode an "emtpy" object using the default constructor with no arguments for the class associated to the codec 97 | BsonDocument docFromEmptyObj = new BsonDocument(); 98 | BsonWriter writer = new BsonDocumentWriter(docFromEmptyObj); 99 | codec.encode( 100 | writer, 101 | encoderClass.getConstructor().newInstance(), 102 | EncoderContext.builder().build()); 103 | writer.flush(); 104 | 105 | try (JsonReader reader = new JsonReader(new StringReader("{}"))) { 106 | // Decode the empty document 107 | Object encodedObj = codec.decode(reader, DecoderContext.builder().build()); 108 | assertEquals(encoderClass, encodedObj.getClass()); 109 | 110 | // Re-encode the decoded schema and check its content, verify that it matches a new "empty" instance 111 | BsonDocument docFromDecodedEmptyJson = new BsonDocument(); 112 | writer = new BsonDocumentWriter(docFromDecodedEmptyJson); 113 | codec.encode(writer, encodedObj, EncoderContext.builder().build()); 114 | writer.flush(); 115 | 116 | assertEquals( 117 | docFromEmptyObj.toJson(settings), docFromDecodedEmptyJson.toJson(settings)); 118 | } 119 | } 120 | } 121 | 122 | private void testDeserializeAndSimplifySchema(File input, File output) 123 | throws FileNotFoundException { 124 | JsonSchema in_schema = null; 125 | MongoJsonSchema out_schema = null; 126 | // Decode the input 127 | try (JsonReader reader = new JsonReader(new FileReader(input))) { 128 | in_schema = JSON_SCHEMA_CODEC.decode(reader, DecoderContext.builder().build()); 129 | } 130 | // Decode the expected out as jsonSchema to make sure that no simplification is happening 131 | // except the transformation from String to Set if necessary for bsonType. 132 | try (JsonReader reader = new JsonReader(new FileReader(output))) { 133 | out_schema = MONGO_JSON_SCHEMA_CODEC.decode(reader, DecoderContext.builder().build()); 134 | } 135 | 136 | // Transform the mongoJsonSchema to a JsonSchema for comparing each other 137 | MongoJsonSchema simplifiedSchema = MongoJsonSchema.toSimplifiedMongoJsonSchema(in_schema); 138 | 139 | assertEquals(simplifiedSchema, out_schema); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/test/java/com/mongodb/jdbc/MongoSQLTranslateLibTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc; 18 | 19 | import static org.junit.jupiter.api.Assertions.*; 20 | 21 | import com.mongodb.jdbc.logging.MongoLogger; 22 | import com.mongodb.jdbc.mongosql.GetMongosqlTranslateVersionResult; 23 | import com.mongodb.jdbc.mongosql.MongoSQLException; 24 | import com.mongodb.jdbc.mongosql.MongoSQLTranslate; 25 | import java.lang.reflect.Field; 26 | import java.lang.reflect.Method; 27 | import java.util.logging.Logger; 28 | import org.junit.jupiter.api.BeforeEach; 29 | import org.junit.jupiter.api.Test; 30 | 31 | public class MongoSQLTranslateLibTest { 32 | 33 | /** Helper function to call the runCommand endpoint of the translation library. */ 34 | private static void testRunCommand() throws MongoSQLException, MongoSerializationException { 35 | MongoLogger mongoLogger = new MongoLogger(Logger.getLogger("Logger"), 1); 36 | MongoSQLTranslate mongosqlTranslate = new MongoSQLTranslate(mongoLogger); 37 | 38 | GetMongosqlTranslateVersionResult result = mongosqlTranslate.getMongosqlTranslateVersion(); 39 | 40 | assertNotNull(result); 41 | assertNotNull(result.version); 42 | } 43 | 44 | @BeforeEach 45 | void setup() throws Exception { 46 | // Reset the mongoSqlTranslateLibraryLoaded flag to false before each test case. 47 | // This ensures that the flag starts with a known value at the start of the test 48 | // as it can be set during the static initialization or test interference. 49 | Field mongoSqlTranslateLibraryLoadedField = 50 | MongoDriver.class.getDeclaredField("mongoSqlTranslateLibraryLoaded"); 51 | mongoSqlTranslateLibraryLoadedField.setAccessible(true); 52 | mongoSqlTranslateLibraryLoadedField.set(null, false); 53 | 54 | Field mongoSqlTranslateLibraryPathField = 55 | MongoDriver.class.getDeclaredField("mongoSqlTranslateLibraryPath"); 56 | mongoSqlTranslateLibraryPathField.setAccessible(true); 57 | mongoSqlTranslateLibraryPathField.set(null, null); 58 | 59 | Field mongoSqlTranslateLibraryLoadingError = 60 | MongoDriver.class.getDeclaredField("mongoSqlTranslateLibraryLoadingError"); 61 | mongoSqlTranslateLibraryPathField.setAccessible(true); 62 | mongoSqlTranslateLibraryPathField.set(null, null); 63 | } 64 | 65 | @Test 66 | void testLibraryLoadingFromDriverPath() throws Exception { 67 | assertNull( 68 | System.getenv(MongoDriver.MONGOSQL_TRANSLATE_PATH), 69 | "MONGOSQL_TRANSLATE_PATH should not be set"); 70 | 71 | Method initMethod = MongoDriver.class.getDeclaredMethod("loadMongoSqlTranslateLibrary"); 72 | initMethod.setAccessible(true); 73 | initMethod.invoke(null); 74 | 75 | assertTrue( 76 | MongoDriver.isMongoSqlTranslateLibraryLoaded(), 77 | "Library should be loaded successfully from the driver directory"); 78 | String tempDir = System.getProperty("java.io.tmpdir"); 79 | assertTrue( 80 | MongoDriver.getMongoSqlTranslateLibraryPath().contains(tempDir), 81 | "Expected library path to contain '" 82 | + tempDir 83 | + "' but didn't. Actual path is " 84 | + MongoDriver.getMongoSqlTranslateLibraryPath()); 85 | 86 | // The library was loaded successfully. Now, let's make sure that we can call the runCommand endpoint. 87 | testRunCommand(); 88 | } 89 | 90 | @Test 91 | void testLibraryLoadingWithEnvironmentVariable() throws Exception { 92 | String envPath = System.getenv(MongoDriver.MONGOSQL_TRANSLATE_PATH); 93 | assertNotNull(envPath, "MONGOSQL_TRANSLATE_PATH should be set"); 94 | 95 | // Test loadMongoSqlTranslateLibrary, with Environment variable set it should find the library 96 | Method initMethod = MongoDriver.class.getDeclaredMethod("loadMongoSqlTranslateLibrary"); 97 | initMethod.setAccessible(true); 98 | initMethod.invoke(null); 99 | 100 | assertNull(MongoDriver.getMongoSqlTranslateLibraryLoadError()); 101 | 102 | assertTrue( 103 | MongoDriver.isMongoSqlTranslateLibraryLoaded(), 104 | "Library should be loaded when MONGOSQL_TRANSLATE_PATH is set"); 105 | 106 | assertTrue( 107 | MongoDriver.getMongoSqlTranslateLibraryPath() 108 | .contains("resources/MongoSqlLibraryTest"), 109 | "Expected library path to contain 'resources/MongoSqlLibraryTest' but didn't. Actual path is " 110 | + MongoDriver.getMongoSqlTranslateLibraryPath()); 111 | 112 | // The library was loaded successfully. Now, let's make sure that we can call the runCommand endpoint. 113 | testRunCommand(); 114 | } 115 | 116 | @Test 117 | void testLibraryLoadingWithInvalidEnvironmentVariableFallback() throws Exception { 118 | String envPath = System.getenv(MongoDriver.MONGOSQL_TRANSLATE_PATH); 119 | assertNotNull(envPath, "MONGOSQL_TRANSLATE_PATH should be set"); 120 | 121 | // Test loadMongoSqlTranslateLibrary, with invalid Environment variable set should fallback to driver directory 122 | Method initMethod = MongoDriver.class.getDeclaredMethod("loadMongoSqlTranslateLibrary"); 123 | initMethod.setAccessible(true); 124 | initMethod.invoke(null); 125 | 126 | assertNotNull(MongoDriver.getMongoSqlTranslateLibraryLoadError()); 127 | 128 | assertTrue( 129 | MongoDriver.getMongoSqlTranslateLibraryLoadError() 130 | .getMessage() 131 | .contains("java.lang.UnsatisfiedLinkError: Can't load library"), 132 | "Expected error to be a loading error but is " 133 | + MongoDriver.getMongoSqlTranslateLibraryLoadError().getMessage()); 134 | 135 | // The library must be loaded and it should be the one from inside the driver. 136 | assertTrue( 137 | MongoDriver.isMongoSqlTranslateLibraryLoaded(), 138 | "Library should be loaded successfully from the driver directory"); 139 | String tempDir = System.getProperty("java.io.tmpdir"); 140 | assertTrue( 141 | MongoDriver.getMongoSqlTranslateLibraryPath().contains(tempDir), 142 | "Expected library path to contain '" 143 | + tempDir 144 | + "' but didn't. Actual path is " 145 | + MongoDriver.getMongoSqlTranslateLibraryPath()); 146 | 147 | // The library was loaded successfully. Now, let's make sure that we can call the runCommand endpoint. 148 | testRunCommand(); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/test/java/com/mongodb/jdbc/oidc/RFC8252HttpServerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024-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 | package com.mongodb.jdbc.oidc; 18 | 19 | import static org.junit.jupiter.api.Assertions.*; 20 | 21 | import java.io.IOException; 22 | import java.net.HttpURLConnection; 23 | import java.net.URL; 24 | import org.junit.jupiter.api.AfterEach; 25 | import org.junit.jupiter.api.BeforeEach; 26 | import org.junit.jupiter.api.Test; 27 | 28 | class RFC8252HttpServerTest { 29 | private RFC8252HttpServer server; 30 | 31 | @BeforeEach 32 | void setUp() throws IOException { 33 | server = new RFC8252HttpServer(); 34 | server.start(); 35 | } 36 | 37 | @AfterEach 38 | void tearDown() { 39 | server.stop(); 40 | } 41 | 42 | @Test 43 | void testAcceptedResponse() throws OidcTimeoutException, IOException, InterruptedException { 44 | URL url = 45 | new URL( 46 | "http://localhost:" 47 | + RFC8252HttpServer.DEFAULT_REDIRECT_PORT 48 | + "/callback?code=1234&state=foo"); 49 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 50 | connection.setRequestMethod("GET"); 51 | connection.connect(); 52 | 53 | assertEquals(200, connection.getResponseCode()); 54 | assertNull(connection.getHeaderField("Location")); 55 | 56 | OidcResponse oidcResponse = server.getOidcResponse(); 57 | assertEquals("1234", oidcResponse.getCode()); 58 | assertEquals("foo", oidcResponse.getState()); 59 | } 60 | 61 | @Test 62 | void testErrorResponse() throws OidcTimeoutException, IOException, InterruptedException { 63 | URL url = 64 | new URL( 65 | "http://localhost:" 66 | + RFC8252HttpServer.DEFAULT_REDIRECT_PORT 67 | + "/callback?error=1234&error_description=foo"); 68 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 69 | connection.setRequestMethod("GET"); 70 | connection.connect(); 71 | 72 | assertEquals(400, connection.getResponseCode()); 73 | 74 | OidcResponse oidcResponse = server.getOidcResponse(); 75 | assertEquals("1234", oidcResponse.getError()); 76 | assertEquals("foo", oidcResponse.getErrorDescription()); 77 | } 78 | 79 | @Test 80 | void testMissingParameters() throws OidcTimeoutException, IOException, InterruptedException { 81 | URL url = 82 | new URL( 83 | "http://localhost:" 84 | + RFC8252HttpServer.DEFAULT_REDIRECT_PORT 85 | + "/callback"); 86 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 87 | connection.setRequestMethod("GET"); 88 | connection.connect(); 89 | 90 | assertEquals(404, connection.getResponseCode()); 91 | 92 | OidcResponse oidcResponse = server.getOidcResponse(); 93 | assertNull(oidcResponse.getCode()); 94 | assertNull(oidcResponse.getState()); 95 | assert (oidcResponse.getError().equals("Not found")); 96 | assert (oidcResponse.getErrorDescription().equals("Not found. Parameters: No parameters")); 97 | } 98 | 99 | @Test 100 | void testRedirectUnknownParameters() 101 | throws OidcTimeoutException, IOException, InterruptedException { 102 | URL url = 103 | new URL( 104 | "http://localhost:" 105 | + RFC8252HttpServer.DEFAULT_REDIRECT_PORT 106 | + "/redirect?foo=bar"); 107 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 108 | connection.setRequestMethod("GET"); 109 | connection.connect(); 110 | 111 | assertEquals(404, connection.getResponseCode()); 112 | 113 | OidcResponse oidcResponse = server.getOidcResponse(); 114 | assertNull(oidcResponse.getCode()); 115 | assertNull(oidcResponse.getState()); 116 | assert (oidcResponse.getError().equals("Not found")); 117 | assert (oidcResponse.getErrorDescription().equals("Not found. Parameters: foo=bar")); 118 | } 119 | 120 | @Test 121 | void testAmpersandInParameterValue() 122 | throws OidcTimeoutException, IOException, InterruptedException { 123 | URL url = 124 | new URL( 125 | "http://localhost:" 126 | + RFC8252HttpServer.DEFAULT_REDIRECT_PORT 127 | + "/callback?code=1234&state=foo%26bar"); 128 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 129 | connection.setRequestMethod("GET"); 130 | connection.connect(); 131 | 132 | assertEquals(200, connection.getResponseCode()); 133 | OidcResponse oidcResponse = server.getOidcResponse(); 134 | assertEquals("1234", oidcResponse.getCode()); 135 | assertEquals("foo&bar", oidcResponse.getState()); 136 | } 137 | 138 | @Test 139 | void testEqualsInParameterValue() 140 | throws OidcTimeoutException, IOException, InterruptedException { 141 | URL url = 142 | new URL( 143 | "http://localhost:" 144 | + RFC8252HttpServer.DEFAULT_REDIRECT_PORT 145 | + "/callback?code=1234&state=foo%3Dbar"); 146 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 147 | connection.setRequestMethod("GET"); 148 | connection.connect(); 149 | 150 | assertEquals(200, connection.getResponseCode()); 151 | OidcResponse oidcResponse = server.getOidcResponse(); 152 | assertEquals("1234", oidcResponse.getCode()); 153 | assertEquals("foo=bar", oidcResponse.getState()); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/test/resources/MongoSqlLibraryTest/libmongosqltranslate.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mongodb/mongo-jdbc-driver/db847ccea7131cb0bae802a3b3313731a9cf6c2f/src/test/resources/MongoSqlLibraryTest/libmongosqltranslate.so -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/bsonTypeAsSetAndAnyOfToMergeWith.json: -------------------------------------------------------------------------------- 1 | { 2 | "additionalProperties": false, 3 | "bsonType": "object", 4 | "properties": { 5 | "bar": { 6 | "additionalProperties": false, 7 | "anyOf": [ 8 | { 9 | "additionalProperties": false, 10 | "bsonType": "object", 11 | "properties": { 12 | "a": { 13 | "bsonType": "string" 14 | } 15 | }, 16 | "required": [ 17 | "a" 18 | ] 19 | }, 20 | { 21 | "bsonType": "bool" 22 | }, 23 | { 24 | "bsonType": "int" 25 | }, 26 | { 27 | "additionalProperties": false, 28 | "bsonType": "object", 29 | "properties": { 30 | "a": { 31 | "bsonType": "int" 32 | } 33 | }, 34 | "required": [ 35 | "a" 36 | ] 37 | }, 38 | { 39 | "bsonType": "string" 40 | }, 41 | { 42 | "bsonType": "null" 43 | }, 44 | { 45 | "bsonType": "bool", 46 | "additionalProperties": true 47 | } 48 | ] 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/bsonTypeAsSetOfOneElem.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "bsonType": "int" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/bsonTypeAsSetOfSimpleTypes.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "anyOf": [ 6 | {"bsonType": "int"}, 7 | {"bsonType": "string"}, 8 | { 9 | "bsonType": "double" 10 | } 11 | ] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/bsonTypeAsSingleType.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "bsonType": "int" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/flattenAnyOf.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "anyOf": [ 4 | { 5 | "bsonType": "symbol" 6 | }, 7 | { 8 | "bsonType": "decimal" 9 | }, 10 | { 11 | "bsonType": "regex" 12 | }, 13 | { 14 | "bsonType": "objectId" 15 | }, 16 | { 17 | "bsonType": "date" 18 | }, 19 | { 20 | "bsonType": "double" 21 | } 22 | ], 23 | "properties": { 24 | "bar": { 25 | "anyOf": [ 26 | {"bsonType": "null"}, 27 | { 28 | "bsonType": "bool", 29 | "additionalProperties": false 30 | }, 31 | {"bsonType": "int"}, 32 | { 33 | "bsonType": "bool", 34 | "additionalProperties": true 35 | }, 36 | { 37 | "bsonType": "string" 38 | } 39 | ] 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/flattenedAnyOfReducedToOneType.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "bsonType": "array", 6 | "items":{}, 7 | "additionalProperties": true 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/polymorphicAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | {"bsonType": "object", 2 | "properties": { 3 | "bar": { 4 | "bsonType": "object", 5 | "properties": { 6 | "a": { 7 | "bsonType": "object", 8 | "additionalProperties": true 9 | }, 10 | "b": { 11 | "bsonType": "boolean", 12 | "additionalProperties": false 13 | }, 14 | "c": { 15 | "bsonType": "string", 16 | "additionalProperties": true 17 | }, 18 | "d": { 19 | "bsonType": "date" 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/polymorphicItems.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType":"object", 3 | "properties":{ 4 | "bar":{ 5 | "bsonType":"object", 6 | "properties":{ 7 | "a":{ 8 | "bsonType":"array", 9 | "items":{} 10 | }, 11 | "b":{ 12 | "bsonType":"array", 13 | "items":{}, 14 | "additionalProperties":false 15 | }, 16 | "c":{ 17 | "bsonType":"objectId" 18 | } 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/expectedOutput/simpleSchema.json: -------------------------------------------------------------------------------- 1 | {"bsonType": "object", 2 | "properties": { 3 | "bar": { 4 | "bsonType": "object", 5 | "properties": { 6 | "a": {}, 7 | "b": {"anyOf": []}, 8 | "c": {"bsonType": "string"}, 9 | "e": {"bsonType": "int"}, 10 | "f": {"bsonType": "double"}, 11 | "g": {"bsonType": "long"}, 12 | "h": {"bsonType": "decimal"}, 13 | "i": {"bsonType": "binData"}, 14 | "j": {"bsonType": "objectId"}, 15 | "k": {"bsonType": "bool"}, 16 | "l": {"bsonType": "date"}, 17 | "m": {"bsonType": "null"}, 18 | "n": {"bsonType": "regex"}, 19 | "o": {"bsonType": "dbPointer"}, 20 | "p": {"bsonType": "javascript"}, 21 | "q": {"bsonType": "symbol"}, 22 | "r": {"bsonType": "javascriptWithScope"}, 23 | "s": {"bsonType": "timestamp"}, 24 | "t": {"bsonType": "minKey"}, 25 | "u": {"bsonType": "maxKey"}, 26 | "v": { 27 | "bsonType": "array", 28 | "items":{} 29 | }, 30 | "w": { 31 | "anyOf": [ 32 | {"bsonType": "null"}, 33 | { 34 | "bsonType": "object", 35 | "properties": {}, 36 | "required": [], 37 | "additionalProperties": true 38 | } 39 | ] 40 | }, 41 | "x": { 42 | "bsonType": "string" 43 | }, 44 | "y": { 45 | "anyOf": [ 46 | {"bsonType": "string"}, 47 | {"bsonType": "int"} 48 | ] 49 | } 50 | }, 51 | "required": ["a", "b", "c"], 52 | "additionalProperties": false 53 | } 54 | }, 55 | "required": [], 56 | "additionalProperties": false 57 | } 58 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/bsonTypeAsSetAndAnyOfToMergeWith.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "bsonType": [ 6 | "int", 7 | "object", 8 | "string", 9 | "bool", 10 | "null" 11 | ], 12 | "anyOf": [ 13 | { 14 | "bsonType": "null" 15 | }, 16 | { 17 | "bsonType": "bool", 18 | "additionalProperties": true 19 | }, 20 | { 21 | "bsonType": "object", 22 | "properties": { 23 | "a": { "bsonType": "string" } 24 | }, 25 | "required": [ 26 | "a" 27 | ] 28 | } 29 | ], 30 | "properties": { 31 | "a": {"bsonType": "int"} 32 | }, 33 | "required": [ 34 | "a" 35 | ] 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/bsonTypeAsSetOfOneElem.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "bsonType": ["int"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/bsonTypeAsSetOfSimpleTypes.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "bsonType": [ 6 | "int", 7 | "string", 8 | "double" 9 | ] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/bsonTypeAsSingleType.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "bsonType": "int" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/flattenAnyOf.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "anyOf": [ 4 | {"bsonType": "double"}, 5 | { 6 | "bsonType": "date" 7 | }, 8 | { 9 | "anyOf": [ 10 | {"bsonType": "regex"}, 11 | { 12 | "anyOf": [ 13 | { 14 | "bsonType": "symbol" 15 | }, 16 | { 17 | "bsonType": "objectId" 18 | }, 19 | { 20 | "bsonType": "decimal" 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | ], 27 | "properties": { 28 | "bar": { 29 | "anyOf": [ 30 | {"bsonType": "null"}, 31 | { 32 | "bsonType": "bool", 33 | "additionalProperties": false 34 | }, 35 | { 36 | "anyOf": [ 37 | {"bsonType": "int"}, 38 | { 39 | "anyOf": [ 40 | { 41 | "bsonType": "null" 42 | }, 43 | { 44 | "bsonType": "bool", 45 | "additionalProperties": true 46 | }, 47 | { 48 | "bsonType": "string" 49 | } 50 | ] 51 | } 52 | ] 53 | } 54 | ] 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/flattenedAnyOfReducedToOneType.json: -------------------------------------------------------------------------------- 1 | { 2 | "bsonType": "object", 3 | "properties": { 4 | "bar": { 5 | "anyOf": [ 6 | { 7 | "anyOf": [ 8 | { 9 | "anyOf": [ 10 | { 11 | "bsonType": "array", 12 | "items" : {"bsonType": "int"}, 13 | "additionalProperties": true 14 | } 15 | ] 16 | } 17 | ] 18 | } 19 | ] 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/polymorphicAdditionalProperties.json: -------------------------------------------------------------------------------- 1 | {"bsonType": "object", 2 | "properties": { 3 | "bar": { 4 | "bsonType": "object", 5 | "properties": { 6 | "a": { 7 | "bsonType": "object", 8 | "additionalProperties": { 9 | "props": "val" 10 | } 11 | }, 12 | "b": { 13 | "bsonType": "boolean", 14 | "additionalProperties": false 15 | }, 16 | "c": { 17 | "bsonType": "string", 18 | "additionalProperties": true 19 | }, 20 | "d": { 21 | "bsonType": "date" 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/polymorphicItems.json: -------------------------------------------------------------------------------- 1 | {"bsonType": "object", 2 | "properties": { 3 | "bar": { 4 | "bsonType": "object", 5 | "properties": { 6 | "a": { 7 | "bsonType": "array", 8 | "items": {"bsonType": "date"} 9 | }, 10 | "b": { 11 | "bsonType": "array", 12 | "items": [ 13 | { 14 | "anyOf": [ 15 | { 16 | "bsonType": "string" 17 | }, 18 | { 19 | "bsonType": "null" 20 | } 21 | ] 22 | }, 23 | { 24 | "bsonType": "boolean" 25 | } 26 | ], 27 | "additionalProperties": false 28 | }, 29 | "c": {"bsonType": "objectId"} 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/resources/mongoJsonSchemaTest/input/simpleSchema.json: -------------------------------------------------------------------------------- 1 | {"bsonType": "object", 2 | "properties": { 3 | "bar": { 4 | "bsonType": "object", 5 | "properties": { 6 | "a": {}, 7 | "b": {"anyOf": []}, 8 | "c": {"bsonType": "string"}, 9 | "e": {"bsonType": "int"}, 10 | "f": {"bsonType": "double"}, 11 | "g": {"bsonType": "long"}, 12 | "h": {"bsonType": "decimal"}, 13 | "i": {"bsonType": "binData"}, 14 | "j": {"bsonType": "objectId"}, 15 | "k": {"bsonType": "bool"}, 16 | "l": {"bsonType": "date"}, 17 | "m": {"bsonType": "null"}, 18 | "n": {"bsonType": "regex"}, 19 | "o": {"bsonType": "dbPointer"}, 20 | "p": {"bsonType": "javascript"}, 21 | "q": {"bsonType": "symbol"}, 22 | "r": {"bsonType": "javascriptWithScope"}, 23 | "s": {"bsonType": "timestamp"}, 24 | "t": {"bsonType": "minKey"}, 25 | "u": {"bsonType": "maxKey"}, 26 | "v": { 27 | "bsonType": "array", 28 | "items": { 29 | "anyOf": [ 30 | {"bsonType": "string"}, 31 | {"bsonType": "null"} 32 | ] 33 | } 34 | }, 35 | "w": { 36 | "anyOf": [ 37 | {"bsonType": "null"}, 38 | { 39 | "bsonType": "object", 40 | "properties": {}, 41 | "required": [], 42 | "additionalProperties": true 43 | } 44 | ] 45 | }, 46 | "x": { 47 | "bsonType": ["string"] 48 | }, 49 | "y": { 50 | "bsonType": ["string", "int"] 51 | } 52 | }, 53 | "required": ["a", "b", "c"], 54 | "additionalProperties": false 55 | } 56 | }, 57 | "required": [], 58 | "additionalProperties": false 59 | } 60 | --------------------------------------------------------------------------------