├── .ci
└── cloudbuild.yaml
├── .envrc.example
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.yaml
│ ├── documentation_issue.yaml
│ ├── feature_request.yaml
│ └── question.yaml
├── auto-label.yaml
├── blunderbuss.yml
├── dependabot.yml
├── flakybot.yaml
├── generated-files-bot.yml
├── header-checker-lint.yml
├── labels.yml
├── release-please.yml
├── release-trigger.yml
├── renovate.json5
├── scripts
│ ├── run_tests.sh
│ └── run_tests_graalvm_native.sh
├── sync-repo-settings.yaml
├── trusted-contribution.yml
└── workflows
│ ├── codeql.yml
│ ├── labels.yaml
│ ├── lint.yaml
│ ├── scorecard.yml
│ └── tests.yml
├── .gitignore
├── .kokoro
├── build.bat
├── build.sh
├── check_coverage.sh
├── coerce_logs.sh
├── common.cfg
├── common.sh
├── dependencies.sh
├── populate-secrets.sh
├── release
│ ├── bump_snapshot.cfg
│ ├── common.cfg
│ ├── common.sh
│ ├── drop.cfg
│ ├── drop.sh
│ ├── promote.cfg
│ ├── promote.sh
│ ├── publish_javadoc.cfg
│ ├── publish_javadoc.sh
│ ├── publish_javadoc11.cfg
│ ├── publish_javadoc11.sh
│ ├── snapshot.cfg
│ ├── snapshot.sh
│ ├── stage.cfg
│ └── stage.sh
├── requirements.in
├── requirements.txt
└── trampoline.sh
├── .mvn
└── wrapper
│ └── maven-wrapper.properties
├── .release
├── generate_sha.sh
├── snapshot.sh
├── update_versions.sh
└── upload_uberjars.yaml
├── .repo-metadata.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── checkstyle-suppressions.xml
├── core
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── google
│ │ │ └── cloud
│ │ │ └── sql
│ │ │ ├── AuthType.java
│ │ │ ├── ConnectorConfig.java
│ │ │ ├── ConnectorRegistry.java
│ │ │ ├── CredentialFactory.java
│ │ │ ├── IpType.java
│ │ │ ├── RefreshStrategy.java
│ │ │ ├── core
│ │ │ ├── AccessTokenSupplier.java
│ │ │ ├── ApiClientRetryingCallable.java
│ │ │ ├── ApplicationDefaultCredentialFactory.java
│ │ │ ├── AsyncRateLimiter.java
│ │ │ ├── CloudSqlInstanceName.java
│ │ │ ├── ConnectionConfig.java
│ │ │ ├── ConnectionInfo.java
│ │ │ ├── ConnectionInfoCache.java
│ │ │ ├── ConnectionInfoRepository.java
│ │ │ ├── ConnectionInfoRepositoryFactory.java
│ │ │ ├── ConnectionMetadata.java
│ │ │ ├── Connector.java
│ │ │ ├── ConscryptWorkaroundDelegatingTrustManger.java
│ │ │ ├── ConstantCredentialFactory.java
│ │ │ ├── CoreSocketFactory.java
│ │ │ ├── CredentialFactoryProvider.java
│ │ │ ├── DefaultAccessTokenSupplier.java
│ │ │ ├── DefaultConnectionInfoRepository.java
│ │ │ ├── DefaultConnectionInfoRepositoryFactory.java
│ │ │ ├── DnsInstanceConnectionNameResolver.java
│ │ │ ├── DnsResolver.java
│ │ │ ├── FileCredentialFactory.java
│ │ │ ├── InstanceCheckingTrustManagerFactory.java
│ │ │ ├── InstanceCheckingTrustManagerFactorySpi.java
│ │ │ ├── InstanceCheckingTrustManger.java
│ │ │ ├── InstanceConnectionNameResolver.java
│ │ │ ├── InstanceMetadata.java
│ │ │ ├── InternalConnectorRegistry.java
│ │ │ ├── JndiDnsResolver.java
│ │ │ ├── LazyRefreshConnectionInfoCache.java
│ │ │ ├── LazyRefreshStrategy.java
│ │ │ ├── MonitoredCache.java
│ │ │ ├── RefreshAheadConnectionInfoCache.java
│ │ │ ├── RefreshAheadStrategy.java
│ │ │ ├── RefreshCalculator.java
│ │ │ ├── RefreshStrategy.java
│ │ │ ├── RetryingCallable.java
│ │ │ ├── ServiceAccountImpersonatingCredentialFactory.java
│ │ │ ├── SslData.java
│ │ │ ├── SupplierCredentialFactory.java
│ │ │ ├── TerminalException.java
│ │ │ └── package-info.java
│ │ │ ├── nativeimage
│ │ │ └── CloudSqlFeature.java
│ │ │ └── package-info.java
│ └── resources
│ │ ├── META-INF
│ │ └── native-image
│ │ │ └── com.google.cloud.sql
│ │ │ └── cloud-sql-jdbc-socket-factory-parent
│ │ │ ├── jni-unix-socket-config.json
│ │ │ ├── native-image.properties
│ │ │ ├── proxy-config.json
│ │ │ └── resource-config.json
│ │ └── com.google.cloud.sql
│ │ └── project.properties
│ └── test
│ ├── java
│ └── com
│ │ └── google
│ │ └── cloud
│ │ └── sql
│ │ ├── ConnectorConfigTest.java
│ │ ├── CredentialFactoryTest.java
│ │ └── core
│ │ ├── ApiClientRetryingCallableTest.java
│ │ ├── AsyncRateLimiterTest.java
│ │ ├── BadConnectionFactory.java
│ │ ├── CloudSqlCoreTestingBase.java
│ │ ├── CloudSqlInstanceNameTest.java
│ │ ├── ConnectionConfigTest.java
│ │ ├── ConnectorTest.java
│ │ ├── ConstantCredentialsFactoryTest.java
│ │ ├── CredentialFactoryProviderTest.java
│ │ ├── DefaultAccessTokenSupplierTest.java
│ │ ├── DefaultConnectionInfoRepositoryIntegrationTests.java
│ │ ├── DefaultConnectionInfoRepositoryTest.java
│ │ ├── FakeSslServer.java
│ │ ├── FakeUnixSocketServer.java
│ │ ├── FileCredentialFactoryTest.java
│ │ ├── InstanceCheckingTrustManagerFactoryTest.java
│ │ ├── InternalConnectorRegistryTest.java
│ │ ├── LazyRefreshConnectionInfoCacheTest.java
│ │ ├── LazyRefreshStrategyTest.java
│ │ ├── MockAdminApi.java
│ │ ├── MonitoredCacheTest.java
│ │ ├── PauseCondition.java
│ │ ├── RefreshAheadConnectionInfoCacheConcurrencyTest.java
│ │ ├── RefreshAheadConnectionInfoCacheTest.java
│ │ ├── RefreshAheadStrategyTest.java
│ │ ├── RefreshCalculatorTest.java
│ │ ├── RetryingCallableTest.java
│ │ ├── ServiceAccountImpersonatingCredentialFactoryIntegrationTests.java
│ │ ├── StubConnectionInfoRepository.java
│ │ ├── StubConnectionInfoRepositoryFactory.java
│ │ ├── StubCredentialFactory.java
│ │ ├── SupplierCredentialFactoryTest.java
│ │ ├── TestCertificateGenerator.java
│ │ ├── TestDataSupplier.java
│ │ └── TestKeys.java
│ └── resources
│ ├── logback.xml
│ └── sample-credentials.json
├── docs
├── configuration.md
├── jdbc.md
└── r2dbc.md
├── java.header
├── jdbc
├── mariadb
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── google
│ │ │ └── cloud
│ │ │ └── sql
│ │ │ └── mariadb
│ │ │ └── SocketFactory.java
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── google
│ │ └── cloud
│ │ └── sql
│ │ └── mariadb
│ │ ├── JdbcMariaDBIamAuthIntegrationTests.java
│ │ └── JdbcMariaDBIntegrationTests.java
├── mysql-j-8
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── google
│ │ │ └── cloud
│ │ │ └── sql
│ │ │ └── mysql
│ │ │ └── SocketFactory.java
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── google
│ │ └── cloud
│ │ └── sql
│ │ └── mysql
│ │ ├── JdbcMysqlJ8DomainNameIntegrationTests.java
│ │ ├── JdbcMysqlJ8IAMServiceAccountImpersonationIntegrationTests.java
│ │ ├── JdbcMysqlJ8IamAuthIntegrationTests.java
│ │ ├── JdbcMysqlJ8IntegrationTests.java
│ │ ├── JdbcMysqlJ8McpIamAuthIntegrationTests.java
│ │ ├── JdbcMysqlJ8McpIntegrationTests.java
│ │ └── JdbcMysqlJ8ServiceAccountImpersonationIntegrationTests.java
├── postgres
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── google
│ │ │ └── cloud
│ │ │ └── sql
│ │ │ └── postgres
│ │ │ └── SocketFactory.java
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── google
│ │ │ └── cloud
│ │ │ └── sql
│ │ │ └── postgres
│ │ │ ├── JdbcPostgresCasIntegrationTests.java
│ │ │ ├── JdbcPostgresCustomSanIntegrationTests.java
│ │ │ ├── JdbcPostgresCustomerCasIntegrationTests.java
│ │ │ ├── JdbcPostgresDomainNameIntegrationTests.java
│ │ │ ├── JdbcPostgresIamAuthIntegrationTests.java
│ │ │ ├── JdbcPostgresIntegrationTests.java
│ │ │ ├── JdbcPostgresLazyRefreshIntegrationTests.java
│ │ │ ├── JdbcPostgresMcpIntegrationTests.java
│ │ │ ├── JdbcPostgresNamedConnectorIntegrationTests.java
│ │ │ ├── JdbcPostgresQuotaProjecImpersonationtIntegrationTests.java
│ │ │ ├── JdbcPostgresQuotaProjectIAMAuthIntegrationTests.java
│ │ │ └── JdbcPostgresServiceAccountImpersonationIntegrationTests.java
│ │ └── resources
│ │ └── conscrypt-security.properties
└── sqlserver
│ ├── pom.xml
│ └── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── google
│ │ └── cloud
│ │ └── sql
│ │ └── sqlserver
│ │ └── SocketFactory.java
│ └── test
│ └── java
│ └── com
│ └── google
│ └── cloud
│ └── sql
│ └── sqlserver
│ ├── JdbcSqlServerIntegrationTests.java
│ └── JdbcSqlServerUnitTests.java
├── license-checks.xml
├── mvnw
├── mvnw.cmd
├── owlbot.py
├── pom.xml
├── r2dbc
├── core
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── google
│ │ │ └── cloud
│ │ │ └── sql
│ │ │ └── core
│ │ │ ├── CloudSqlConnection.java
│ │ │ ├── CloudSqlConnectionFactory.java
│ │ │ └── GcpConnectionFactoryProvider.java
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── google
│ │ │ └── cloud
│ │ │ └── sql
│ │ │ └── core
│ │ │ ├── GcpConnectionFactoryProviderTest.java
│ │ │ └── R2dbcTestKeys.java
│ │ └── resources
│ │ └── mockito-extensions
│ │ └── org.mockito.plugins.MockMaker
├── mariadb
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── google
│ │ │ │ └── cloud
│ │ │ │ └── sql
│ │ │ │ └── core
│ │ │ │ └── GcpConnectionFactoryProviderMariadb.java
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── services
│ │ │ └── io.r2dbc.spi.ConnectionFactoryProvider
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── google
│ │ └── cloud
│ │ └── sql
│ │ └── core
│ │ ├── R2dbcMariadbIamAuthIntegrationTests.java
│ │ └── R2dbcMariadbIntegrationTests.java
├── mysql
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── google
│ │ │ │ └── cloud
│ │ │ │ └── sql
│ │ │ │ └── core
│ │ │ │ └── GcpConnectionFactoryProviderMysql.java
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── services
│ │ │ └── io.r2dbc.spi.ConnectionFactoryProvider
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── google
│ │ └── cloud
│ │ └── sql
│ │ └── core
│ │ ├── R2dbcMysqlIamAuthIntegrationTests.java
│ │ └── R2dbcMysqlIntegrationTests.java
├── postgres
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── google
│ │ │ │ └── cloud
│ │ │ │ └── sql
│ │ │ │ └── core
│ │ │ │ └── GcpConnectionFactoryProviderPostgres.java
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── services
│ │ │ └── io.r2dbc.spi.ConnectionFactoryProvider
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── google
│ │ └── cloud
│ │ └── sql
│ │ └── core
│ │ ├── R2dbcPostgresIamAuthIntegrationTests.java
│ │ ├── R2dbcPostgresIntegrationTests.java
│ │ └── R2dbcPostgresPoolRemoteValidationIntegrationTests.java
└── sqlserver
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── google
│ │ │ └── cloud
│ │ │ └── sql
│ │ │ └── core
│ │ │ └── GcpConnectionFactoryProviderMssql.java
│ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── io.r2dbc.spi.ConnectionFactoryProvider
│ └── test
│ └── java
│ └── com
│ └── google
│ └── cloud
│ └── sql
│ └── core
│ └── R2dbcSqlserverIntegrationTests.java
└── versions.txt
/.envrc.example:
--------------------------------------------------------------------------------
1 | export GOOGLE_CLOUD_PROJECT="project-name"
2 |
3 | export MYSQL_CONNECTION_NAME="project:region:instance"
4 | export MYSQL_USER="mysql-user"
5 | export MYSQL_PASS="mysql-password"
6 | export MYSQL_DB="mysql-db-name"
7 |
8 | export POSTGRES_CONNECTION_NAME="project:region:instance"
9 | export POSTGRES_USER="postgres-user"
10 | export POSTGRES_PASS="postgres-password"
11 | export POSTGRES_DB="postgres-db-name"
12 |
13 | export SQLSERVER_CONNECTION_NAME="project:region:instance"
14 | export SQLSERVER_USER="sqlserver-user"
15 | export SQLSERVER_PASS="sqlserver-password"
16 | export SQLSERVER_DB="sqlserver-db-name"
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @GoogleCloudPlatform/cloud-sql-connectors
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: 🐞 Bug Report
16 | description: File a bug report
17 | title: "Brief summary of what bug or error was observed"
18 | labels: ["type: bug"]
19 | body:
20 | - type: markdown
21 | attributes:
22 | value: |
23 | Thanks for stopping by to let us know something could be better!
24 |
25 | Please run down the following list and make sure you've tried the usual "quick fixes":
26 | - Search the [current open issues](https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/issues)
27 | - Check for answers on [StackOverflow](https://stackoverflow.com/questions/tagged/google-cloud-sql) (under the 'google-cloud-sql' tag)
28 |
29 | If you are still having issues, please include as much information as possible below! :smile:
30 | - type: textarea
31 | id: bug-description
32 | attributes:
33 | label: Bug Description
34 | description: "Please enter a detailed description of the bug, and any information about what behavior you noticed and why it is defective or unintentional."
35 | validations:
36 | required: true
37 | - type: textarea
38 | id: example-code
39 | attributes:
40 | label: Example code (or command)
41 | description: "Please paste any useful application code related to the bug below. (if your code is in a public repo, feel free to paste a link!)"
42 | render: Java
43 | - type: textarea
44 | id: stacktrace
45 | attributes:
46 | label: Stacktrace
47 | description: "Paste any relevant stacktrace or error you are running into here. Be sure to filter sensitive information!"
48 | render: bash
49 | - type: textarea
50 | id: repro
51 | attributes:
52 | label: Steps to reproduce?
53 | description: "How do you trigger this bug? Please walk us through it step by step."
54 | value: |
55 | 1. ?
56 | 2. ?
57 | 3. ?
58 | ...
59 | validations:
60 | required: true
61 | - type: textarea
62 | id: environment
63 | attributes:
64 | label: Environment
65 | description: "Let us know some details about the environment in which you are seeing the bug!"
66 | value: |
67 | 1. OS type and version:
68 | 2. Java SDK version:
69 | 3. Cloud SQL Java Socket Factory version:
70 | validations:
71 | required: true
72 | - type: textarea
73 | id: additional-details
74 | attributes:
75 | label: Additional Details
76 | description: "Any other information you want us to know?"
77 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/documentation_issue.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: 📝 Documentation Issue
16 | description: Report wrong or missing information with the documentation in this repo.
17 | title: "Brief summary of what is missing or incorrect"
18 | labels: ["type: docs"]
19 | body:
20 | - type: markdown
21 | attributes:
22 | value: |
23 | Thanks for stopping by to let us know something could be better! :smile:
24 |
25 | Please explain below how we can improve our documentation.
26 | - type: textarea
27 | id: description
28 | attributes:
29 | label: Description
30 | description: "Provide a short description of what is missing or incorrect, as well as a link to the specific location of the issue."
31 | validations:
32 | required: true
33 | - type: textarea
34 | id: potential-solution
35 | attributes:
36 | label: Potential Solution
37 | description: "What would you prefer the documentation say? Why would this information be more accurate or helpful?"
38 | - type: textarea
39 | id: additional-details
40 | attributes:
41 | label: Additional Details
42 | description: "Please reference any other relevant issues, PRs, descriptions, or screenshots here."
43 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: ✨ Feature Request
16 | description: Suggest an idea for new or improved behavior.
17 | title: "Brief summary of the proposed feature"
18 | labels: ["type: feature request"]
19 | body:
20 | - type: markdown
21 | attributes:
22 | value: |
23 | Thanks for stopping by to let us know something could be better!
24 |
25 | Please run down the following list before proceeding with your feature request:
26 | - Search the [current open issues](https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/issues) to prevent creating a duplicate.
27 |
28 | Please include as much information as possible below! :smile:
29 | - type: textarea
30 | id: feature-description
31 | attributes:
32 | label: Feature Description
33 | description: "A clear and concise description of what feature you would like to see, and why it would be useful to have added."
34 | validations:
35 | required: true
36 | - type: textarea
37 | id: sample-code
38 | attributes:
39 | label: Sample code
40 | description: "If you already have an idea of what the implementation of this feature would like in code please provide it. (pseudo code is okay!)"
41 | render: Java
42 | - type: textarea
43 | id: alternatives-considered
44 | attributes:
45 | label: Alternatives Considered
46 | description: "Are there any workaround or third party tools to replicate this behavior? Why would adding this feature be preferred over them?"
47 | - type: textarea
48 | id: additional-details
49 | attributes:
50 | label: Additional Details
51 | description: "Any additional information we should know? Please reference it here (issues, PRs, descriptions, or screenshots)"
52 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: 💬 Question
16 | description: Questions on how something works or the best way to do something?
17 | title: "Brief summary of your question"
18 | labels: ["type: question"]
19 | body:
20 | - type: markdown
21 | attributes:
22 | value: |
23 | Thanks for stopping by to let us know something could be better!
24 |
25 | Please run down the following list and make sure you've tried the usual "quick fixes":
26 | - Search the [current open issues](https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/issues) for a similar question
27 | - Check for answers on [StackOverflow](https://stackoverflow.com/questions/tagged/google-cloud-sql) (under the 'google-cloud-sql' tag)
28 |
29 | If you still have a question, please include as much information as possible below! :smile:
30 | - type: textarea
31 | id: question
32 | attributes:
33 | label: Question
34 | description: "What's your question? Please provide as much relevant information as possible to reduce turnaround time."
35 | placeholder: "Example: How do I connect using this connector with Private IP from Cloud Run?"
36 | validations:
37 | required: true
38 | - type: textarea
39 | id: code
40 | attributes:
41 | label: Code
42 | description: "Please paste any useful application code that might be relevant to your question. (if your code is in a public repo, feel free to paste a link!)"
43 | render: Java
44 | - type: textarea
45 | id: additional-details
46 | attributes:
47 | label: Additional Details
48 | description: "Any other information you want us to know that might be helpful in answering your question? (link issues, PRs, descriptions, or screenshots)"
49 |
--------------------------------------------------------------------------------
/.github/auto-label.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | requestsize:
15 | enabled: true
16 |
--------------------------------------------------------------------------------
/.github/blunderbuss.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2021 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | assign_issues:
16 | - hessjcg
17 | - kgala2
18 |
19 | assign_prs:
20 | - hessjcg
21 | - kgala2
22 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | version: 2
16 | updates:
17 | - package-ecosystem: "maven"
18 | directory: "/"
19 | schedule:
20 | interval: "daily"
21 | # Disable version updates for Maven dependencies
22 | open-pull-requests-limit: 0
23 | - package-ecosystem: "pip"
24 | directory: "/"
25 | schedule:
26 | interval: "daily"
27 | # Disable version updates for pip dependencies
28 | open-pull-requests-limit: 0
29 |
--------------------------------------------------------------------------------
/.github/flakybot.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | issuePriority: p2
16 |
--------------------------------------------------------------------------------
/.github/generated-files-bot.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | externalManifests:
16 | - type: json
17 | file: 'synth.metadata'
18 | jsonpath: '$.generatedFiles[*]'
19 | - type: json
20 | file: '.github/readme/synth.metadata/synth.metadata'
21 | jsonpath: '$.generatedFiles[*]'
22 | ignoreAuthors:
23 | - 'renovate-bot'
24 | - 'yoshi-automation'
25 | - 'release-please[bot]'
26 | - 'gcf-owl-bot[bot]'
27 |
--------------------------------------------------------------------------------
/.github/header-checker-lint.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2021 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | allowedCopyrightHolders:
16 | - 'Google LLC'
17 | allowedLicenses:
18 | - 'Apache-2.0'
19 | sourceFileExtensions:
20 | - 'java'
21 | - 'yaml'
22 | - 'yml'
23 | - 'xml'
24 |
--------------------------------------------------------------------------------
/.github/release-please.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | bumpMinorPreMajor: true
16 | handleGHRelease: true
17 | releaseType: java-yoshi
18 | extraFiles:
19 | - docs/jdbc.md
20 | - docs/r2dbc.md
21 |
--------------------------------------------------------------------------------
/.github/release-trigger.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | enabled: true
16 | multiScmName: cloud-sql-jdbc-socket-factory
17 |
--------------------------------------------------------------------------------
/.github/renovate.json5:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:recommended",
4 | "helpers:pinGitHubActionDigests",
5 | ":separateMajorReleases",
6 | ":combinePatchMinorReleases",
7 | ":ignoreUnstable",
8 | ":prImmediately",
9 | ":updateNotScheduled",
10 | ":automergeDisabled",
11 | ":ignoreModulesAndTests",
12 | ":maintainLockFilesDisabled"
13 | ],
14 | "commitMessagePrefix": "deps: ",
15 | "ignorePresets": [":semanticPrefixFixDepsChoreOthers"],
16 | "rebaseWhen": "behind-base-branch",
17 | "dependencyDashboard": true,
18 | "dependencyDashboardLabels": ["type: process"],
19 | "semanticCommits": "disabled",
20 | "ignorePaths": [".kokoro/requirements.txt"],
21 | "ignoreDeps": [
22 | "com.coveo:fmt-maven-plugin",
23 | "com.zaxxer:HikariCP",
24 | "com.google.googlejavaformat:google-java-format",
25 | "com.google.errorprone:error_prone_core",
26 | "ch.qos.logback:logback-classic"
27 | ],
28 | "packageRules": [
29 | {"matchPackagePatterns": ["^com.google.guava:"], "versioning": "docker"},
30 | {
31 | "matchPackagePatterns": [
32 | "^org.apache.maven",
33 | "^org.jacoco:",
34 | "^org.codehaus.mojo:",
35 | "^org.sonatype.plugins:",
36 | "^com.coveo:",
37 | "^com.google.cloud:google-cloud-shared-config"
38 | ],
39 | "semanticCommitType": "build",
40 | "semanticCommitScope": "deps"
41 | },
42 | {
43 | "matchPackagePatterns": ["^com.google.cloud:google-cloud-"],
44 | "ignoreUnstable": false
45 | },
46 | {"matchPackageNames": ["mysql:mysql-connector-java"], "enabled": false},
47 | {
48 | "matchPackageNames": ["com.google.guava:guava"],
49 | "allowedVersions": "/.+-android/"
50 | },
51 | {
52 | "matchPackageNames": ["com.microsoft.sqlserver:mssql-jdbc"],
53 | "allowedVersions": "/.+jre8.?/"
54 | },
55 | {
56 | "matchPackageNames": ["com.google.apis:google-api-services-sqladmin"],
57 | "allowedVersions": "/v1beta4-.*/"
58 | },
59 | {
60 | "groupName": "Non-major dependencies",
61 | "matchManagers": ["maven"],
62 | "matchUpdateTypes": ["minor", "patch"]
63 | },
64 | {
65 | "matchManagers": ["github-actions"],
66 | "groupName": "dependencies for github",
67 | "commitMessagePrefix": "chore(deps):"
68 | }
69 | ]
70 | }
71 |
--------------------------------------------------------------------------------
/.github/scripts/run_tests.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | # Copyright 2020 Google 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 | # `-e` enables the script to automatically fail when a command fails
17 | set -ex
18 |
19 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
20 | PROJECT_DIR=$( dirname "$SCRIPT_DIR" )
21 |
22 | if [[ $OSTYPE == 'darwin'* ]]; then
23 | # Add alias for 127.0.0.2 to be used as a loopback address
24 | # https://superuser.com/questions/458875/how-do-you-get-loopback-addresses-other-than-127-0-0-1-to-work-on-os-x
25 | sudo ifconfig lo0 alias 127.0.0.2 up
26 | sudo ifconfig lo0 alias 127.0.0.3 up
27 | fi
28 |
29 | echo -e "******************** Running tests... ********************\n"
30 | echo "Running tests using Java:"
31 | java -version
32 |
33 | # Use the mvn command
34 | if which mvn ; then
35 | mvn_cmd="mvn"
36 | else
37 | mvn_cmd="./mvnw"
38 | fi
39 |
40 | ls -al
41 |
42 | echo "Maven version: $($mvn_cmd --version)"
43 |
44 | echo "Job type: ${JOB_TYPE}"
45 |
46 | RETURN_CODE=0
47 | set +e
48 |
49 | case ${JOB_TYPE} in
50 | test)
51 | $mvn_cmd -e -B clean -ntp test -P coverage -Dcheckstyle.skip
52 | RETURN_CODE=$?
53 | ;;
54 | integration)
55 | $mvn_cmd -e -B clean -ntp verify -P e2e -P coverage -Dcheckstyle.skip
56 | RETURN_CODE=$?
57 | ;;
58 | esac
59 |
60 | echo -e "******************** Tests complete. ********************\n"
61 | echo "exiting with ${RETURN_CODE}"
62 | exit ${RETURN_CODE}
63 |
--------------------------------------------------------------------------------
/.github/scripts/run_tests_graalvm_native.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | # Copyright 2020 Google 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 | # `-e` enables the script to automatically fail when a command fails
17 | set -e
18 |
19 | echo -e "******************** Installing modules... ********************\n"
20 | mvn -e -B install -DskipTests
21 | echo -e "******************** Installation complete. ********************\n"
22 | echo "JAVA_HOME: $JAVA_HOME"
23 | echo "Java version:"
24 | java -version
25 |
26 | # Why change directories to run the tests? Because GraalVM test execution
27 | # requires at least one matching test per Maven module. Not all modules in this
28 | # repository have "*IntegrationTests.java".
29 | # https://github.com/graalvm/native-build-tools/issues/188
30 | set +e
31 | declare -i return_code=0
32 |
33 | # Currently, jdbc/postgres works with GraalVM native image.
34 | # TODO(#824): Provide GraalVM configuration and enable native image tests below:
35 | # jdbc/mysql-j-5 jdbc/mysql-j-8 jdbc/sqlserver r2dbc/sqlserver r2dbc/sqlserver
36 | # r2dbc/mysql
37 | # https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/issues/824
38 | for test_directory in jdbc/postgres jdbc/mysql-j-8; do
39 | pushd ${test_directory}
40 | echo -e "******************** Running tests in ${test_directory} ********************\n"
41 | # Dependency convergence enforcer rule would fail with the junit dependencies
42 | # specified in "native" profile. The test-scope dependencies do not have any
43 | # effect to library users' class path.
44 | mvn -e -B clean verify -P e2e,native -P coverage
45 | result=$?
46 | return_code=$((return_code || result))
47 | echo -e "******************** Tests complete in ${test_directory}, result: $result ********************\n"
48 | popd
49 | done
50 | exit ${return_code}
51 |
--------------------------------------------------------------------------------
/.github/sync-repo-settings.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | # Whether or not rebase-merging is enabled on this repository.
15 | # Defaults to `true`
16 | rebaseMergeAllowed: false
17 |
18 | # Whether or not squash-merging is enabled on this repository.
19 | # Defaults to `true`
20 | squashMergeAllowed: true
21 |
22 | # Whether or not PRs are merged with a merge commit on this repository.
23 | # Defaults to `false`
24 | mergeCommitAllowed: false
25 |
26 | # Rules for main branch protection
27 | branchProtectionRules:
28 | # Identifies the protection rule pattern. Name of the branch to be protected.
29 | # Defaults to `main`
30 | - pattern: main
31 | # Can admins overwrite branch protection.
32 | # Defaults to `true`
33 | isAdminEnforced: true
34 | # Number of approving reviews required to update matching branches.
35 | # Defaults to `1`
36 | requiredApprovingReviewCount: 1
37 | # Are reviews from code owners required to update matching branches.
38 | # Defaults to `false`
39 | requiresCodeOwnerReviews: true
40 | # Require up to date branches
41 | requiresStrictStatusChecks: true
42 | # List of required status check contexts that must pass for commits to be accepted to matching branches.
43 | requiredStatusCheckContexts:
44 | - "lint"
45 | - "unit tests (macos-latest, 8)"
46 | - "unit tests (macos-latest, 11)"
47 | - "unit tests (macos-latest, 17)"
48 | - "unit tests (windows-latest, 8)"
49 | - "unit tests (windows-latest, 11)"
50 | - "unit tests (windows-latest, 17)"
51 | - "unit tests (ubuntu-latest, 8)"
52 | - "unit tests (ubuntu-latest, 11)"
53 | - "unit tests (ubuntu-latest, 17)"
54 | - "units + e2e (ubuntu-latest, 17)"
55 | - "cla/google"
56 | # Wait until we make the repo public before bringing this back
57 | # - "OwlBot Post Processor"
58 |
--------------------------------------------------------------------------------
/.github/trusted-contribution.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2025 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # Trigger presubmit tests for trusted contributors
16 | # https://github.com/googleapis/repo-automation-bots/tree/main/packages/trusted-contribution
17 | # Install: https://github.com/apps/trusted-contributions-gcf
18 |
19 | trustedContributors:
20 | - "dependabot[bot]"
21 | - "renovate-bot"
22 | - "renovate[bot]"
23 | - "forking-renovate[bot]"
24 | - "release-please[bot]"
25 | annotations:
26 | # Trigger Cloud Build tests
27 | - type: comment
28 | text: "/gcbrun"
29 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: "CodeQL"
16 |
17 | on:
18 | push:
19 | branches: ["main"]
20 | pull_request:
21 | branches: ["main"]
22 | paths-ignore:
23 | - "**/*.md"
24 | - "**/*.txt"
25 |
26 | # Declare default permissions as read only.
27 | permissions: read-all
28 |
29 | jobs:
30 | analyze:
31 | name: Analyze
32 | runs-on: ubuntu-latest
33 | permissions:
34 | actions: read
35 | contents: read
36 | security-events: write
37 |
38 | strategy:
39 | fail-fast: false
40 | matrix:
41 | language: ["java"]
42 |
43 | steps:
44 | - name: Checkout repository
45 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
46 |
47 | # Initializes the CodeQL tools for scanning.
48 | - name: Initialize CodeQL
49 | uses: github/codeql-action/init@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
50 | with:
51 | languages: ${{ matrix.language }}
52 |
53 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
54 | # If this step fails, then you should remove it and run the build manually
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
57 |
58 | - name: Perform CodeQL Analysis
59 | uses: github/codeql-action/analyze@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
60 | with:
61 | category: "/language:${{matrix.language}}"
62 |
--------------------------------------------------------------------------------
/.github/workflows/labels.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: Sync labels
16 | on:
17 | push:
18 | branches:
19 | - main
20 |
21 | # Declare default permissions as read only.
22 | permissions: read-all
23 |
24 | jobs:
25 | build:
26 | runs-on: ubuntu-latest
27 | permissions:
28 | issues: write
29 | pull-requests: write
30 | steps:
31 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
32 | - uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c # v1.3.0
33 | env:
34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: lint
16 | on:
17 | pull_request:
18 |
19 | # Declare default permissions as read only.
20 | permissions: read-all
21 |
22 | jobs:
23 | lint:
24 | name: checkstyle
25 | runs-on: ubuntu-latest
26 | steps:
27 | - name: Checkout code
28 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
29 | - name: Set up JDK 17
30 | uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
31 | with:
32 | distribution: "zulu"
33 | java-version: "17"
34 | - name: lint
35 | run: mvn -B compile -Plint
36 |
--------------------------------------------------------------------------------
/.github/workflows/scorecard.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2023 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: OSSF Scorecard
16 | on:
17 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
18 | branch_protection_rule:
19 | schedule:
20 | # weekly on Sunday
21 | - cron: '0 20 * * 0'
22 | push:
23 | branches: [ "main" ]
24 |
25 | # Declare default permissions as read only.
26 | permissions: read-all
27 |
28 | jobs:
29 | analysis:
30 | name: Scorecard analysis
31 | runs-on: ubuntu-latest
32 | permissions:
33 | # Needed to upload the results to code-scanning dashboard.
34 | security-events: write
35 |
36 | steps:
37 | - name: "Checkout code"
38 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
39 | with:
40 | persist-credentials: false
41 |
42 | - name: "Run analysis"
43 | uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
44 | with:
45 | results_file: results.sarif
46 | results_format: sarif
47 |
48 | - name: Filter SARIF to skip false positives
49 | # filter out DangerousWorkflow alerts as they do not account for safe use of labels to trigger actions
50 | env:
51 | SCORECARD_SKIPPED_RULE_IDS: "DangerousWorkflowID"
52 | run: |
53 | SCORECARD_SKIPPED_RULE_IDS_JSON=$(echo $SCORECARD_SKIPPED_RULE_IDS | jq -cR 'split(",")')
54 | # Trim the SARIF file to remove false positive detections
55 | cat results.sarif | jq '.runs[].results |= map(select(.ruleId as $id | '$SCORECARD_SKIPPED_RULE_IDS_JSON' | all($id != .)))' > resultsFiltered.sarif
56 |
57 | # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
58 | # format to the repository Actions tab.
59 | - name: "Upload artifact"
60 | uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
61 | with:
62 | name: SARIF file
63 | path: results.sarif
64 | retention-days: 5
65 |
66 | # Upload the results to GitHub's code scanning dashboard.
67 | - name: "Upload to code-scanning"
68 | uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
69 | with:
70 | sarif_file: resultsFiltered.sarif
71 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # misc java
2 | target/
3 | *.class
4 |
5 | # IntelliJ
6 | .idea/
7 | *.iml
8 | *.bak
9 |
10 | # vscode
11 | **/.project
12 | **/.settings/
13 | **/.classpath
14 |
15 | # direnv
16 | .envrc
17 |
18 | # Package Files
19 | *.jar
20 | *.war
21 | *.nar
22 | *.ear
23 | *.zip
24 | *.tar.gz
25 | *.rar
26 |
27 | # Packages
28 | dist
29 | bin
30 | var
31 | sdist
32 | target
33 |
34 | # Unit test / coverage reports
35 | .coverage
36 | .tox
37 | nosetests.xml
38 |
39 | # Translations
40 | *.mo
41 |
42 | # Mr Developer
43 | .mr.developer.cfg
44 |
45 | .metadata
46 | .project
47 | .pydevproject
48 |
49 | *.iml
50 | .idea
51 | .settings
52 | .DS_Store
53 | .classpath
54 |
55 | # API key file containing value of GOOGLE_API_KEY for integration tests
56 | api_key
57 |
58 | # Python utilities
59 | *.pyc
60 | artman-genfiles
61 | /venv
62 | /env
63 |
64 | .flattened-pom.xml
65 | .envrc
66 |
67 | # Package Files
68 | *.jar
69 | *.war
70 | *.nar
71 | *.ear
72 | *.zip
73 | *.tar.gz
74 | *.rar
75 |
--------------------------------------------------------------------------------
/.kokoro/build.bat:
--------------------------------------------------------------------------------
1 | :: Copyright 2022 Google LLC
2 | ::
3 | :: Licensed under the Apache License, Version 2.0 (the "License");
4 | :: you may not use this file except in compliance with the License.
5 | :: You may obtain a copy of the License at
6 | ::
7 | :: http://www.apache.org/licenses/LICENSE-2.0
8 | ::
9 | :: Unless required by applicable law or agreed to in writing, software
10 | :: distributed under the License is distributed on an "AS IS" BASIS,
11 | :: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | :: See the License for the specific language governing permissions and
13 | :: limitations under the License.
14 | :: Github action job to test core java library features on
15 | :: downstream client libraries before they are released.
16 | :: See documentation in type-shell-output.bat
17 |
18 | "C:\Program Files\Git\bin\bash.exe" %~dp0build.sh
19 |
--------------------------------------------------------------------------------
/.kokoro/check_coverage.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | # Copyright 2023 Google LLC
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 | # `-e` enables the script to automatically fail when a command fails
17 | set -e
18 |
19 | export CUR_COVER=$(cat core/target/site/jacoco/index.html | grep -o 'Total[^%]*' | sed 's/<.*>//; s/Total//')
20 | echo "Current Coverage is $CUR_COVER%"
21 | if [ "$CUR_COVER" -lt 75 ]; then
22 | exit 1;
23 | fi
24 |
--------------------------------------------------------------------------------
/.kokoro/coerce_logs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2019 Google LLC
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 | # This script finds and moves sponge logs so that they can be found by placer
17 | # and are not flagged as flaky by sponge.
18 |
19 | set -eo pipefail
20 |
21 | ## Get the directory of the build script
22 | scriptDir=$(realpath $(dirname "${BASH_SOURCE[0]}"))
23 | ## cd to the parent directory, i.e. the root of the git repo
24 | cd ${scriptDir}/..
25 |
26 | job=$(basename ${KOKORO_JOB_NAME})
27 |
28 | echo "coercing sponge logs..."
29 | for xml in `find . -name *-sponge_log.xml`
30 | do
31 | class=$(basename ${xml} | cut -d- -f2)
32 | dir=$(dirname ${xml})/${job}/${class}
33 | text=$(dirname ${xml})/${class}-sponge_log.txt
34 | mkdir -p ${dir}
35 | mv ${xml} ${dir}/sponge_log.xml
36 | mv ${text} ${dir}/sponge_log.txt
37 | done
38 |
--------------------------------------------------------------------------------
/.kokoro/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Download trampoline resources. These will be in ${KOKORO_GFILE_DIR}
4 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
5 |
6 | # All builds use the trampoline script to run in docker.
7 | build_file: "cloud-sql-jdbc-socket-factory/.kokoro/trampoline.sh"
8 |
9 | # Tell the trampoline which build file to use.
10 | env_vars: {
11 | key: "TRAMPOLINE_BUILD_FILE"
12 | value: "github/cloud-sql-jdbc-socket-factory/.kokoro/build.sh"
13 | }
14 |
--------------------------------------------------------------------------------
/.kokoro/common.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2022 Google LLC
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 | function retry_with_backoff {
17 | attempts_left=$1
18 | sleep_seconds=$2
19 | shift 2
20 | command=$@
21 |
22 |
23 | # store current flag state
24 | flags=$-
25 |
26 | # allow a failures to continue
27 | set +e
28 | ${command}
29 | exit_code=$?
30 |
31 | # restore "e" flag
32 | if [[ ${flags} =~ e ]]
33 | then set -e
34 | else set +e
35 | fi
36 |
37 | if [[ $exit_code == 0 ]]
38 | then
39 | return 0
40 | fi
41 |
42 | # failure
43 | if [[ ${attempts_left} > 0 ]]
44 | then
45 | echo "failure (${exit_code}), sleeping ${sleep_seconds}..."
46 | sleep ${sleep_seconds}
47 | new_attempts=$((${attempts_left} - 1))
48 | new_sleep=$((${sleep_seconds} * 2))
49 | retry_with_backoff ${new_attempts} ${new_sleep} ${command}
50 | fi
51 |
52 | return $exit_code
53 | }
54 |
55 | ## Helper functionss
56 | function now() { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n'; }
57 | function msg() { println "$*" >&2; }
58 | function println() { printf '%s\n' "$(now) $*"; }
59 |
60 | ## Helper comment to trigger updated repo dependency release
61 |
--------------------------------------------------------------------------------
/.kokoro/dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2019 Google LLC
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 | set -eo pipefail
17 | shopt -s nullglob
18 |
19 | ## Get the directory of the build script
20 | scriptDir=$(realpath $(dirname "${BASH_SOURCE[0]}"))
21 | ## cd to the parent directory, i.e. the root of the git repo
22 | cd ${scriptDir}/..
23 |
24 | # include common functions
25 | source ${scriptDir}/common.sh
26 |
27 | # Print out Java
28 | java -version
29 | echo $JOB_TYPE
30 |
31 | function determineMavenOpts() {
32 | local javaVersion=$(
33 | # filter down to the version line, then pull out the version between quotes,
34 | # then trim the version number down to its minimal number (removing any
35 | # update or suffix number).
36 | java -version 2>&1 | grep "version" \
37 | | sed -E 's/^.*"(.*?)".*$/\1/g' \
38 | | sed -E 's/^(1\.[0-9]\.0).*$/\1/g'
39 | )
40 |
41 | if [[ $javaVersion == 17* ]]
42 | then
43 | # MaxPermSize is no longer supported as of jdk 17
44 | echo -n "-Xmx1024m"
45 | else
46 | echo -n "-Xmx1024m -XX:MaxPermSize=128m"
47 | fi
48 | }
49 |
50 | export MAVEN_OPTS=$(determineMavenOpts)
51 |
52 | # this should run maven enforcer
53 | retry_with_backoff 3 10 \
54 | mvn install -B -V -ntp \
55 | -DskipTests=true \
56 | -Dmaven.javadoc.skip=true \
57 | -Dclirr.skip=true
58 |
59 | mvn -B dependency:analyze -DfailOnWarning=true
60 |
--------------------------------------------------------------------------------
/.kokoro/populate-secrets.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2020 Google LLC.
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 | set -eo pipefail
17 |
18 | function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;}
19 | function msg { println "$*" >&2 ;}
20 | function println { printf '%s\n' "$(now) $*" ;}
21 |
22 |
23 | # Populates requested secrets set in SECRET_MANAGER_KEYS from service account:
24 | # kokoro-trampoline@cloud-devrel-kokoro-resources.iam.gserviceaccount.com
25 | SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager"
26 | msg "Creating folder on disk for secrets: ${SECRET_LOCATION}"
27 | mkdir -p ${SECRET_LOCATION}
28 | for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g")
29 | do
30 | msg "Retrieving secret ${key}"
31 | docker run --entrypoint=gcloud \
32 | --volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR} \
33 | gcr.io/google.com/cloudsdktool/cloud-sdk \
34 | secrets versions access latest \
35 | --project cloud-devrel-kokoro-resources \
36 | --secret ${key} > \
37 | "${SECRET_LOCATION}/${key}"
38 | if [[ $? == 0 ]]; then
39 | msg "Secret written to ${SECRET_LOCATION}/${key}"
40 | else
41 | msg "Error retrieving secret ${key}"
42 | fi
43 | done
44 |
--------------------------------------------------------------------------------
/.kokoro/release/bump_snapshot.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Build logs will be here
4 | action {
5 | define_artifacts {
6 | regex: "**/*sponge_log.xml"
7 | }
8 | }
9 |
10 | # Download trampoline resources.
11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
12 |
13 | # Use the trampoline script to run in docker.
14 | build_file: "cloud-sql-jdbc-socket-factory/.kokoro/trampoline.sh"
15 |
16 | # Configure the docker image for kokoro-trampoline.
17 | env_vars: {
18 | key: "TRAMPOLINE_IMAGE"
19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user"
20 | }
21 |
22 | env_vars: {
23 | key: "TRAMPOLINE_BUILD_FILE"
24 | value: "github/cloud-sql-jdbc-socket-factory/.kokoro/release/bump_snapshot.sh"
25 | }
26 |
27 | # tokens used by release-please to keep an up-to-date release PR.
28 | before_action {
29 | fetch_keystore {
30 | keystore_resource {
31 | keystore_config_id: 73713
32 | keyname: "github-magic-proxy-key-release-please"
33 | }
34 | }
35 | }
36 |
37 | before_action {
38 | fetch_keystore {
39 | keystore_resource {
40 | keystore_config_id: 73713
41 | keyname: "github-magic-proxy-token-release-please"
42 | }
43 | }
44 | }
45 |
46 | before_action {
47 | fetch_keystore {
48 | keystore_resource {
49 | keystore_config_id: 73713
50 | keyname: "github-magic-proxy-url-release-please"
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/.kokoro/release/common.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # Download trampoline resources.
4 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
5 |
6 | # Use the trampoline script to run in docker.
7 | build_file: "cloud-sql-jdbc-socket-factory/.kokoro/trampoline.sh"
8 |
9 | # Configure the docker image for kokoro-trampoline.
10 | env_vars: {
11 | key: "TRAMPOLINE_IMAGE"
12 | value: "gcr.io/cloud-devrel-kokoro-resources/java11"
13 | }
14 |
15 | before_action {
16 | fetch_keystore {
17 | keystore_resource {
18 | keystore_config_id: 70247
19 | keyname: "maven-gpg-keyring"
20 | }
21 | }
22 | }
23 |
24 | before_action {
25 | fetch_keystore {
26 | keystore_resource {
27 | keystore_config_id: 70247
28 | keyname: "maven-gpg-passphrase"
29 | }
30 | }
31 | }
32 |
33 | before_action {
34 | fetch_keystore {
35 | keystore_resource {
36 | keystore_config_id: 70247
37 | keyname: "maven-gpg-pubkeyring"
38 | }
39 | }
40 | }
41 |
42 | before_action {
43 | fetch_keystore {
44 | keystore_resource {
45 | keystore_config_id: 70247
46 | keyname: "sonatype-credentials"
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/.kokoro/release/common.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC
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 | set -eo pipefail
17 |
18 | # Get secrets from keystore and set and environment variables
19 | setup_environment_secrets() {
20 | export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase)
21 | export GPG_TTY=$(tty)
22 | export GPG_HOMEDIR=/gpg
23 | mkdir $GPG_HOMEDIR
24 | mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-pubkeyring $GPG_HOMEDIR/pubring.gpg
25 | mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-keyring $GPG_HOMEDIR/secring.gpg
26 | export SONATYPE_USERNAME=$(cat ${KOKORO_KEYSTORE_DIR}/70247_sonatype-credentials | cut -f1 -d'|')
27 | export SONATYPE_PASSWORD=$(cat ${KOKORO_KEYSTORE_DIR}/70247_sonatype-credentials | cut -f2 -d'|')
28 | }
29 |
30 | create_settings_xml_file() {
31 | echo "
32 |
33 |
34 | ossrh
35 | ${SONATYPE_USERNAME}
36 | ${SONATYPE_PASSWORD}
37 |
38 |
39 | sonatype-nexus-staging
40 | ${SONATYPE_USERNAME}
41 | ${SONATYPE_PASSWORD}
42 |
43 |
44 | sonatype-nexus-snapshots
45 | ${SONATYPE_USERNAME}
46 | ${SONATYPE_PASSWORD}
47 |
48 |
49 | " > $1
50 | }
--------------------------------------------------------------------------------
/.kokoro/release/drop.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "TRAMPOLINE_BUILD_FILE"
5 | value: "github/cloud-sql-jdbc-socket-factory/.kokoro/release/drop.sh"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/release/drop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC
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 | set -eo pipefail
17 |
18 | # STAGING_REPOSITORY_ID must be set
19 | if [ -z "${STAGING_REPOSITORY_ID}" ]; then
20 | echo "Missing STAGING_REPOSITORY_ID environment variable"
21 | exit 1
22 | fi
23 |
24 | source $(dirname "$0")/common.sh
25 | pushd $(dirname "$0")/../../
26 |
27 | setup_environment_secrets
28 | create_settings_xml_file "settings.xml"
29 |
30 | mvn nexus-staging:drop -B \
31 | --settings=settings.xml \
32 | -DstagingRepositoryId=${STAGING_REPOSITORY_ID}
33 |
--------------------------------------------------------------------------------
/.kokoro/release/promote.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "TRAMPOLINE_BUILD_FILE"
5 | value: "github/cloud-sql-jdbc-socket-factory/.kokoro/release/promote.sh"
6 | }
7 |
--------------------------------------------------------------------------------
/.kokoro/release/promote.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC
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 | set -eo pipefail
17 |
18 | # STAGING_REPOSITORY_ID must be set
19 | if [ -z "${STAGING_REPOSITORY_ID}" ]; then
20 | echo "Missing STAGING_REPOSITORY_ID environment variable"
21 | exit 1
22 | fi
23 |
24 | source $(dirname "$0")/common.sh
25 |
26 | pushd $(dirname "$0")/../../
27 |
28 | setup_environment_secrets
29 | create_settings_xml_file "settings.xml"
30 |
31 | mvn nexus-staging:release -B \
32 | -DperformRelease=true \
33 | --settings=settings.xml \
34 | -DstagingRepositoryId=${STAGING_REPOSITORY_ID}
35 |
--------------------------------------------------------------------------------
/.kokoro/release/publish_javadoc.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/doc-templates/"
4 |
5 | env_vars: {
6 | key: "STAGING_BUCKET"
7 | value: "docs-staging"
8 | }
9 |
10 | env_vars: {
11 | key: "TRAMPOLINE_BUILD_FILE"
12 | value: "github/cloud-sql-jdbc-socket-factory/.kokoro/release/publish_javadoc.sh"
13 | }
14 |
15 |
16 | before_action {
17 | fetch_keystore {
18 | keystore_resource {
19 | keystore_config_id: 73713
20 | keyname: "docuploader_service_account"
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.kokoro/release/publish_javadoc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2019 Google LLC
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 | set -eo pipefail
17 |
18 | if [[ -z "${CREDENTIALS}" ]]; then
19 | CREDENTIALS=${KOKORO_KEYSTORE_DIR}/73713_docuploader_service_account
20 | fi
21 |
22 | if [[ -z "${STAGING_BUCKET}" ]]; then
23 | echo "Need to set STAGING_BUCKET environment variable"
24 | exit 1
25 | fi
26 |
27 | # work from the git root directory
28 | pushd $(dirname "$0")/../../
29 |
30 | # install docuploader package
31 | python3 -m pip install --require-hashes -r .kokoro/requirements.txt
32 |
33 | # compile all packages
34 | mvn clean install -B -q -DskipTests=true
35 |
36 | export NAME=jdbc-socket-factory-parent
37 | export VERSION=$(grep ${NAME}: versions.txt | cut -d: -f3)
38 |
39 | # build the docs
40 | mvn site -B -q
41 |
42 | pushd target/site/apidocs
43 |
44 | # create metadata
45 | python3 -m docuploader create-metadata \
46 | --name ${NAME} \
47 | --version ${VERSION} \
48 | --language java
49 |
50 | # upload docs
51 | python3 -m docuploader upload . \
52 | --credentials ${CREDENTIALS} \
53 | --staging-bucket ${STAGING_BUCKET}
54 |
--------------------------------------------------------------------------------
/.kokoro/release/publish_javadoc11.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | # cloud-rad production
4 | env_vars: {
5 | key: "STAGING_BUCKET_V2"
6 | value: "docs-staging-v2"
7 | }
8 |
9 | # Configure the docker image for kokoro-trampoline
10 | env_vars: {
11 | key: "TRAMPOLINE_IMAGE"
12 | value: "gcr.io/cloud-devrel-kokoro-resources/java11"
13 | }
14 |
15 | env_vars: {
16 | key: "TRAMPOLINE_BUILD_FILE"
17 | value: "github/jdbc-socket-factory-parent/.kokoro/release/publish_javadoc11.sh"
18 | }
19 |
20 | before_action {
21 | fetch_keystore {
22 | keystore_resource {
23 | keystore_config_id: 73713
24 | keyname: "docuploader_service_account"
25 | }
26 | }
27 | }
28 |
29 | # Downloads docfx doclet resource. This will be in ${KOKORO_GFILE_DIR}/
30 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/docfx"
31 |
--------------------------------------------------------------------------------
/.kokoro/release/publish_javadoc11.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2023 Google LLC
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 | set -eo pipefail
17 |
18 | if [[ -z "${CREDENTIALS}" ]]; then
19 | CREDENTIALS=${KOKORO_KEYSTORE_DIR}/73713_docuploader_service_account
20 | fi
21 |
22 | if [[ -z "${STAGING_BUCKET_V2}" ]]; then
23 | echo "Need to set STAGING_BUCKET_V2 environment variable"
24 | exit 1
25 | fi
26 |
27 | # work from the git root directory
28 | pushd $(dirname "$0")/../../
29 |
30 | # install docuploader package
31 | python3 -m pip install --require-hashes -r .kokoro/requirements.txt
32 |
33 | # compile all packages
34 | mvn clean install -B -q -DskipTests=true
35 |
36 | export NAME=jdbc-socket-factory-parent
37 | export VERSION=$(grep ${NAME}: versions.txt | cut -d: -f3)
38 |
39 | # cloud RAD generation
40 | mvn clean javadoc:aggregate -B -q -P docFX
41 | # include CHANGELOG
42 | cp CHANGELOG.md target/docfx-yml/history.md
43 |
44 | pushd target/docfx-yml
45 |
46 | # create metadata
47 | python3 -m docuploader create-metadata \
48 | --name ${NAME} \
49 | --version ${VERSION} \
50 | --xrefs devsite://java/gax \
51 | --xrefs devsite://java/google-cloud-core \
52 | --xrefs devsite://java/api-common \
53 | --xrefs devsite://java/proto-google-common-protos \
54 | --xrefs devsite://java/google-api-client \
55 | --xrefs devsite://java/google-http-client \
56 | --xrefs devsite://java/protobuf \
57 | --language java
58 |
59 | # upload yml to production bucket
60 | python3 -m docuploader upload . \
61 | --credentials ${CREDENTIALS} \
62 | --staging-bucket ${STAGING_BUCKET_V2} \
63 | --destination-prefix docfx
64 |
--------------------------------------------------------------------------------
/.kokoro/release/snapshot.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "TRAMPOLINE_BUILD_FILE"
5 | value: "github/jdbc-socket-factory-parent/.kokoro/release/snapshot.sh"
6 | }
7 |
8 |
9 | action {
10 | define_artifacts {
11 | regex: "github/jdbc-socket-factory-parent/.*/target/.*\.jar"
12 | strip_prefix: "github/jdbc-socket-factory-parent"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.kokoro/release/snapshot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2019 Google LLC
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 | set -eo pipefail
17 |
18 | source $(dirname "$0")/common.sh
19 | source $(dirname "$0")/../common.sh
20 | MAVEN_SETTINGS_FILE=$(realpath $(dirname "$0")/../../)/settings.xml
21 | pushd $(dirname "$0")/../../
22 |
23 | # ensure we're trying to push a snapshot (no-result returns non-zero exit code)
24 | grep SNAPSHOT versions.txt
25 |
26 | setup_environment_secrets
27 | create_settings_xml_file "settings.xml"
28 |
29 | mvn clean deploy -B \
30 | --settings ${MAVEN_SETTINGS_FILE} \
31 | -DperformRelease=true \
32 | -Dgpg.executable=gpg \
33 | -Dgpg.passphrase=${GPG_PASSPHRASE} \
34 | -Dgpg.homedir=${GPG_HOMEDIR}
35 |
--------------------------------------------------------------------------------
/.kokoro/release/stage.cfg:
--------------------------------------------------------------------------------
1 | # Format: //devtools/kokoro/config/proto/build.proto
2 |
3 | env_vars: {
4 | key: "TRAMPOLINE_BUILD_FILE"
5 | value: "github/jdbc-socket-factory-parent/.kokoro/release/stage.sh"
6 | }
7 |
8 | # Need to save the properties file
9 | action {
10 | define_artifacts {
11 | regex: "github/jdbc-socket-factory-parent/target/nexus-staging/staging/*.properties"
12 | strip_prefix: "github/jdbc-socket-factory-parent"
13 | }
14 | }
15 |
16 | # Save jar artifacts for SBOM generation
17 | action {
18 | define_artifacts {
19 | regex: "github/jdbc-socket-factory-parent/.*/target/.*\.jar"
20 | strip_prefix: "github/jdbc-socket-factory-parent"
21 | }
22 | }
23 |
24 | env_vars: {
25 | key: "SECRET_MANAGER_KEYS"
26 | value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem"
27 | }
28 |
--------------------------------------------------------------------------------
/.kokoro/release/stage.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2018 Google LLC
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 | set -eo pipefail
17 |
18 | # Start the releasetool reporter
19 | requirementsFile=$(realpath $(dirname "${BASH_SOURCE[0]}")/../requirements.txt)
20 | python3 -m pip install --require-hashes -r $requirementsFile
21 | python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script
22 |
23 | source $(dirname "$0")/common.sh
24 | source $(dirname "$0")/../common.sh
25 | MAVEN_SETTINGS_FILE=$(realpath $(dirname "$0")/../../)/settings.xml
26 | pushd $(dirname "$0")/../../
27 |
28 | setup_environment_secrets
29 | create_settings_xml_file "settings.xml"
30 |
31 | # attempt to stage 3 times with exponential backoff (starting with 10 seconds)
32 | retry_with_backoff 3 10 \
33 | mvn clean deploy -B \
34 | --settings ${MAVEN_SETTINGS_FILE} \
35 | -DskipTests=true \
36 | -Dclirr.skip=true \
37 | -DperformRelease=true \
38 | -Dgpg.executable=gpg \
39 | -Dgpg.passphrase=${GPG_PASSPHRASE} \
40 | -Dgpg.homedir=${GPG_HOMEDIR}
41 |
42 | if [[ -n "${AUTORELEASE_PR}" ]]
43 | then
44 | mvn nexus-staging:release -B \
45 | -DperformRelease=true \
46 | --settings=settings.xml
47 | fi
48 |
--------------------------------------------------------------------------------
/.kokoro/requirements.in:
--------------------------------------------------------------------------------
1 | gcp-docuploader
2 | gcp-releasetool>=1.10.5 # required for compatibility with cryptography>=39.x
3 | wheel
4 | setuptools
5 | typing-extensions
6 | click<8.1.0
7 |
--------------------------------------------------------------------------------
/.kokoro/trampoline.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2019 Google 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 | set -eo pipefail
16 | # Always run the cleanup script, regardless of the success of bouncing into
17 | # the container.
18 | function cleanup() {
19 | chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh
20 | ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh
21 | echo "cleanup";
22 | }
23 | trap cleanup EXIT
24 |
25 | $(dirname $0)/populate-secrets.sh # Secret Manager secrets.
26 | python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py"
27 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 | wrapperVersion=3.3.1
18 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
19 |
--------------------------------------------------------------------------------
/.release/generate_sha.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | # Copyright 2022 Google LLC
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 | touch release_table.md
17 | types=("mysql-socket-factory" "postgres-socket-factory" "jdbc-sqlserver" "r2dbc-mysql" "r2dbc-postgres" "r2dbc-sqlserver")
18 | for t in "${types[@]}"; do
19 | echo "### $t" >> release_table.md
20 | echo "| filename | sha256 hash |" >> release_table.md
21 | echo "|----------|-------------|" >> release_table.md
22 | for f in $(gsutil ls "gs://$BUCKET_NAME/v$VERSION/*$t*"); do
23 | file=$(basename "$f")
24 | sha=$(gsutil cat "$f" | sha256sum --binary | head -c 64)
25 | echo "| [$file](https://storage.googleapis.com/$BUCKET_NAME/v$VERSION/$file) | $sha |" >> release_table.md
26 | done
27 | echo -e "\n\n" >> release_table.md
28 | done
29 |
--------------------------------------------------------------------------------
/.release/snapshot.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | # Copyright 2022 Google LLC
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 | VERSION=$(cat version.txt)
17 | regex="([0-9]+).([0-9]+).([0-9]+)"
18 |
19 | if [[ $VERSION =~ $regex ]]; then
20 | major="${BASH_REMATCH[1]}"
21 | minor="${BASH_REMATCH[2]}"
22 | build="${BASH_REMATCH[3]}"
23 | fi
24 |
25 | build="$(echo $build + 1 | bc)"
26 |
27 | echo "${major}.${minor}.${build}-SNAPSHOT" > version.txt
28 |
--------------------------------------------------------------------------------
/.release/update_versions.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2021 Google 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 | VERSION=$(cat version.txt)
17 | # Update parent pom version
18 | mvn versions:set -DnewVersion=$VERSION -DgenerateBackupPoms=false
19 |
20 | # Update versions in README if not snapshot release
21 | if ! [[ $VERSION =~ .*SNAPSHOT ]]
22 | then
23 | sed -i.bak -E 's/[0-9]+\.[0-9]+\.[0-9]+/'"$VERSION"'/g' docs/*.md
24 | fi
25 |
--------------------------------------------------------------------------------
/.release/upload_uberjars.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2020 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | steps:
16 | - id: jar-with-dependencies
17 | name: maven:3-jdk-11
18 | entrypoint: mvn
19 | args: ["-P", "jar-with-dependencies", "package", "-DskipTests", "-Dmaven.repo.local=/workspace/.m2"]
20 | - id: driver-and-dependencies
21 | name: maven:3-jdk-11
22 | entrypoint: mvn
23 | args: ["-P", "jar-with-driver-and-dependencies", "package", "-DskipTests", "-Dmaven.repo.local=/workspace/.m2"]
24 | artifacts:
25 | objects:
26 | location: "gs://${_BUCKET_NAME}/v${_VERSION}/"
27 | paths:
28 | - "jdbc/postgres/target/*dependencies.jar"
29 | - "jdbc/mysql-j-*/target/*dependencies.jar"
30 | - "jdbc/sqlserver/target/*dependencies.jar"
31 | - "r2dbc/mysql/target/*dependencies.jar"
32 | - "r2dbc/postgres/target/*dependencies.jar"
33 | - "r2dbc/sqlserver/target/*dependencies.jar"
34 |
--------------------------------------------------------------------------------
/.repo-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "api_shortname": "cloud-sql-jdbc-socket-factory",
3 | "name_pretty": "Google Cloud SQL JDBC Socket Factory",
4 | "product_documentation": "https://cloud.google.com/sql",
5 | "release_level": "stable",
6 | "language": "java",
7 | "repo": "GoogleCloudPlatform/cloud-sql-jdbc-socket-factory",
8 | "repo_short": "cloud-sql-jdbc-socket-factory",
9 | "distribution_name": "com.google.cloud.sql:jdbc-socket-factory-parent",
10 | "api_id": "sqladmin.googleapis.com",
11 | "library_type": "OTHER",
12 | "codeowner_team": "@GoogleCloudPlatform/infra-db-sdk"
13 | }
14 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz).
4 |
5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz.
6 |
7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue.
8 |
--------------------------------------------------------------------------------
/checkstyle-suppressions.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
21 |
22 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/AuthType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql;
18 |
19 | /** Enum for supported authentication methods. */
20 | public enum AuthType {
21 | IAM,
22 | PASSWORD
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/ConnectorRegistry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql;
18 |
19 | import com.google.cloud.sql.core.InternalConnectorRegistry;
20 |
21 | /** Configure the CloudSQL JDBC Connector. */
22 | public final class ConnectorRegistry {
23 |
24 | /**
25 | * Register a named connection so that it can later be referenced by name in a JDBC or R2DBC URL.
26 | *
27 | * @param name the named connection name.
28 | * @param config the full configuration of the connection.
29 | */
30 | public static void register(String name, ConnectorConfig config) {
31 | InternalConnectorRegistry.getInstance().register(name, config);
32 | }
33 |
34 | /**
35 | * Close a named connector. This will stop all background credential refresh processes. All future
36 | * attempts to connect via this named connection will fail.
37 | *
38 | * @param name the name of the connector to close.
39 | */
40 | public static void close(String name) {
41 | InternalConnectorRegistry.getInstance().close(name);
42 | }
43 |
44 | /**
45 | * Shutdown the entire CloudSQL JDBC Connector. This will stop all background threads. All future
46 | * attempts to connect to a CloudSQL database will fail.
47 | */
48 | public static void shutdown() {
49 | InternalConnectorRegistry.shutdownInstance();
50 | }
51 |
52 | /**
53 | * Resets the entire CloudSQL JDBC Connector. This will stop all background threads. The next
54 | * attempt to open a connection or register a configuration will start a new ConnectorRegistry.
55 | */
56 | public static void reset() {
57 | InternalConnectorRegistry.resetInstance();
58 | }
59 |
60 | /**
61 | * Adds an external application name to the user agent string for tracking. This is known to be
62 | * used by the spring-cloud-gcp project.
63 | *
64 | * @throws IllegalStateException if the SQLAdmin client has already been initialized
65 | */
66 | public static void addArtifactId(String artifactId) {
67 | InternalConnectorRegistry.addArtifactId(artifactId, false);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/IpType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql;
18 |
19 | /** IP types that for connecting to a Cloud SQL Database. */
20 | public enum IpType {
21 | PUBLIC,
22 | PRIVATE,
23 | PSC;
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/RefreshStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql;
18 |
19 | /** Enum for supported refresh strategies. */
20 | public enum RefreshStrategy {
21 | /** Use the Background refresh strategy. */
22 | BACKGROUND,
23 | /** Use the Lazy refresh strategy. */
24 | LAZY
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/AccessTokenSupplier.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.auth.oauth2.AccessToken;
20 | import java.io.IOException;
21 | import java.util.Optional;
22 |
23 | /** Supplies an AccessToken to use when authenticating with the Google API. */
24 | @FunctionalInterface
25 | interface AccessTokenSupplier {
26 |
27 | /**
28 | * Returns a valid access token or Optional.empty() when no token is available.
29 | *
30 | * @return the access token
31 | * @throws IOException when an error occurs attempting to refresh the token.
32 | */
33 | Optional get() throws IOException;
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ApiClientRetryingCallable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.http.HttpResponseException;
20 | import java.util.concurrent.Callable;
21 |
22 | /**
23 | * Extends RetryingCallable with logic to only retry on HTTP errors with error codes in the 5xx
24 | * range.
25 | *
26 | * @param the return value for Callable
27 | */
28 | class ApiClientRetryingCallable extends RetryingCallable {
29 |
30 | /**
31 | * Construct a new RetryLogic.
32 | *
33 | * @param callable the callable that should be retried
34 | */
35 | public ApiClientRetryingCallable(Callable callable) {
36 | super(callable);
37 | }
38 |
39 | /**
40 | * Returns false indicating that there should be another attempt if the exception is an HTTP
41 | * response with an error code in the 5xx range.
42 | *
43 | * @param e the exception
44 | * @return false if this is a http response with a 5xx status code, otherwise true.
45 | */
46 | @Override
47 | protected boolean isFatalException(Exception e) {
48 | // Only retry if the error is an HTTP response with a 5xx error code.
49 | if (e instanceof HttpResponseException) {
50 | HttpResponseException re = (HttpResponseException) e;
51 | return re.getStatusCode() < 500;
52 | }
53 | // Otherwise this is a fatal exception, no more tries.
54 | return true;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ApplicationDefaultCredentialFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.http.HttpRequestInitializer;
20 | import com.google.api.services.sqladmin.SQLAdminScopes;
21 | import com.google.auth.http.HttpCredentialsAdapter;
22 | import com.google.auth.oauth2.GoogleCredentials;
23 | import com.google.cloud.sql.CredentialFactory;
24 | import java.io.IOException;
25 | import java.util.Arrays;
26 |
27 | /** This class creates a HttpRequestInitializer from Application Default Credentials. */
28 | class ApplicationDefaultCredentialFactory implements CredentialFactory {
29 |
30 | @Override
31 | public HttpRequestInitializer create() {
32 | GoogleCredentials credentials = getCredentials();
33 | return new HttpCredentialsAdapter(credentials);
34 | }
35 |
36 | @Override
37 | public GoogleCredentials getCredentials() {
38 | GoogleCredentials credentials;
39 | try {
40 | credentials = GoogleCredentials.getApplicationDefault();
41 | } catch (IOException err) {
42 | throw new RuntimeException(
43 | "Unable to obtain credentials to communicate with the Cloud SQL API", err);
44 | }
45 |
46 | if (credentials.createScopedRequired()) {
47 | credentials =
48 | credentials.createScoped(
49 | Arrays.asList(SQLAdminScopes.SQLSERVICE_ADMIN, SQLAdminScopes.CLOUD_PLATFORM));
50 | }
51 | return credentials;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/AsyncRateLimiter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.common.util.concurrent.Futures;
20 | import com.google.common.util.concurrent.ListenableFuture;
21 | import java.util.concurrent.ScheduledExecutorService;
22 | import java.util.concurrent.TimeUnit;
23 | import java.util.function.LongSupplier;
24 |
25 | /**
26 | * A simple, constant-time rate limit calculator. Ensures that there is always at least
27 | * delayBetweenAttempts milliseconds between attempts.
28 | */
29 | class AsyncRateLimiter {
30 | private long nextOperationTimestamp;
31 | private final long delayBetweenAttempts;
32 | private final LongSupplier currentTimestampMs;
33 |
34 | /**
35 | * Creates a new AsyncRateLimiter uses the System.currentTimeMillis() as the current time.
36 | *
37 | * @param delayBetweenAttempts the required delay in milliseconds between attempts.
38 | */
39 | AsyncRateLimiter(long delayBetweenAttempts) {
40 | this(delayBetweenAttempts, System::currentTimeMillis);
41 | }
42 |
43 | /**
44 | * Creates a new AsyncRateLimiter which uses a custom function for the current time.
45 | *
46 | * @param delayBetweenAttempts the required delay in milliseconds between attempts.
47 | * @param currentTimestampMs A function that supplies the current time in milliseconds
48 | */
49 | AsyncRateLimiter(long delayBetweenAttempts, LongSupplier currentTimestampMs) {
50 | this.delayBetweenAttempts = delayBetweenAttempts;
51 | this.currentTimestampMs = currentTimestampMs;
52 | }
53 |
54 | /**
55 | * Returns the number of milliseconds to delay before proceeding with the rate limited operation.
56 | * If this returns > 0, the operation must call "acquire" again until it returns 0.
57 | */
58 | private synchronized long nextDelayMs(long nowTimestampMs) {
59 | // allow exactly 1 operation to pass the timestamp.
60 | if (nextOperationTimestamp <= nowTimestampMs) {
61 | nextOperationTimestamp = nowTimestampMs + delayBetweenAttempts;
62 | return 0;
63 | }
64 |
65 | return nextOperationTimestamp - nowTimestampMs;
66 | }
67 |
68 | /**
69 | * Returns a future that will be done when the rate limit has been acquired.
70 | *
71 | * @param executor the executor to use to schedule future checks for available rate limits.
72 | */
73 | public ListenableFuture> acquireAsync(ScheduledExecutorService executor) {
74 | long limit = this.nextDelayMs(currentTimestampMs.getAsLong());
75 | if (limit > 0) {
76 | return Futures.scheduleAsync(
77 | () -> this.acquireAsync(executor), limit, TimeUnit.MILLISECONDS, executor);
78 | }
79 | return Futures.immediateFuture(null);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ConnectionInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.cloud.sql.IpType;
20 | import java.time.Instant;
21 | import java.util.Map;
22 | import java.util.stream.Collectors;
23 | import javax.net.ssl.SSLContext;
24 |
25 | /** Represents the results of a certificate and metadata refresh operation. */
26 | class ConnectionInfo {
27 |
28 | private final InstanceMetadata instanceMetadata;
29 | private final SSLContext sslContext;
30 | private final SslData sslData;
31 | private final Instant expiration;
32 |
33 | ConnectionInfo(InstanceMetadata instanceMetadata, SslData sslData, Instant expiration) {
34 | this.instanceMetadata = instanceMetadata;
35 | this.sslData = sslData;
36 | this.sslContext = sslData.getSslContext();
37 | this.expiration = expiration;
38 | }
39 |
40 | public Instant getExpiration() {
41 | return expiration;
42 | }
43 |
44 | SSLContext getSslContext() {
45 | return sslContext;
46 | }
47 |
48 | Map getIpAddrs() {
49 | return instanceMetadata.getIpAddrs();
50 | }
51 |
52 | SslData getSslData() {
53 | return sslData;
54 | }
55 |
56 | ConnectionMetadata toConnectionMetadata(
57 | ConnectionConfig config, CloudSqlInstanceName instanceName) {
58 | String preferredIp = null;
59 |
60 | for (IpType ipType : config.getIpTypes()) {
61 | preferredIp = getIpAddrs().get(ipType);
62 | if (preferredIp != null) {
63 | break;
64 | }
65 | }
66 | if (preferredIp == null) {
67 | throw new IllegalArgumentException(
68 | String.format(
69 | "[%s] Cloud SQL instance does not have any IP addresses matching preferences (%s)",
70 | instanceName.getConnectionName(),
71 | config.getIpTypes().stream().map(IpType::toString).collect(Collectors.joining(","))));
72 | }
73 |
74 | return new ConnectionMetadata(
75 | preferredIp,
76 | sslData.getKeyManagerFactory(),
77 | sslData.getTrustManagerFactory(),
78 | sslData.getSslContext());
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ConnectionInfoCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | /** ConnectionInfoCache is the contract for a caching strategy for ConnectionInfo. */
20 | interface ConnectionInfoCache {
21 |
22 | /**
23 | * Returns metadata needed to create a connection to the instance.
24 | *
25 | * @return returns ConnectionMetadata containing the preferred IP and SSL connection data.
26 | * @throws IllegalArgumentException If the instance has no IP addresses matching the provided
27 | * preferences.
28 | */
29 | ConnectionMetadata getConnectionMetadata(long timeoutMs);
30 |
31 | void forceRefresh();
32 |
33 | void refreshIfExpired();
34 |
35 | void close();
36 |
37 | boolean isClosed();
38 |
39 | ConnectionConfig getConfig();
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ConnectionInfoRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.cloud.sql.AuthType;
20 | import com.google.common.util.concurrent.ListenableFuture;
21 | import com.google.common.util.concurrent.ListeningScheduledExecutorService;
22 | import java.security.KeyPair;
23 |
24 | /** Internal Use Only: Gets the instance data for the CloudSqlInstance from the API. */
25 | interface ConnectionInfoRepository {
26 | /** Internal Use Only: Gets the instance data for the CloudSqlInstance from the API. */
27 | ListenableFuture getConnectionInfo(
28 | CloudSqlInstanceName instanceName,
29 | AccessTokenSupplier accessTokenSupplier,
30 | AuthType authType,
31 | ListeningScheduledExecutorService executor,
32 | ListenableFuture keyPair);
33 |
34 | ConnectionInfo getConnectionInfoSync(
35 | CloudSqlInstanceName instanceName,
36 | AccessTokenSupplier accessTokenSupplier,
37 | AuthType authType,
38 | KeyPair keyPair);
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ConnectionInfoRepositoryFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.http.HttpRequestInitializer;
20 | import com.google.cloud.sql.ConnectorConfig;
21 |
22 | /** Factory interface for creating SQLAdmin clients to interact with Cloud SQL Admin API. */
23 | interface ConnectionInfoRepositoryFactory {
24 |
25 | ConnectionInfoRepository create(HttpRequestInitializer credentials, ConnectorConfig config);
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ConnectionMetadata.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import javax.net.ssl.KeyManagerFactory;
20 | import javax.net.ssl.SSLContext;
21 | import javax.net.ssl.TrustManagerFactory;
22 |
23 | /**
24 | * A value object containing configuration needed to set up an mTLS connection to a Cloud SQL
25 | * instance.
26 | */
27 | public class ConnectionMetadata {
28 | private final String preferredIpAddress;
29 | private final KeyManagerFactory keyManagerFactory;
30 | private final TrustManagerFactory trustManagerFactory;
31 | private final SSLContext sslContext;
32 |
33 | /** Construct an immutable ConnectionMetadata. */
34 | public ConnectionMetadata(
35 | String preferredIpAddress,
36 | KeyManagerFactory keyManagerFactory,
37 | TrustManagerFactory trustManagerFactory,
38 | SSLContext sslContext) {
39 |
40 | this.preferredIpAddress = preferredIpAddress;
41 | this.keyManagerFactory = keyManagerFactory;
42 | this.trustManagerFactory = trustManagerFactory;
43 | this.sslContext = sslContext;
44 | }
45 |
46 | public String getPreferredIpAddress() {
47 | return preferredIpAddress;
48 | }
49 |
50 | public KeyManagerFactory getKeyManagerFactory() {
51 | return keyManagerFactory;
52 | }
53 |
54 | public TrustManagerFactory getTrustManagerFactory() {
55 | return trustManagerFactory;
56 | }
57 |
58 | public SSLContext getSslContext() {
59 | return sslContext;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ConstantCredentialFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.http.HttpRequestInitializer;
20 | import com.google.auth.http.HttpCredentialsAdapter;
21 | import com.google.auth.oauth2.GoogleCredentials;
22 | import com.google.cloud.sql.CredentialFactory;
23 |
24 | class ConstantCredentialFactory implements CredentialFactory {
25 |
26 | private final GoogleCredentials credentials;
27 |
28 | public ConstantCredentialFactory(GoogleCredentials credentials) {
29 | this.credentials = credentials;
30 | }
31 |
32 | @Override
33 | public HttpRequestInitializer create() {
34 | return new HttpCredentialsAdapter(getCredentials());
35 | }
36 |
37 | @Override
38 | public GoogleCredentials getCredentials() {
39 | return credentials;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/CoreSocketFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Google 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.google.cloud.sql.core;
18 |
19 | /**
20 | * Implementation of informally used Java API to preserve compatibility with older code that uses
21 | * CoreSocketFactory.
22 | *
23 | * @deprecated Use the official java API instead.
24 | * @see com.google.cloud.sql.ConnectorRegistry
25 | */
26 | @SuppressWarnings("InlineMeSuggester")
27 | @Deprecated
28 | public final class CoreSocketFactory {
29 |
30 | /**
31 | * Connection property name.
32 | *
33 | * @deprecated Use the public API instead.
34 | * @see ConnectionConfig#CLOUD_SQL_INSTANCE_PROPERTY
35 | */
36 | @Deprecated
37 | public static final String CLOUD_SQL_INSTANCE_PROPERTY =
38 | ConnectionConfig.CLOUD_SQL_INSTANCE_PROPERTY;
39 |
40 | /**
41 | * Delegates property name.
42 | *
43 | * @deprecated Use the public API instead.
44 | * @see ConnectionConfig#CLOUD_SQL_DELEGATES_PROPERTY
45 | */
46 | @Deprecated
47 | public static final String CLOUD_SQL_DELEGATES_PROPERTY =
48 | ConnectionConfig.CLOUD_SQL_DELEGATES_PROPERTY;
49 |
50 | /**
51 | * TargetPrincipal property name.
52 | *
53 | * @deprecated Use the public API instead.
54 | * @see ConnectionConfig#CLOUD_SQL_TARGET_PRINCIPAL_PROPERTY
55 | */
56 | @Deprecated
57 | public static final String CLOUD_SQL_TARGET_PRINCIPAL_PROPERTY =
58 | ConnectionConfig.CLOUD_SQL_TARGET_PRINCIPAL_PROPERTY;
59 |
60 | /**
61 | * IpTypes default property value.
62 | *
63 | * @deprecated Use the public API instead.
64 | * @see ConnectionConfig#DEFAULT_IP_TYPES
65 | */
66 | @Deprecated public static final String DEFAULT_IP_TYPES = ConnectionConfig.DEFAULT_IP_TYPES;
67 |
68 | /**
69 | * Property used to set the application name for the underlying SQLAdmin client.
70 | *
71 | * @deprecated Use {@link #setApplicationName(String)} to set the application name
72 | * programmatically.
73 | */
74 | @Deprecated
75 | public static final String USER_TOKEN_PROPERTY_NAME =
76 | InternalConnectorRegistry.USER_TOKEN_PROPERTY_NAME;
77 |
78 | /**
79 | * Sets the application name for the user agent.
80 | *
81 | * @deprecated Use the official java API instead.
82 | * @see com.google.cloud.sql.ConnectorRegistry
83 | */
84 | @Deprecated
85 | static void setApplicationName(String artifactId) {
86 | InternalConnectorRegistry.setApplicationName(artifactId);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/DefaultConnectionInfoRepositoryFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
20 | import com.google.api.client.googleapis.services.CommonGoogleClientRequestInitializer;
21 | import com.google.api.client.googleapis.services.GoogleClientRequestInitializer;
22 | import com.google.api.client.http.HttpRequestInitializer;
23 | import com.google.api.client.http.HttpTransport;
24 | import com.google.api.client.json.JsonFactory;
25 | import com.google.api.client.json.gson.GsonFactory;
26 | import com.google.api.services.sqladmin.SQLAdmin;
27 | import com.google.cloud.sql.ConnectorConfig;
28 | import java.io.IOException;
29 | import java.security.GeneralSecurityException;
30 |
31 | /** Factory for creating a SQLAdmin client that interacts with the real SQL Admin API. */
32 | public class DefaultConnectionInfoRepositoryFactory implements ConnectionInfoRepositoryFactory {
33 | private final String userAgents;
34 |
35 | /**
36 | * Initializes a new SQLAdminApiClientFactory class from defaults and provided userAgents.
37 | *
38 | * @param userAgents string representing userAgents for the admin API client
39 | */
40 | public DefaultConnectionInfoRepositoryFactory(String userAgents) {
41 | this.userAgents = userAgents;
42 | }
43 |
44 | @Override
45 | public DefaultConnectionInfoRepository create(
46 | HttpRequestInitializer requestInitializer, ConnectorConfig config) {
47 | SQLAdmin adminApiBuilder = getApiBuilder(requestInitializer, config);
48 | return new DefaultConnectionInfoRepository(adminApiBuilder);
49 | }
50 |
51 | private SQLAdmin getApiBuilder(
52 | HttpRequestInitializer requestInitializer, ConnectorConfig config) {
53 | HttpTransport httpTransport;
54 | try {
55 | httpTransport = GoogleNetHttpTransport.newTrustedTransport();
56 | } catch (GeneralSecurityException | IOException err) {
57 | throw new RuntimeException("Unable to initialize HTTP transport", err);
58 | }
59 |
60 | JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
61 | SQLAdmin.Builder adminApiBuilder =
62 | new SQLAdmin.Builder(httpTransport, jsonFactory, requestInitializer)
63 | .setApplicationName(userAgents);
64 | if (config.getAdminRootUrl() != null) {
65 | adminApiBuilder.setRootUrl(config.getAdminRootUrl());
66 | }
67 | if (config.getAdminServicePath() != null) {
68 | adminApiBuilder.setServicePath(config.getAdminServicePath());
69 | }
70 | if (config.getAdminQuotaProject() != null) {
71 | GoogleClientRequestInitializer clientRequestInitializer =
72 | CommonGoogleClientRequestInitializer.newBuilder()
73 | .setUserProject(config.getAdminQuotaProject())
74 | .build();
75 | adminApiBuilder.setGoogleClientRequestInitializer(clientRequestInitializer);
76 | }
77 | if (config.getUniverseDomain() != null) {
78 | adminApiBuilder.setUniverseDomain(config.getUniverseDomain());
79 | }
80 | return adminApiBuilder.build();
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/DnsInstanceConnectionNameResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Google LLC
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.google.cloud.sql.core;
18 |
19 | import java.util.Collection;
20 | import java.util.Objects;
21 | import javax.naming.NameNotFoundException;
22 | import org.slf4j.Logger;
23 | import org.slf4j.LoggerFactory;
24 |
25 | /**
26 | * An implementation of InstanceConnectionNameResolver that uses DNS TXT records to resolve an
27 | * instance name from a domain name.
28 | */
29 | class DnsInstanceConnectionNameResolver implements InstanceConnectionNameResolver {
30 | private static final Logger logger =
31 | LoggerFactory.getLogger(DnsInstanceConnectionNameResolver.class);
32 |
33 | private final DnsResolver dnsResolver;
34 |
35 | public DnsInstanceConnectionNameResolver(DnsResolver dnsResolver) {
36 | this.dnsResolver = dnsResolver;
37 | }
38 |
39 | @Override
40 | public CloudSqlInstanceName resolve(final String name) {
41 | if (CloudSqlInstanceName.isValidInstanceName(name)) {
42 | // name contains a well-formed instance name.
43 | return new CloudSqlInstanceName(name);
44 | }
45 |
46 | if (CloudSqlInstanceName.isValidDomain(name)) {
47 | // name contains a well-formed domain name.
48 | return resolveDomainName(name);
49 | }
50 |
51 | // name is not well-formed, and therefore cannot be resolved.
52 | throw new IllegalArgumentException(
53 | String.format(
54 | "Unable to resolve database instance for \"%s\". It should be a "
55 | + "well-formed instance name or domain name.",
56 | name));
57 | }
58 |
59 | private CloudSqlInstanceName resolveDomainName(String name) {
60 | // Next, attempt to resolve DNS name.
61 | Collection instanceNames;
62 | try {
63 | instanceNames = this.dnsResolver.resolveTxt(name);
64 | } catch (NameNotFoundException ne) {
65 | // No DNS record found. This is not a valid instance name.
66 | throw new IllegalArgumentException(
67 | String.format(
68 | "Unable to resolve TXT record containing the instance name for "
69 | + "domain name \"%s\".",
70 | name));
71 | }
72 |
73 | // Use the first valid instance name from the list
74 | // or throw an IllegalArgumentException if none of the values can be parsed.
75 | return instanceNames.stream()
76 | .map(
77 | target -> {
78 | try {
79 | return new CloudSqlInstanceName(target, name);
80 | } catch (IllegalArgumentException e) {
81 | logger.info(
82 | "Unable to parse instance name in TXT record for "
83 | + "domain name \"{}\" with target \"{}\"",
84 | name,
85 | target,
86 | e);
87 | return null;
88 | }
89 | })
90 | .filter(Objects::nonNull)
91 | .findFirst()
92 | .orElseThrow(
93 | () ->
94 | new IllegalArgumentException(
95 | String.format("Unable to parse values of TXT record for \"%s\".", name)));
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/DnsResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | import java.util.Collection;
20 | import javax.naming.NameNotFoundException;
21 |
22 | /** Wraps the Java DNS API. */
23 | interface DnsResolver {
24 | Collection resolveTxt(String domainName) throws NameNotFoundException;
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/FileCredentialFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.http.HttpRequestInitializer;
20 | import com.google.api.services.sqladmin.SQLAdminScopes;
21 | import com.google.auth.http.HttpCredentialsAdapter;
22 | import com.google.auth.oauth2.GoogleCredentials;
23 | import com.google.cloud.sql.CredentialFactory;
24 | import java.io.FileInputStream;
25 | import java.io.IOException;
26 | import java.util.Arrays;
27 |
28 | class FileCredentialFactory implements CredentialFactory {
29 | private final String path;
30 |
31 | FileCredentialFactory(String path) {
32 | this.path = path;
33 | }
34 |
35 | @Override
36 | public HttpRequestInitializer create() {
37 | return new HttpCredentialsAdapter(getCredentials());
38 | }
39 |
40 | @Override
41 | public GoogleCredentials getCredentials() {
42 | GoogleCredentials credentials;
43 | try {
44 | credentials = GoogleCredentials.fromStream(new FileInputStream(path));
45 | } catch (IOException e) {
46 | throw new IllegalStateException("Unable to load GoogleCredentials from file " + path, e);
47 | }
48 |
49 | if (credentials.createScopedRequired()) {
50 | credentials =
51 | credentials.createScoped(
52 | Arrays.asList(SQLAdminScopes.SQLSERVICE_ADMIN, SQLAdminScopes.CLOUD_PLATFORM));
53 | }
54 |
55 | return credentials;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/InstanceCheckingTrustManagerFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | import java.io.IOException;
20 | import java.security.KeyStore;
21 | import java.security.KeyStoreException;
22 | import java.security.NoSuchAlgorithmException;
23 | import java.security.cert.Certificate;
24 | import java.security.cert.CertificateException;
25 | import javax.net.ssl.TrustManagerFactory;
26 |
27 | /**
28 | * Implement custom server certificate trust checks specific to Cloud SQL.
29 | *
30 | *
In the JVM, we need to implement 3 classes to make sure that we are capturing all the
31 | * TrustManager instances created by the Java Crypto provider so that the connector will:
32 | *
33 | *
class InstanceCheckingTrustManagerFactory extends TrustManagerFactory - has a bunch of final
34 | * methods that delegate to a TrustManagerFactorySpi.
35 | *
36 | *
class InstanceCheckingTrustManagerFactorySpi implements TrustManagerFactorySpi - can actually
37 | * intercept requests for the list of TrustManager instances and wrap them with our replacement
38 | * TrustManager.
39 | *
40 | *
class ConscryptWorkaroundTrustManager - the workaround for the Conscrypt bug.
41 | *
42 | *
class InstanceCheckingTrustManager - delegates TLS checks to the default provider and then
43 | * does custom hostname verification.
44 | */
45 | class InstanceCheckingTrustManagerFactory extends TrustManagerFactory {
46 |
47 | static InstanceCheckingTrustManagerFactory newInstance(InstanceMetadata instanceMetadata)
48 | throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
49 |
50 | TrustManagerFactory delegate = TrustManagerFactory.getInstance("X.509");
51 | KeyStore trustedKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
52 | trustedKeyStore.load(null, null);
53 |
54 | // Add all the certificates in the chain of trust to the trust keystore.
55 | for (Certificate cert : instanceMetadata.getInstanceCaCertificates()) {
56 | trustedKeyStore.setCertificateEntry("ca" + cert.hashCode(), cert);
57 | }
58 |
59 | // Use a custom trust manager factory that checks the CN against the instance name
60 | // The delegate TrustManagerFactory will check the certificate chain, but will not do
61 | // hostname checking.
62 | InstanceCheckingTrustManagerFactory tmf =
63 | new InstanceCheckingTrustManagerFactory(instanceMetadata, delegate);
64 | tmf.init(trustedKeyStore);
65 |
66 | return tmf;
67 | }
68 |
69 | private InstanceCheckingTrustManagerFactory(
70 | InstanceMetadata instanceMetadata, TrustManagerFactory delegate) {
71 | super(
72 | new InstanceCheckingTrustManagerFactorySpi(instanceMetadata, delegate),
73 | delegate.getProvider(),
74 | delegate.getAlgorithm());
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/InstanceCheckingTrustManagerFactorySpi.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | import java.security.InvalidAlgorithmParameterException;
20 | import java.security.KeyStore;
21 | import java.security.KeyStoreException;
22 | import javax.net.ssl.ManagerFactoryParameters;
23 | import javax.net.ssl.TrustManager;
24 | import javax.net.ssl.TrustManagerFactory;
25 | import javax.net.ssl.TrustManagerFactorySpi;
26 | import javax.net.ssl.X509ExtendedTrustManager;
27 |
28 | /**
29 | * Part of the InstanceCheckingTrustManagerFactory that implements custom CloudSQL server
30 | * certificate checks.
31 | */
32 | class InstanceCheckingTrustManagerFactorySpi extends TrustManagerFactorySpi {
33 | private final TrustManagerFactory delegate;
34 | private final InstanceMetadata instanceMetadata;
35 |
36 | InstanceCheckingTrustManagerFactorySpi(
37 | InstanceMetadata instanceMetadata, TrustManagerFactory delegate) {
38 | this.instanceMetadata = instanceMetadata;
39 | this.delegate = delegate;
40 | }
41 |
42 | @Override
43 | protected void engineInit(KeyStore ks) throws KeyStoreException {
44 | delegate.init(ks);
45 | }
46 |
47 | @Override
48 | protected void engineInit(ManagerFactoryParameters spec)
49 | throws InvalidAlgorithmParameterException {
50 | delegate.init(spec);
51 | }
52 |
53 | @Override
54 | protected TrustManager[] engineGetTrustManagers() {
55 | TrustManager[] tms = delegate.getTrustManagers();
56 | TrustManager[] delegates = new TrustManager[tms.length];
57 | for (int i = 0; i < tms.length; i++) {
58 | if (tms[i] instanceof X509ExtendedTrustManager) {
59 | X509ExtendedTrustManager tm = (X509ExtendedTrustManager) tms[i];
60 |
61 | // Note: This is a workaround for Conscrypt bug #1033
62 | // Conscrypt is the JCE provider on some Google Cloud runtimes like DataProc.
63 | // https://github.com/google/conscrypt/issues/1033
64 | if (ConscryptWorkaroundDelegatingTrustManger.isWorkaroundNeeded()) {
65 | tm = new ConscryptWorkaroundDelegatingTrustManger(tm);
66 | }
67 |
68 | delegates[i] = new InstanceCheckingTrustManger(instanceMetadata, tm);
69 | } else {
70 | delegates[i] = tms[i];
71 | }
72 | }
73 | return delegates;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/InstanceConnectionNameResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2025 Google LLC
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.google.cloud.sql.core;
18 |
19 | /** Resolves the Cloud SQL Instance from the configuration name. */
20 | interface InstanceConnectionNameResolver {
21 |
22 | /**
23 | * Resolves the CloudSqlInstanceName from a configuration string value.
24 | *
25 | * @param name the configuration string
26 | * @return the CloudSqlInstanceName
27 | * @throws IllegalArgumentException if the name cannot be resolved.
28 | */
29 | CloudSqlInstanceName resolve(String name);
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/InstanceMetadata.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.cloud.sql.IpType;
20 | import java.security.cert.Certificate;
21 | import java.util.List;
22 | import java.util.Map;
23 |
24 | /** Represents the results of @link #fetchMetadata(). */
25 | class InstanceMetadata {
26 |
27 | private final CloudSqlInstanceName instanceName;
28 | private final Map ipAddrs;
29 | private final List instanceCaCertificates;
30 | private final boolean casManagedCertificate;
31 | private final String dnsName;
32 | private final boolean pscEnabled;
33 |
34 | InstanceMetadata(
35 | CloudSqlInstanceName instanceName,
36 | Map ipAddrs,
37 | List instanceCaCertificates,
38 | boolean casManagedCertificate,
39 | String dnsName,
40 | boolean pscEnabled) {
41 | this.instanceName = instanceName;
42 | this.ipAddrs = ipAddrs;
43 | this.instanceCaCertificates = instanceCaCertificates;
44 | this.casManagedCertificate = casManagedCertificate;
45 | this.dnsName = dnsName;
46 | this.pscEnabled = pscEnabled;
47 | }
48 |
49 | Map getIpAddrs() {
50 | return ipAddrs;
51 | }
52 |
53 | List getInstanceCaCertificates() {
54 | return instanceCaCertificates;
55 | }
56 |
57 | public boolean isCasManagedCertificate() {
58 | return casManagedCertificate;
59 | }
60 |
61 | public String getDnsName() {
62 | return dnsName;
63 | }
64 |
65 | public boolean isPscEnabled() {
66 | return pscEnabled;
67 | }
68 |
69 | public CloudSqlInstanceName getInstanceName() {
70 | return instanceName;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/JndiDnsResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | import java.util.Collection;
20 | import java.util.Collections;
21 | import java.util.Hashtable;
22 | import java.util.stream.Collectors;
23 | import javax.naming.Context;
24 | import javax.naming.NameNotFoundException;
25 | import javax.naming.NamingException;
26 | import javax.naming.directory.Attribute;
27 | import javax.naming.directory.InitialDirContext;
28 |
29 | /** Implements DnsResolver using the Java JNDI built-in DNS directory. */
30 | class JndiDnsResolver implements DnsResolver {
31 | private final String jndiPrefix;
32 |
33 | /** Creates a resolver using the system DNS settings. */
34 | JndiDnsResolver() {
35 | this.jndiPrefix = "dns:";
36 | }
37 |
38 | /**
39 | * Creates a DNS resolver that uses a specific DNS server.
40 | *
41 | * @param dnsServer the DNS server hostname
42 | * @param port the DNS server port (DNS servers usually use port 53)
43 | */
44 | JndiDnsResolver(String dnsServer, int port) {
45 | this.jndiPrefix = "dns://" + dnsServer + ":" + port + "/";
46 | }
47 |
48 | /**
49 | * Returns DNS records for a domain name, sorted alphabetically.
50 | *
51 | * @param domainName the domain name to lookup
52 | * @return the list of record
53 | * @throws javax.naming.NameNotFoundException when the domain name did not resolve.
54 | */
55 | @Override
56 | @SuppressWarnings("JdkObsolete")
57 | public Collection resolveTxt(String domainName)
58 | throws javax.naming.NameNotFoundException {
59 | try {
60 | // Notice: This is old Java 1.2 style code. It uses the ancient JNDI DNS Provider api.
61 | // See https://docs.oracle.com/javase/7/docs/technotes/guides/jndi/jndi-dns.html
62 |
63 | // Explicitly reference the JNDI DNS classes. This is required for GraalVM.
64 | Hashtable contextProps = new Hashtable<>();
65 | contextProps.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
66 | contextProps.put(Context.OBJECT_FACTORIES, "com.sun.jndi.url.dns.dnsURLContextFactory");
67 | Attribute attr =
68 | new InitialDirContext(contextProps)
69 | .getAttributes(jndiPrefix + domainName, new String[] {"TXT"})
70 | .get("TXT");
71 | // attr.getAll() returns a Vector containing strings, one for each record returned by dns.
72 | return Collections.list(attr.getAll()).stream()
73 | .map((Object v) -> (String) v)
74 | .sorted() // sort multiple records alphabetically
75 | .collect(Collectors.toList());
76 | } catch (NameNotFoundException e) {
77 | throw e;
78 | } catch (NamingException e) {
79 | throw new RuntimeException("Unable to look up domain name " + domainName, e);
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/LazyRefreshConnectionInfoCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | import static com.google.cloud.sql.core.RefreshCalculator.DEFAULT_REFRESH_BUFFER;
20 |
21 | import com.google.cloud.sql.CredentialFactory;
22 | import java.security.KeyPair;
23 |
24 | /**
25 | * Implements the lazy refresh cache strategy, which loads the new certificate as needed during a
26 | * request for a new connection.
27 | */
28 | class LazyRefreshConnectionInfoCache implements ConnectionInfoCache {
29 | private final ConnectionConfig config;
30 | private final CloudSqlInstanceName instanceName;
31 |
32 | private final LazyRefreshStrategy refreshStrategy;
33 |
34 | /**
35 | * Initializes a new Cloud SQL instance based on the given connection name using the lazy refresh
36 | * strategy.
37 | *
38 | * @param config instance connection name in the format "PROJECT_ID:REGION_ID:INSTANCE_ID"
39 | * @param connectionInfoRepository Service class for interacting with the Cloud SQL Admin API
40 | * @param keyPair public/private key pair used to authenticate connections
41 | */
42 | public LazyRefreshConnectionInfoCache(
43 | ConnectionConfig config,
44 | ConnectionInfoRepository connectionInfoRepository,
45 | CredentialFactory tokenSourceFactory,
46 | KeyPair keyPair) {
47 |
48 | CloudSqlInstanceName instanceName =
49 | new CloudSqlInstanceName(config.getCloudSqlInstance(), config.getDomainName());
50 |
51 | this.config = config;
52 | this.instanceName = instanceName;
53 |
54 | AccessTokenSupplier accessTokenSupplier =
55 | DefaultAccessTokenSupplier.newInstance(config.getAuthType(), tokenSourceFactory);
56 |
57 | this.refreshStrategy =
58 | new LazyRefreshStrategy(
59 | config.getCloudSqlInstance(),
60 | () ->
61 | connectionInfoRepository.getConnectionInfoSync(
62 | instanceName, accessTokenSupplier, config.getAuthType(), keyPair),
63 | DEFAULT_REFRESH_BUFFER);
64 | }
65 |
66 | @Override
67 | public ConnectionMetadata getConnectionMetadata(long timeoutMs) {
68 | return refreshStrategy.getConnectionInfo(timeoutMs).toConnectionMetadata(config, instanceName);
69 | }
70 |
71 | @Override
72 | public void forceRefresh() {
73 | refreshStrategy.forceRefresh();
74 | }
75 |
76 | @Override
77 | public void refreshIfExpired() {
78 | refreshStrategy.refreshIfExpired();
79 | }
80 |
81 | @Override
82 | public void close() {
83 | refreshStrategy.close();
84 | }
85 |
86 | @Override
87 | public boolean isClosed() {
88 | return refreshStrategy.isClosed();
89 | }
90 |
91 | @Override
92 | public ConnectionConfig getConfig() {
93 | return config;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/RefreshCalculator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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 | * https://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.google.cloud.sql.core;
18 |
19 | import java.time.Duration;
20 | import java.time.Instant;
21 |
22 | /**
23 | * RefreshCalculator determines the number of seconds until the next refresh operation using the
24 | * same algorithm used by the other Connectors.
25 | */
26 | class RefreshCalculator {
27 |
28 | // defaultRefreshBuffer is the minimum amount of time for which a
29 | // certificate must be valid to ensure the next refresh attempt has adequate
30 | // time to complete.
31 | static final Duration DEFAULT_REFRESH_BUFFER = Duration.ofMinutes(4);
32 |
33 | long calculateSecondsUntilNextRefresh(Instant now, Instant expiration) {
34 | Duration timeUntilExp = Duration.between(now, expiration);
35 |
36 | if (timeUntilExp.compareTo(Duration.ofHours(1)) < 0) {
37 | if (timeUntilExp.compareTo(DEFAULT_REFRESH_BUFFER) < 0) {
38 | // If the time until the certificate expires is less the refresh buffer, schedule the
39 | // refresh immediately
40 | return 0;
41 | }
42 | // Otherwise schedule a refresh in (timeUntilExp - buffer) seconds
43 | return timeUntilExp.minus(DEFAULT_REFRESH_BUFFER).getSeconds();
44 | }
45 |
46 | // If the time until the certificate expires is longer than an hour, return timeUntilExp//2
47 | return timeUntilExp.dividedBy(2).getSeconds();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/RefreshStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | /** Provide the refresh strategy to the DefaultConnectionInfoCache. */
20 | public interface RefreshStrategy {
21 | /** Return the current valid ConnectionInfo, blocking if necessary for up to the timeout. */
22 | ConnectionInfo getConnectionInfo(long timeoutMs);
23 |
24 | /** Force a refresh of the ConnectionInfo, possibly in the background. */
25 | void forceRefresh();
26 |
27 | /** Refresh the ConnectionInfo if it has expired or is near expiration. */
28 | void refreshIfExpired();
29 |
30 | /**
31 | * Stop background threads and refresh operations in progress and refuse to start subsequent
32 | * refresh operations.
33 | */
34 | void close();
35 |
36 | /** Returns true when the RefreshStrategy instance is closed. */
37 | boolean isClosed();
38 | }
39 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/ServiceAccountImpersonatingCredentialFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.http.HttpRequestInitializer;
20 | import com.google.api.services.sqladmin.SQLAdminScopes;
21 | import com.google.auth.http.HttpCredentialsAdapter;
22 | import com.google.auth.oauth2.GoogleCredentials;
23 | import com.google.auth.oauth2.ImpersonatedCredentials;
24 | import com.google.cloud.sql.CredentialFactory;
25 | import java.util.Arrays;
26 | import java.util.List;
27 |
28 | /**
29 | * Wraps an existing CredentialFactory to impersonate the targetPrincipal, with an optional list of
30 | * delegating service accounts in accordance with the ImpersonatedCredentials API.
31 | *
32 | *
targetPrincipal – the service account to impersonate
33 | *
34 | *
delegates – the chained list of delegates required to grant the final access_token. If set,
35 | * the sequence of identities must have "Service Account Token Creator" capability granted to the
36 | * preceding identity. For example, if set to [serviceAccountB, serviceAccountC], the
37 | * sourceCredential must have the Token Creator role on serviceAccountB. serviceAccountB must have
38 | * the Token Creator on serviceAccountC. Finally, C must have Token Creator on target_principal. If
39 | * unset, sourceCredential must have that role on targetPrincipal.
40 | *
41 | * @see com.google.auth.oauth2.ImpersonatedCredentials
42 | */
43 | class ServiceAccountImpersonatingCredentialFactory implements CredentialFactory {
44 |
45 | private final CredentialFactory source;
46 | private final List delegates;
47 | private final String targetPrincipal;
48 |
49 | /**
50 | * Creates a new ServiceAccountImpersonatingCredentialFactory.
51 | *
52 | * @param source the source of the original credentials, before they are impersonated.
53 | * @param targetPrincipal The target principal in the form of a service account, must not be null.
54 | * @param delegates The optional list of delegate service accounts, may be null or empty.
55 | */
56 | ServiceAccountImpersonatingCredentialFactory(
57 | CredentialFactory source, String targetPrincipal, List delegates) {
58 | if (targetPrincipal == null || targetPrincipal.isEmpty()) {
59 | throw new IllegalArgumentException("targetPrincipal must not be empty");
60 | }
61 | this.source = source;
62 | this.delegates = delegates;
63 | this.targetPrincipal = targetPrincipal;
64 | }
65 |
66 | @Override
67 | public HttpRequestInitializer create() {
68 | GoogleCredentials credentials = getCredentials();
69 | return new HttpCredentialsAdapter(credentials);
70 | }
71 |
72 | @Override
73 | public GoogleCredentials getCredentials() {
74 | GoogleCredentials credentials = source.getCredentials();
75 |
76 | credentials =
77 | ImpersonatedCredentials.newBuilder()
78 | .setSourceCredentials(credentials)
79 | .setTargetPrincipal(targetPrincipal)
80 | .setDelegates(this.delegates)
81 | .setScopes(
82 | Arrays.asList(SQLAdminScopes.SQLSERVICE_ADMIN, SQLAdminScopes.CLOUD_PLATFORM))
83 | .build();
84 | return credentials;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/SslData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Google LLC
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.google.cloud.sql.core;
18 |
19 | import javax.net.ssl.KeyManagerFactory;
20 | import javax.net.ssl.SSLContext;
21 | import javax.net.ssl.TrustManagerFactory;
22 |
23 | /** This class stores data that can be used to establish Cloud SQL SSL connection. */
24 | class SslData {
25 |
26 | private final SSLContext sslContext;
27 | private final KeyManagerFactory keyManagerFactory;
28 | private final TrustManagerFactory trustManagerFactory;
29 |
30 | SslData(
31 | SSLContext sslContext,
32 | KeyManagerFactory keyManagerFactory,
33 | TrustManagerFactory trustManagerFactory) {
34 | this.sslContext = sslContext;
35 | this.keyManagerFactory = keyManagerFactory;
36 | this.trustManagerFactory = trustManagerFactory;
37 | }
38 |
39 | SSLContext getSslContext() {
40 | return sslContext;
41 | }
42 |
43 | KeyManagerFactory getKeyManagerFactory() {
44 | return keyManagerFactory;
45 | }
46 |
47 | TrustManagerFactory getTrustManagerFactory() {
48 | return trustManagerFactory;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/SupplierCredentialFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.http.HttpRequestInitializer;
20 | import com.google.auth.http.HttpCredentialsAdapter;
21 | import com.google.auth.oauth2.GoogleCredentials;
22 | import com.google.cloud.sql.CredentialFactory;
23 | import java.util.function.Supplier;
24 |
25 | class SupplierCredentialFactory implements CredentialFactory {
26 |
27 | private final Supplier supplier;
28 |
29 | public SupplierCredentialFactory(Supplier supplier) {
30 | this.supplier = supplier;
31 | }
32 |
33 | @Override
34 | public HttpRequestInitializer create() {
35 | return new HttpCredentialsAdapter(getCredentials());
36 | }
37 |
38 | @Override
39 | public GoogleCredentials getCredentials() {
40 | return supplier.get();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/TerminalException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | class TerminalException extends RuntimeException {
20 | public TerminalException() {
21 | super();
22 | }
23 |
24 | public TerminalException(String message) {
25 | super(message);
26 | }
27 |
28 | public TerminalException(String message, Throwable cause) {
29 | super(message, cause);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/core/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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 | /**
18 | * WARNING: This package does not contain any stable, public Java API. The class definitions may
19 | * change without notice.
20 | *
21 | *
Package com.google.cloud.sql.core holds internal shared packages that implement logic to
22 | * create a socket to a Cloud SQL database.
23 | */
24 | package com.google.cloud.sql.core;
25 |
--------------------------------------------------------------------------------
/core/src/main/java/com/google/cloud/sql/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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 | /**
18 | * Package com.google.cloud.sql holds the stable public java API for creating sockets to Cloud SQL
19 | * database.
20 | */
21 | package com.google.cloud.sql;
22 |
--------------------------------------------------------------------------------
/core/src/main/resources/META-INF/native-image/com.google.cloud.sql/cloud-sql-jdbc-socket-factory-parent/jni-unix-socket-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "jnr.ffi.provider.LoadedLibrary"
4 | },
5 | {
6 | "name": "jnr.unixsocket.Native$LibC",
7 | "interfaces": [
8 | "jnr.unixsocket.Native$LibC",
9 | "jnr.ffi.provider.LoadedLibrary"
10 | ]
11 | },
12 | {
13 | "name": "jnr.enxio.channels.Native$LibC",
14 | "interfaces": [
15 | "jnr.enxio.channels.Native$LibC",
16 | "jnr.ffi.provider.LoadedLibrary"
17 | ]
18 | }
19 | ]
20 |
--------------------------------------------------------------------------------
/core/src/main/resources/META-INF/native-image/com.google.cloud.sql/cloud-sql-jdbc-socket-factory-parent/native-image.properties:
--------------------------------------------------------------------------------
1 | Args =\
2 | -H:+AddAllCharsets \
3 | -H:ReflectionConfigurationResources=META-INF/native-image/com.google.cloud.sql/cloud-sql-jdbc-socket-factory-parent/jni-unix-socket-config.json \
4 | -H:ResourceConfigurationResources=META-INF/native-image/com.google.cloud.sql/cloud-sql-jdbc-socket-factory-parent/resource-config.json \
5 | -H:DynamicProxyConfigurationResources=META-INF/native-image/com.google.cloud.sql/cloud-sql-jdbc-socket-factory-parent/proxy-config.json \
6 | --features=com.google.cloud.sql.nativeimage.CloudSqlFeature
7 |
--------------------------------------------------------------------------------
/core/src/main/resources/META-INF/native-image/com.google.cloud.sql/cloud-sql-jdbc-socket-factory-parent/proxy-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "condition": {
4 | "typeReachable": "jnr.unixsocket.Native$LibC"
5 | },
6 | "name": "jnr.unixsocket.Native$LibC",
7 | "interfaces": [
8 | "jnr.unixsocket.Native$LibC",
9 | "jnr.ffi.provider.LoadedLibrary"
10 | ]
11 | },
12 | {
13 | "condition": {
14 | "typeReachable":"jnr.enxio.channels.Native$LibC"
15 | },
16 | "name": "jnr.enxio.channels.Native$LibC",
17 | "interfaces": [
18 | "jnr.enxio.channels.Native$LibC",
19 | "jnr.ffi.provider.LoadedLibrary"
20 | ]
21 | },
22 | {
23 | "name": "com.sun.jndi.dns.DnsContextFactory",
24 | "interfaces": [
25 | "javax.naming.spi.InitialContextFactory"
26 | ]
27 | },
28 | {
29 | "name": "com.sun.jndi.url.dns.dnsURLContextFactory",
30 | "interfaces": [
31 | "javax.naming.spi.ObjectFactory"
32 | ]
33 | }
34 | ]
35 |
--------------------------------------------------------------------------------
/core/src/main/resources/META-INF/native-image/com.google.cloud.sql/cloud-sql-jdbc-socket-factory-parent/resource-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "resources":[
3 | {"pattern":"\\Qcom.google.cloud.sql/project.properties\\E"},
4 | {"pattern":"\\QMETA-INF/services/java.sql.Driver\\E"},
5 | {"pattern":"\\Qcom/mysql/cj/util/TimeZoneMapping.properties\\E"},
6 | {"pattern":"jni/.*\\.so"},
7 | {"pattern":"jni/.*\\.dll"}
8 | ],
9 | "bundles": [
10 | {"name":"com.mysql.cj.LocalizedErrorMessages"},
11 | {"name":"com.mysql.jdbc.LocalizedErrorMessages"}
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/main/resources/com.google.cloud.sql/project.properties:
--------------------------------------------------------------------------------
1 | version=${project.version}
--------------------------------------------------------------------------------
/core/src/test/java/com/google/cloud/sql/core/ApiClientRetryingCallableTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | import static com.google.common.truth.Truth.assertThat;
20 |
21 | import com.google.api.client.http.HttpHeaders;
22 | import com.google.api.client.http.HttpResponseException;
23 | import java.util.concurrent.atomic.AtomicInteger;
24 | import org.junit.Assert;
25 | import org.junit.Test;
26 | import org.junit.runner.RunWith;
27 | import org.junit.runners.JUnit4;
28 |
29 | @RunWith(JUnit4.class)
30 | public class ApiClientRetryingCallableTest {
31 | @Test
32 | public void testApiClientRetriesOn500ErrorAndSucceeds() throws Exception {
33 | AtomicInteger counter = new AtomicInteger(0);
34 | ApiClientRetryingCallable c =
35 | new ApiClientRetryingCallable<>(
36 | () -> {
37 | int attempt = counter.incrementAndGet();
38 | if (attempt < 3) {
39 | throw new HttpResponseException.Builder(
40 | 503, "service unavailable", new HttpHeaders())
41 | .build();
42 | }
43 | return attempt;
44 | });
45 |
46 | Integer v = c.call();
47 | assertThat(counter.get()).isEqualTo(3);
48 | assertThat(v).isEqualTo(3);
49 | }
50 |
51 | @Test
52 | public void testApiClientRetriesOn500ErrorAndFailsAfter5Attempts() throws Exception {
53 | AtomicInteger counter = new AtomicInteger(0);
54 | ApiClientRetryingCallable c =
55 | new ApiClientRetryingCallable<>(
56 | () -> {
57 | counter.incrementAndGet();
58 | throw new HttpResponseException.Builder(503, "service unavailable", new HttpHeaders())
59 | .build();
60 | });
61 |
62 | try {
63 | c.call();
64 | Assert.fail("got no exception, wants an exception to be thrown");
65 | } catch (Exception e) {
66 | // Expected to throw an exception
67 | }
68 | assertThat(counter.get()).isEqualTo(5);
69 | }
70 |
71 | @Test
72 | public void testRetryStopsAfterFatalException() throws Exception {
73 | final AtomicInteger counter = new AtomicInteger();
74 | RetryingCallable r =
75 | new RetryingCallable(
76 | () -> {
77 | counter.incrementAndGet();
78 | throw new Exception("nope");
79 | }) {
80 | @Override
81 | protected boolean isFatalException(Exception e) {
82 | return true;
83 | }
84 | };
85 |
86 | try {
87 | r.call();
88 | Assert.fail("got no exception, wants an exception to be thrown");
89 | } catch (Exception e) {
90 | // Expected to throw an exception
91 | }
92 | assertThat(counter.get()).isEqualTo(1);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/core/src/test/java/com/google/cloud/sql/core/BadConnectionFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import com.google.api.client.http.HttpTransport;
20 | import com.google.api.client.http.LowLevelHttpRequest;
21 | import com.google.api.client.http.LowLevelHttpResponse;
22 | import java.io.IOException;
23 | import java.net.SocketTimeoutException;
24 |
25 | public class BadConnectionFactory extends HttpTransport {
26 |
27 | @Override
28 | protected LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
29 | return new FailToConnectRequest();
30 | }
31 |
32 | private static class FailToConnectRequest extends LowLevelHttpRequest {
33 |
34 | @Override
35 | public void addHeader(String name, String value) throws IOException {
36 | // do nothing.
37 | }
38 |
39 | @Override
40 | public LowLevelHttpResponse execute() throws IOException {
41 | try {
42 | Thread.sleep(100);
43 | } catch (InterruptedException e) {
44 | // Ignore the interruption
45 | }
46 | throw new SocketTimeoutException("Fake connect timeout");
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/core/src/test/java/com/google/cloud/sql/core/CloudSqlInstanceNameTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import static com.google.common.truth.Truth.assertThat;
20 | import static org.junit.Assert.assertThrows;
21 |
22 | import org.junit.Assert;
23 | import org.junit.Test;
24 | import org.junit.runner.RunWith;
25 | import org.junit.runners.JUnit4;
26 |
27 | @RunWith(JUnit4.class)
28 | public class CloudSqlInstanceNameTest {
29 |
30 | @Test
31 | public void parseStandardConnectionName() {
32 | String connectionName = "my-project:my-region:my-instance";
33 |
34 | CloudSqlInstanceName instanceName = new CloudSqlInstanceName(connectionName);
35 |
36 | Assert.assertEquals(connectionName, instanceName.getConnectionName());
37 | Assert.assertEquals("my-project", instanceName.getProjectId());
38 | Assert.assertEquals("my-region", instanceName.getRegionId());
39 | Assert.assertEquals("my-instance", instanceName.getInstanceId());
40 | }
41 |
42 | @Test
43 | public void parseLegacyConnectionName() {
44 | String connectionName = "google.com:my-project:my-region:my-instance";
45 |
46 | CloudSqlInstanceName instanceName = new CloudSqlInstanceName(connectionName);
47 |
48 | Assert.assertEquals(instanceName.getConnectionName(), connectionName);
49 | Assert.assertEquals("google.com:my-project", instanceName.getProjectId());
50 | Assert.assertEquals("my-region", instanceName.getRegionId());
51 | Assert.assertEquals("my-instance", instanceName.getInstanceId());
52 | }
53 |
54 | @Test
55 | public void parseBadConnectionName() {
56 | IllegalArgumentException ex =
57 | assertThrows(
58 | IllegalArgumentException.class,
59 | () -> new CloudSqlInstanceName("my-project:my-instance"));
60 |
61 | assertThat(ex).hasMessageThat().contains("Cloud SQL connection name is invalid");
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/core/src/test/java/com/google/cloud/sql/core/ConstantCredentialsFactoryTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import static com.google.common.truth.Truth.assertThat;
20 |
21 | import com.google.auth.oauth2.GoogleCredentials;
22 | import org.junit.Test;
23 | import org.junit.runner.RunWith;
24 | import org.junit.runners.JUnit4;
25 |
26 | @RunWith(JUnit4.class)
27 | public class ConstantCredentialsFactoryTest {
28 |
29 | @Test
30 | public void testConstantCredentials() {
31 | GoogleCredentials c = GoogleCredentials.create(null);
32 | ConstantCredentialFactory f = new ConstantCredentialFactory(c);
33 | assertThat(f.getCredentials()).isSameInstanceAs(c);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/core/src/test/java/com/google/cloud/sql/core/DefaultConnectionInfoRepositoryIntegrationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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.google.cloud.sql.core;
18 |
19 | import static com.google.common.truth.Truth.assertThat;
20 | import static com.google.common.truth.Truth.assertWithMessage;
21 |
22 | import com.google.cloud.sql.ConnectorConfig;
23 | import com.google.cloud.sql.CredentialFactory;
24 | import com.google.common.collect.ImmutableList;
25 | import java.util.concurrent.TimeUnit;
26 | import org.junit.BeforeClass;
27 | import org.junit.Rule;
28 | import org.junit.Test;
29 | import org.junit.rules.Timeout;
30 | import org.junit.runner.RunWith;
31 | import org.junit.runners.JUnit4;
32 |
33 | @RunWith(JUnit4.class)
34 | public class DefaultConnectionInfoRepositoryIntegrationTests {
35 | private static final String QUOTA_PROJECT = System.getenv("QUOTA_PROJECT");
36 | private static final String CONNECTION_NAME = System.getenv("MYSQL_CONNECTION_NAME");
37 |
38 | private static final ImmutableList requiredEnvVars =
39 | ImmutableList.of("QUOTA_PROJECT", "MYSQL_CONNECTION_NAME");
40 | @Rule public Timeout globalTimeout = new Timeout(80, TimeUnit.SECONDS);
41 |
42 | @BeforeClass
43 | public static void checkEnvVars() {
44 | // Check that required env vars are set
45 | requiredEnvVars.forEach(
46 | (varName) ->
47 | assertWithMessage(
48 | String.format(
49 | "Environment variable '%s' must be set to perform these tests.", varName))
50 | .that(System.getenv(varName))
51 | .isNotEmpty());
52 | }
53 |
54 | @Test
55 | public void testQuotaProjectIsSetOnAdminApiRequest() {
56 | ConnectorConfig config =
57 | new ConnectorConfig.Builder().withAdminQuotaProject(QUOTA_PROJECT).build();
58 |
59 | CredentialFactoryProvider credentialFactoryProvider = new CredentialFactoryProvider();
60 | CredentialFactory instanceCredentialFactory =
61 | credentialFactoryProvider.getInstanceCredentialFactory(config);
62 | DefaultConnectionInfoRepository repo =
63 | new DefaultConnectionInfoRepositoryFactory("cloud-sql-connector-connector-core")
64 | .create(instanceCredentialFactory.create(), config);
65 |
66 | assertThat(repo.getQuotaProject(CONNECTION_NAME)).isEqualTo(QUOTA_PROJECT);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/core/src/test/java/com/google/cloud/sql/core/FileCredentialFactoryTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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.google.cloud.sql.core;
18 |
19 | import static com.google.common.truth.Truth.assertThat;
20 | import static org.junit.Assert.*;
21 |
22 | import com.google.auth.oauth2.GoogleCredentials;
23 | import org.junit.Test;
24 | import org.junit.runner.RunWith;
25 | import org.junit.runners.JUnit4;
26 |
27 | @RunWith(JUnit4.class)
28 | public class FileCredentialFactoryTest {
29 |
30 | @Test
31 | public void getCredentials_failsWhenNoFileExists() {
32 | FileCredentialFactory f = new FileCredentialFactory("nope");
33 | assertThrows(IllegalStateException.class, f::getCredentials);
34 | }
35 |
36 | @Test
37 | public void getCredentials_loadsFromFilePath() {
38 | String path = FileCredentialFactoryTest.class.getResource("/sample-credentials.json").getFile();
39 | FileCredentialFactory f = new FileCredentialFactory(path);
40 | GoogleCredentials c = f.getCredentials();
41 | assertThat(c.getQuotaProjectId()).isEqualTo("sample");
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/core/src/test/java/com/google/cloud/sql/core/LazyRefreshConnectionInfoCacheTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
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 | package com.google.cloud.sql.core;
17 |
18 | import static com.google.common.truth.Truth.assertThat;
19 |
20 | import com.google.common.util.concurrent.Futures;
21 | import com.google.common.util.concurrent.ListenableFuture;
22 | import java.security.KeyPair;
23 | import java.util.concurrent.ExecutionException;
24 | import org.junit.Before;
25 | import org.junit.Test;
26 | import org.junit.runner.RunWith;
27 | import org.junit.runners.JUnit4;
28 |
29 | @RunWith(JUnit4.class)
30 | public class LazyRefreshConnectionInfoCacheTest {
31 | private ListenableFuture keyPairFuture;
32 | private final StubCredentialFactory stubCredentialFactory =
33 | new StubCredentialFactory("my-token", System.currentTimeMillis() + 3600L);
34 |
35 | @Before
36 | public void setup() throws Exception {
37 | MockAdminApi mockAdminApi = new MockAdminApi();
38 | this.keyPairFuture = Futures.immediateFuture(mockAdminApi.getClientKeyPair());
39 | }
40 |
41 | @Test
42 | public void testCloudSqlInstanceDataLazyStrategyRetrievedSuccessfully()
43 | throws ExecutionException, InterruptedException {
44 | KeyPair kp = keyPairFuture.get();
45 | TestDataSupplier instanceDataSupplier = new TestDataSupplier(false);
46 |
47 | // initialize connectionInfoCache after mocks are set up
48 | LazyRefreshConnectionInfoCache connectionInfoCache =
49 | new LazyRefreshConnectionInfoCache(
50 | new ConnectionConfig.Builder().withCloudSqlInstance("project:region:instance").build(),
51 | instanceDataSupplier,
52 | stubCredentialFactory,
53 | kp);
54 |
55 | ConnectionMetadata gotMetadata = connectionInfoCache.getConnectionMetadata(300);
56 | ConnectionMetadata gotMetadata2 = connectionInfoCache.getConnectionMetadata(300);
57 |
58 | // Assert that the underlying ConnectionInfo was retrieved exactly once.
59 | assertThat(instanceDataSupplier.counter.get()).isEqualTo(1);
60 |
61 | // Assert that the ConnectionInfo fields are added to ConnectionMetadata
62 | assertThat(gotMetadata.getKeyManagerFactory())
63 | .isSameInstanceAs(instanceDataSupplier.response.getSslData().getKeyManagerFactory());
64 | assertThat(gotMetadata.getKeyManagerFactory())
65 | .isSameInstanceAs(gotMetadata2.getKeyManagerFactory());
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/core/src/test/java/com/google/cloud/sql/core/RefreshCalculatorTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
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 | * https://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 | package com.google.cloud.sql.core;
17 |
18 | import static com.google.common.truth.Truth.assertThat;
19 | import static java.time.temporal.ChronoUnit.SECONDS;
20 |
21 | import java.time.Duration;
22 | import java.time.Instant;
23 | import java.util.Arrays;
24 | import java.util.Collection;
25 | import org.junit.Test;
26 | import org.junit.runner.RunWith;
27 | import org.junit.runners.Parameterized;
28 | import org.junit.runners.Parameterized.Parameters;
29 |
30 | @RunWith(Parameterized.class)
31 | public class RefreshCalculatorTest {
32 |
33 | private final Duration input;
34 | private final Duration want;
35 |
36 | @Parameters(name = "Test {0}: calculateSecondsUntilNextRefresh({1})={2}")
37 | public static Collection