├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── .settings.xml
├── .travis.yml
├── LICENSE
├── README.md
├── RELEASE.md
├── header.txt
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
├── main
│ ├── java
│ │ └── io
│ │ │ └── opentracing
│ │ │ └── contrib
│ │ │ └── jdbc
│ │ │ ├── ConnectionInfo.java
│ │ │ ├── JdbcTracing.java
│ │ │ ├── JdbcTracingUtils.java
│ │ │ ├── TracingCallableStatement.java
│ │ │ ├── TracingConnection.java
│ │ │ ├── TracingDataSource.java
│ │ │ ├── TracingDriver.java
│ │ │ ├── TracingPreparedStatement.java
│ │ │ ├── TracingStatement.java
│ │ │ └── parser
│ │ │ ├── AS400URLParser.java
│ │ │ ├── AbstractMatcherURLParser.java
│ │ │ ├── AbstractURLParser.java
│ │ │ ├── ConnectionURLParser.java
│ │ │ ├── DB2URLParser.java
│ │ │ ├── H2URLParser.java
│ │ │ ├── MariadbURLParser.java
│ │ │ ├── MysqlURLParser.java
│ │ │ ├── OracleURLParser.java
│ │ │ ├── PostgreSQLURLParser.java
│ │ │ ├── SqlServerURLParser.java
│ │ │ ├── URLLocation.java
│ │ │ └── URLParser.java
│ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── java.sql.Driver
└── test
│ ├── java
│ └── io
│ │ └── opentracing
│ │ └── contrib
│ │ └── jdbc
│ │ ├── HibernateTest.java
│ │ ├── JdbcTest.java
│ │ ├── JdbcTracingUtilsTest.java
│ │ ├── SpringTest.java
│ │ ├── TestUtil.java
│ │ ├── TracingDataSourceTest.java
│ │ ├── TracingDriverTest.java
│ │ └── parser
│ │ ├── AS400URLParserTest.java
│ │ ├── DB2URLParserTest.java
│ │ ├── OracleURLParserTest.java
│ │ ├── SqlServerURLParserTest.java
│ │ └── URLParserTest.java
│ └── resources
│ └── META-INF
│ └── persistence.xml
└── travis
└── publish.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .metadata/
3 | .recommenders/
4 | .settings/
5 | target/
6 | *.iml
7 | .classpath
8 | .project
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opentracing-contrib/java-jdbc/6722745cbbd61fce8550dd8e1e0d8a828a1e7a3c/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
--------------------------------------------------------------------------------
/.settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
21 |
22 |
23 | sonatype
24 | ${env.SONATYPE_USER}
25 | ${env.SONATYPE_PASSWORD}
26 |
27 |
28 | bintray
29 | ${env.BINTRAY_USER}
30 | ${env.BINTRAY_KEY}
31 |
32 |
33 | jfrog-snapshots
34 | ${env.BINTRAY_USER}
35 | ${env.BINTRAY_KEY}
36 |
37 |
38 | github.com
39 | ${env.GH_USER}
40 | ${env.GH_TOKEN}
41 |
42 |
43 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 |
3 | language: java
4 | jdk:
5 | - oraclejdk8
6 |
7 | cache:
8 | directories:
9 | - $HOME/.m2/repository
10 |
11 | before_install:
12 | # allocate commits to CI, not the owner of the deploy key
13 | - git config user.name "opentracingci"
14 | - git config user.email "opentracingci+opentracing@googlegroups.com"
15 |
16 | # setup https authentication credentials, used by ./mvnw release:prepare
17 | - git config credential.helper "store --file=.git/credentials"
18 | - echo "https://$GH_TOKEN:@github.com" > .git/credentials
19 |
20 | install:
21 | # Override default travis to use the maven wrapper
22 | - ./mvnw install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
23 |
24 | script:
25 | - ./travis/publish.sh
26 |
27 | branches:
28 | except:
29 | - /^[0-9]/
30 |
31 | after_success:
32 | - mvn jacoco:report coveralls:report
33 |
34 | env:
35 | global:
36 | # Ex. travis encrypt BINTRAY_USER=your_github_account
37 | - secure: "hVicpP51WpEErSDy8ThcZ8zJhrQ/+8Mg9NiGT6IBxAuWDH6jQ2BIyYJ5oc/h7TRW2CYiAzBe0Qzd38Ifpw5gH6WHCK1qJiAuO+qjvNh5h5TeVaKUJHs2JPPHYM0WZMMQKpPTmcNi+EkozVTsef5hoX+tv0/WEVwCqJvRA6xelL37/kaTxmZJDq570RG6fFmAsfQFuN+PvFn1SutvIXkseetyKXtr+KvPaLniomOxdmVvzU60RMhxwaacmlRzu1D9uzGEDPmagW8iDB/byuBlZAyQVMMusZwbHSxqH471hNCU/PEg8NysmR0ZuRSonFOUu5RoERz9tLfUTV3PHgnNj/ZqlzABYfVuCIsB4led3uaEgb+en3fbWPFLr4YvTe2pqH7k7XNJELqvgfC2cCBu1cEtPq0bIZiDvz9i+qqUxUPrzkku2XKGf58bJz3UKmLECAC3VEMYE+z/PdjBD6FXK5ynfeWJH2q0MZqiVSqv4XSJn1BnOabINqy2xxnWk4EkfZQhqT70HPZ8AQEppgwDbtqCBdoD3ySNipq7FGJ/hGpmUqKh9E7JBSOLjyyix1ExKYlqglFAYOSgQOHSuVMFBi1GnbFzfKX22dwrN2gJHAx7FezEIxlbM6+ZBpC3DHjTaFlRAcAlE6Ci5KNkv1VnjtooijTPGawDNranRLVnlds="
38 | # Ex. travis encrypt BINTRAY_KEY=xxx-https://bintray.com/profile/edit-xxx --add
39 | - secure: "eyYuOFs7rnWnLnZFrkPsY9fuxPQq9W192vCoEOHzqtfkOHNFJkqwx1H1CWviZHbLVZl7qn0MpI/d3cQ93KgoKHJd1nRKEjBmm32bFg8BGXFhQA0r2/ylNjcZO7sZbJd2L+JK8U+O7hnQF+FJ5Gftn9aIRBxIiV/oJuelHWXEqFLv0Zgh+yVSc/aPzianAv9BcczpGGcO6K64gNMvg1HsIpK2VDw4DMyXkHFmw48BIvzDKgTVFkMKuy2UBSg2O1rqUCfAeoVn4VhF3R4Mrm+NyeCVGkmoL++ZIW9cp7hLsWiLac6AGhdujHEnUhJDd/KtiOoYQR0+perb65tuW8chPW4oul4ije2IKXlZZmv20jTev2N1+rtAmETexVn8EVdVLj90YBV1mjGTQl4tWRfxjQXFcwk9J4g4Nfce/x8DDNxygAB6KSNq1xaoZi+omQ3ELl7uN4et2ZqgJ7m+wapDt09B0An2JgrNKXGqzxZJaDX4gkPWPCtBoaycByrElQokA6abzI5PAFeTdxJ1mpeq8oZo+8sHwnYB0ml3D/P01mNOlU13sxi1nixLrO5RDdHM5tq3Cs/eZQjePu06taOEzCm6APX9FFbAq7AJbGnPjCk8g+7v8mBj/Bwo1qIyIN7LR7tRez1n+FqTPJPvmEI21YKhPOV3dNjDY+dLbhUbAaY="
40 | # Ex. travis encrypt GH_TOKEN=XXX-https://github.com/settings/tokens-XXX --add
41 | - secure: "mvvdjwFUe1D7aRPJCFb2oBiy+pTaYp5p/CXRLRJpq/Ap3aZ7N1GC4wjuWQKG0zR7cRnWX2OrtyQjR4q9iBT7nkrfSRZnNlu1zLQMrfpijIGCwC10wr/nuz/rtH0BjkozHHnDpedHDUp0P/WAWB99QSmxyKauvcShFQ2ceEAdZjuyVRKkWIcE9PgRjKIPc5TjVK9dZRHg/r65P5Mha2r3H5Rg7AfBLQebZqwMcR3BzilQAeUyUwuajNJMthzB76s3vYiAh4AbMJ9eM71VWc3Qtygl9U0xGKFSKuMkoPJIV7KYCoM9CKBmUz8uOGmBZyeYBy4FPXLvItAjJ5Oato9ujAr/sHk1044QT7rriRjSu+yNZeUwLP/uHLcWFHzYsSdIyY+S55BXPk5sg+ZFFZl/Lj+fJizAzQvZC+MgTVIhIIRE06fCA1qKwkMjPeRnGtUJVDw0NVJdTTs28J6l8EWbgOOuUJZaJO2pKcFR2QZfzh90ATVnBKH4UMhQMoLVklqUp2x3DNCamgrw/qa+vMk+PMnOQrPiOBKvu9qqwLVpiU0iNjvNUZrH1cF0WcGd4mqlqYbJ57shs1EVw/JfClrPaf6sYg26GJAfS+W2Nvr7FVT6OIeXAn2XKVrV18H43p+G3UZ3FyoXVnnWwkeXlpp2HtcFa5S53lrAvWdbUBmUsfQ="
42 | # Ex. travis encrypt SONATYPE_USER=your_sonatype_account
43 | - secure: "sdpWjltkPcEBsBHuuFgklG5+U2ZHZR0ea059jQwJtFHLBIBxN3hR0kWXki/VhZ3nT2j6C5gsYA6um6A8gRUIiYeHVWfEPQXDll677FIb3Og9pxblYSaZ4fxplQmqqr6bf52lojMFFG1VdTH7BXaVq0VIgphp4SKcmVZABuFPXFWfZ83UmdXE8zAkL9FJgAQkGi4z6qrEq4HGeUosbuSeH2tM3BYpYZRWwHgAVMTjAkL8NDcyawUJ4ZQWRwXUezmXTXsRjRA5u5TksKNlXPmOpffcYdTTpDH+FNbwjLTNJuy6C0/E2rVMCUgVYD3fQ/pcobp5csJl7VluLTSTIHfpGGCcxGJjTHZQcVlmuPulTNDcJtjEEnX1YczkVS+w1x3/j9Qlpj69YYN9KEee4mmSJlCDvZLSHhSoAuWMiry8RgHKiIlrXR2/75tgBQ/B23UBvC10fhXKdtKiVYjdCpBhHlMuLca7VAROtvzgneMf6c5kiVwspwz8TeOgC8mkL44zK4yBgT5fUExhYV4ModrcuiShgpWvjw/F5F8JaRvIDDaBE7L0NPO0w6lly+Ps6ELNXJzetWFOXlT8ti0YWnOcWfylE3SQfppySFBS6f3vv8aqEuu/RVWY7KI5NcH8iCKSkaS8YkNshv+of7qzoMMQx5mkAAQfT03Y3ozxY+r+9nE="
44 | # Ex. travis encrypt SONATYPE_PASSWORD=your_sonatype_password
45 | - secure: "GaDkVIdmFFJcV1qQF8KnUYritiIco1BFzYVRxxlA14qOJPgEA7XXSgbLWFsZR0tuL+z3ulfP5EvDYo8L+gP8YSrESVZiLCz3fDuqTbpWtFzZSvJuoyyffUHqpsDqT7SbyzzrFV5bEG1KI+jHlyiN6qc4iYPO/ce1ADzmz1sSKb9jpTlNht8ErWyScwScloPWgkG3s1oDVXKCHSRBUEa6FrtbNhg3jMp6dgB7L9FNXM91L7oF/ORyAsK3NgL2p3xOBfLNBbIOhpPD9GY0xC/6edzHUUirE/amSgT0w/mZws3RFRhExU+Q8sKC2PCpUvi2lYUpRSKc84Sq3Bail6EqQiaGnbQHlOKtlBMDosY3bQaqOZGKhWMoLDdPFwsKWtAmfLZD94q4ANwQJ+6QjJ5HV+0+O/bGNfu5CgAwGOeD5GyL1BG2el+3Y2WvLXz0Rhz6SSXRZr/x77hEu1dI7dRVGnb5w2DheSQDFrcCLxFmaZ9BBharfua2pGpipob9zpvzfIIc448j5UeOb+YIuQasbzPEwJfG/E2PTVe0mYhALbEPGYv/Ru09g2IKK1RLw0us7ivspMcob+O2Y8WWzVkHRGiZ++AQBJIIKJgtXsqeQU79PxFVRb23IucND01dMlZm+ZVjPhHhbQ666y2VPf2n79k/U5lMtMEZ/2YVZCs0lpc="
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Released Version][maven-img]][maven] [](https://opensource.org/licenses/Apache-2.0)
2 |
3 | # OpenTracing JDBC Instrumentation
4 |
5 | OpenTracing instrumentation for JDBC.
6 |
7 | ## Installation
8 |
9 | pom.xml
10 |
11 | ```xml
12 |
13 | io.opentracing.contrib
14 | opentracing-jdbc
15 | VERSION
16 |
17 | ```
18 |
19 | ## Usage
20 |
21 | ### Non-interceptor
22 |
23 | > Tracing for JDBC connections of URLs starting with `"jdbc:tracing:"`.
24 |
25 | 1. Activate tracing for JDBC connections by adding `tracing` to the JDBC url:
26 |
27 | _jdbc:**tracing**:h2:mem:test_
28 |
29 | To trace calls with active `Span`s only, set property `traceWithActiveSpanOnly=true`.
30 |
31 | _jdbc:**tracing**:h2:mem:test?**traceWithActiveSpanOnly=true**_
32 |
33 | To ignore specific queries (such as health checks), use the
34 | property `ignoreForTracing="SELECT 1"`. Double quotes can be escaped with `\`.
35 |
36 | `SELECT * FROM \"TEST\"`
The property can be repeated for multiple statements.
37 |
38 | 2. Set driver class to `io.opentracing.contrib.jdbc.TracingDriver`.
39 |
40 | ```java
41 | Class.forName("io.opentracing.contrib.jdbc.TracingDriver");
42 | ```
43 |
44 | or
45 |
46 | ```java
47 | io.opentracing.contrib.jdbc.TracingDriver.load();
48 | ```
49 |
50 | 3. Instantiate tracer and register it with GlobalTracer.
51 |
52 | ```java
53 | // Instantiate tracer
54 | Tracer tracer = ...
55 |
56 | // Register tracer with GlobalTracer
57 | GlobalTracer.register(tracer);
58 |
59 | ```
60 |
61 | ### Interceptor
62 |
63 | > Tracing for all JDBC connections without modifying the URL.
64 |
65 | In "interceptor mode", the `TracingDriver` will intercept calls
66 | to `DriverManager.getConnection(url,...)` for all URLs. The `TracingDriver` provides connections to
67 | the `DriverManager` that are instrumented. Please note that the `TracingDriver` must be registered
68 | before the underlying driver, It's recommended to turn on "interceptor mode" in the first place.
69 |
70 | For standalone applications:
71 |
72 | ```java
73 | public static void main(String[] args) {
74 | io.opentracing.contrib.jdbc.TracingDriver.setInterceptorMode(true);
75 | // some jdbc operation here
76 | }
77 |
78 | ```
79 |
80 | For web applications:
81 |
82 | ```java
83 | public void contextInitialized(ServletContextEvent event) {
84 | io.opentracing.contrib.jdbc.TracingDriver.setInterceptorMode(true);
85 | }
86 | ```
87 |
88 | Or call `TracingDriver.ensureRegisteredAsTheFirstDriver()` along
89 | with `TracingDriver.setInterceptorMode(true)` at any place, Please note driver like Oracle JDBC may
90 | fail since it's destroyed forever after deregistration.
91 |
92 | The `withActiveSpanOnly` and `ignoreStatements` properties for "interceptor mode" can be configured
93 | with the `TracingDriver` via:
94 |
95 | ```java
96 | // Set withActiveSpanOnly=true
97 | TracingDriver.setInterceptorProperty(true);
98 | ```
99 |
100 | and
101 |
102 | ```java
103 | // Set ignoreStatements={"CREATE TABLE ignored (id INTEGER, TEST VARCHAR)"}
104 | TracingDriver.setInterceptorProperty(Collections.singleton("CREATE TABLE ignored (id INTEGER, TEST VARCHAR)"));
105 | ```
106 |
107 | ### Hibernate
108 |
109 | ```xml
110 |
111 |
112 | io.opentracing.contrib.jdbc.TracingDriver
113 | jdbc:tracing:mysql://localhost:3306/test
114 | ...
115 |
116 | ...
117 |
118 | ```
119 |
120 | ### JPA
121 |
122 | ```xml
123 |
124 |
125 |
126 |
127 | ...
128 |
129 |
130 | ```
131 |
132 | ### Spring
133 |
134 | For dbcp2:
135 |
136 | ```xml
137 |
138 |
139 |
140 | ...
141 |
142 |
143 | ```
144 |
145 | ### Spring Boot 2
146 |
147 | For Hikari (Postgresl):
148 |
149 | ```properties
150 | ### Spring JPA Datasource Connection
151 | spring.datasource.username=postgres
152 | spring.datasource.password=XXXXX
153 | spring.datasource.hikari.driverClassName=io.opentracing.contrib.jdbc.TracingDriver
154 | spring.datasource.hikari.jdbcUrl=jdbc:tracing:postgresql://localhost:5432/my_app_db
155 |
156 | ```
157 |
158 | Configuration Bean:
159 |
160 | ```java
161 |
162 | @Component
163 | public class OpenTracingConfig {
164 |
165 | @Bean
166 | public io.opentracing.Tracer jaegerTracer() {
167 | io.opentracing.contrib.jdbc.TracingDriver.load();
168 | return new Configuration("my_app").getTracer();
169 | }
170 | }
171 |
172 | ```
173 |
174 | ## Slow Query
175 |
176 | Span is marked by tag `slow=true` if duration exceed `slowQueryThresholdMs`.
177 | `slowQueryThresholdMs` defaults to `0` which means disabled, can be enabled in two ways:
178 |
179 | 1. Passing system property, E.g. `-Dio.opentracing.contrib.jdbc.slowQueryThresholdMs=100`
180 | 2. Modify value by code, E.g. `io.opentracing.contrib.jdbc.JdbcTracing.setSlowQueryThresholdMs(100)`
181 |
182 | ## Fast Query
183 |
184 | Spans that complete faster than the optional `excludeFastQueryThresholdMs` flag will be not be
185 | reported.
186 | `excludeFastQueryThresholdMs` defaults to `0` which means disabled, can be enabled in two ways:
187 |
188 | 1. Passing system property, E.g. `-Dio.opentracing.contrib.jdbc.excludeFastQueryThresholdMs=100`
189 | 2. Modify value by code,
190 | E.g. `io.opentracing.contrib.jdbc.JdbcTracing.setExcludeFastQueryThresholdMs(100)`
191 |
192 | ## Troubleshooting
193 |
194 | In case of _Unable to find a driver_ error the database driver should be registered before
195 | configuring the datasource. E.g. `Class.forName("com.mysql.jdbc.Driver");`
196 |
197 | ## License
198 |
199 | [Apache 2.0 License](./LICENSE).
200 |
201 | [ci-img]: https://travis-ci.org/opentracing-contrib/java-jdbc.svg?branch=master
202 |
203 | [ci]: https://travis-ci.org/opentracing-contrib/java-jdbc
204 |
205 | [cov-img]: https://coveralls.io/repos/github/opentracing-contrib/java-jdbc/badge.svg?branch=master
206 |
207 | [cov]: https://coveralls.io/github/opentracing-contrib/java-jdbc?branch=master
208 |
209 | [maven-img]: https://img.shields.io/maven-central/v/io.opentracing.contrib/opentracing-jdbc.svg
210 |
211 | [maven]: http://search.maven.org/#search%7Cga%7C1%7Cio.opentracing.contrib%20opentracing-jdbc
212 |
--------------------------------------------------------------------------------
/RELEASE.md:
--------------------------------------------------------------------------------
1 | # OpenTracing Release Process
2 |
3 | This repo uses semantic versions. Please keep this in mind when choosing version numbers.
4 |
5 | For the up-to-date release process, please refer the
6 | [release process from the OpenTracing Java API](https://github.com/opentracing/opentracing-java/blob/master/RELEASE.md)
7 | .
--------------------------------------------------------------------------------
/header.txt:
--------------------------------------------------------------------------------
1 | Copyright ${project.inceptionYear} The OpenTracing Authors
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4 | in compliance with the License. You may obtain a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software distributed under the License
9 | is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10 | or implied. See the License for the specific language governing permissions and limitations under
11 | the License.
12 |
--------------------------------------------------------------------------------
/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ]; then
38 |
39 | if [ -f /etc/mavenrc ]; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ]; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false
51 | darwin=false
52 | mingw=false
53 | case "$(uname)" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true ;;
56 | Darwin*)
57 | darwin=true
58 | #
59 | # Look for the Apple JDKs first to preserve the existing behaviour, and then look
60 | # for the new JDKs provided by Oracle.
61 | #
62 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ]; then
63 | #
64 | # Apple JDKs
65 | #
66 | export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
67 | fi
68 |
69 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ]; then
70 | #
71 | # Apple JDKs
72 | #
73 | export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
74 | fi
75 |
76 | if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ]; then
77 | #
78 | # Oracle JDKs
79 | #
80 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
81 | fi
82 |
83 | if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
84 | #
85 | # Apple JDKs
86 | #
87 | export JAVA_HOME=$(/usr/libexec/java_home)
88 | fi
89 | ;;
90 | esac
91 |
92 | if [ -z "$JAVA_HOME" ]; then
93 | if [ -r /etc/gentoo-release ]; then
94 | JAVA_HOME=$(java-config --jre-home)
95 | fi
96 | fi
97 |
98 | if [ -z "$M2_HOME" ]; then
99 | ## resolve links - $0 may be a link to maven's home
100 | PRG="$0"
101 |
102 | # need this for relative symlinks
103 | while [ -h "$PRG" ]; do
104 | ls=$(ls -ld "$PRG")
105 | link=$(expr "$ls" : '.*-> \(.*\)$')
106 | if expr "$link" : '/.*' >/dev/null; then
107 | PRG="$link"
108 | else
109 | PRG="$(dirname "$PRG")/$link"
110 | fi
111 | done
112 |
113 | saveddir=$(pwd)
114 |
115 | M2_HOME=$(dirname "$PRG")/..
116 |
117 | # make it fully qualified
118 | M2_HOME=$(cd "$M2_HOME" && pwd)
119 |
120 | cd "$saveddir"
121 | # echo Using m2 at $M2_HOME
122 | fi
123 |
124 | # For Cygwin, ensure paths are in UNIX format before anything is touched
125 | if $cygwin; then
126 | [ -n "$M2_HOME" ] &&
127 | M2_HOME=$(cygpath --unix "$M2_HOME")
128 | [ -n "$JAVA_HOME" ] &&
129 | JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
130 | [ -n "$CLASSPATH" ] &&
131 | CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
132 | fi
133 |
134 | # For Migwn, ensure paths are in UNIX format before anything is touched
135 | if $mingw; then
136 | [ -n "$M2_HOME" ] &&
137 | M2_HOME="$( (
138 | cd "$M2_HOME"
139 | pwd
140 | ))"
141 | [ -n "$JAVA_HOME" ] &&
142 | JAVA_HOME="$( (
143 | cd "$JAVA_HOME"
144 | pwd
145 | ))"
146 | # TODO classpath?
147 | fi
148 |
149 | if [ -z "$JAVA_HOME" ]; then
150 | javaExecutable="$(which javac)"
151 | if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then
152 | # readlink(1) is not available as standard on Solaris 10.
153 | readLink=$(which readlink)
154 | if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then
155 | if $darwin; then
156 | javaHome="$(dirname \"$javaExecutable\")"
157 | javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac"
158 | else
159 | javaExecutable="$(readlink -f \"$javaExecutable\")"
160 | fi
161 | javaHome="$(dirname \"$javaExecutable\")"
162 | javaHome=$(expr "$javaHome" : '\(.*\)/bin')
163 | JAVA_HOME="$javaHome"
164 | export JAVA_HOME
165 | fi
166 | fi
167 | fi
168 |
169 | if [ -z "$JAVACMD" ]; then
170 | if [ -n "$JAVA_HOME" ]; then
171 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then
172 | # IBM's JDK on AIX uses strange locations for the executables
173 | JAVACMD="$JAVA_HOME/jre/sh/java"
174 | else
175 | JAVACMD="$JAVA_HOME/bin/java"
176 | fi
177 | else
178 | JAVACMD="$(which java)"
179 | fi
180 | fi
181 |
182 | if [ ! -x "$JAVACMD" ]; then
183 | echo "Error: JAVA_HOME is not defined correctly." >&2
184 | echo " We cannot execute $JAVACMD" >&2
185 | exit 1
186 | fi
187 |
188 | if [ -z "$JAVA_HOME" ]; then
189 | echo "Warning: JAVA_HOME environment variable is not set."
190 | fi
191 |
192 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
193 |
194 | # traverses directory structure from process work directory to filesystem root
195 | # first directory with .mvn subdirectory is considered project base directory
196 | find_maven_basedir() {
197 | local basedir=$(pwd)
198 | local wdir=$(pwd)
199 | while [ "$wdir" != '/' ]; do
200 | if [ -d "$wdir"/.mvn ]; then
201 | basedir=$wdir
202 | break
203 | fi
204 | wdir=$(
205 | cd "$wdir/.."
206 | pwd
207 | )
208 | done
209 | echo "${basedir}"
210 | }
211 |
212 | # concatenates all lines of a file
213 | concat_lines() {
214 | if [ -f "$1" ]; then
215 | echo "$(tr -s '\n' ' ' <"$1")"
216 | fi
217 | }
218 |
219 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
220 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
221 |
222 | # For Cygwin, switch paths to Windows format before running java
223 | if $cygwin; then
224 | [ -n "$M2_HOME" ] &&
225 | M2_HOME=$(cygpath --path --windows "$M2_HOME")
226 | [ -n "$JAVA_HOME" ] &&
227 | JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
228 | [ -n "$CLASSPATH" ] &&
229 | CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
230 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
231 | MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
232 | fi
233 |
234 | # Provide a "standardized" way to retrieve the CLI args that will
235 | # work with both Windows and non-Windows executions.
236 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
237 | export MAVEN_CMD_LINE_ARGS
238 |
239 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
240 |
241 | # avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in $@
242 | exec "$JAVACMD" \
243 | $MAVEN_OPTS \
244 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
245 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
246 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
247 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | # avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in %*
125 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
126 | if ERRORLEVEL 1 goto error
127 | goto end
128 |
129 | :error
130 | set ERROR_CODE=1
131 |
132 | :end
133 | @endlocal & set ERROR_CODE=%ERROR_CODE%
134 |
135 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
136 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
137 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
138 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
139 | :skipRcPost
140 |
141 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
142 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
143 |
144 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
145 |
146 | exit /B %ERROR_CODE%
147 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 | io.opentracing.contrib
20 | opentracing-jdbc
21 | 0.2.16-SNAPSHOT
22 |
23 | ${project.groupId}:${project.artifactId}
24 | OpenTracing Instrumentation for JDBC API
25 | https://github.com/opentracing-contrib/java-jdbc
26 | 2017-2021
27 |
28 |
29 | http://github.com/opentracing-contrib/java-jdbc
30 | scm:git:https://github.com/opentracing-contrib/java-jdbc.git
31 | scm:git:https://github.com/opentracing-contrib/java-jdbc.git
32 |
33 | HEAD
34 |
35 |
36 |
37 |
38 | The Apache Software License, Version 2.0
39 | http://www.apache.org/licenses/LICENSE-2.0.txt
40 | repo
41 |
42 |
43 |
44 |
45 |
46 | malafeev
47 | Sergei Malafeev
48 | sergeymalafeev@gmail.com
49 |
50 |
51 |
52 |
53 | GitHub
54 | https://github.com/opentracing-contrib/java-jdbc/issues
55 |
56 |
57 |
58 | 1.8
59 | 1.8
60 | UTF-8
61 | UTF-8
62 |
63 | 0.33.0
64 | 4.3.0
65 | 0.8.5
66 |
67 |
68 |
69 |
70 | io.opentracing
71 | opentracing-util
72 | ${opentracing.version}
73 |
74 |
75 |
76 | io.opentracing
77 | opentracing-util
78 | ${opentracing.version}
79 | test-jar
80 | test
81 |
82 |
83 |
84 | io.opentracing.contrib
85 | common
86 | 0.1.4
87 |
88 |
89 |
90 | io.opentracing
91 | opentracing-mock
92 | ${opentracing.version}
93 | test
94 |
95 |
96 |
97 | com.h2database
98 | h2
99 | 1.4.200
100 | test
101 |
102 |
103 |
104 | org.hibernate
105 | hibernate-core
106 | 5.4.10.Final
107 | test
108 |
109 |
110 |
111 | org.springframework
112 | spring-jdbc
113 | 5.2.2.RELEASE
114 | test
115 |
116 |
117 |
118 | org.apache.commons
119 | commons-dbcp2
120 | 2.7.0
121 | test
122 |
123 |
124 |
125 | junit
126 | junit
127 | 4.13.2
128 | test
129 |
130 |
131 |
132 | org.assertj
133 | assertj-core
134 | 3.14.0
135 | test
136 |
137 |
138 | org.junit.jupiter
139 | junit-jupiter
140 | 5.7.1
141 | test
142 |
143 |
144 | org.junit.platform
145 | junit-platform-launcher
146 | 1.7.1
147 | test
148 |
149 |
150 | org.junit.vintage
151 | junit-vintage-engine
152 | 5.7.1
153 | test
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 | org.apache.maven.plugins
162 | maven-release-plugin
163 | 2.5.3
164 |
165 | false
166 | release
167 | true
168 | @{project.version}
169 |
170 |
171 |
172 | io.zipkin.centralsync-maven-plugin
173 | centralsync-maven-plugin
174 | 0.1.1
175 |
176 | opentracing
177 | maven
178 | opentracing-jdbc
179 |
180 |
181 |
182 | org.apache.maven.plugins
183 | maven-surefire-plugin
184 | 2.22.2
185 |
186 |
187 | com.mycila
188 | license-maven-plugin
189 | 3.0
190 |
191 |
192 | SLASHSTAR_STYLE
193 |
194 |
195 | true
196 |
197 | LICENSE
198 | mvnw
199 | mvnw.cmd
200 | .mvn/wrapper/maven-wrapper.properties
201 | .coveralls.yml
202 |
203 |
204 |
205 |
206 |
207 | check
208 |
209 | compile
210 |
211 |
212 |
213 |
214 | org.eluder.coveralls
215 | coveralls-maven-plugin
216 | ${coveralls-maven-plugin.version}
217 |
218 |
219 | org.jacoco
220 | jacoco-maven-plugin
221 | ${jacoco-maven-plugin.version}
222 |
223 |
224 | prepare-agent
225 |
226 | prepare-agent
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 | bintray
237 | https://api.bintray.com/maven/opentracing/maven/opentracing-jdbc/;publish=1
238 |
239 |
240 | jfrog-snapshots
241 | http://oss.jfrog.org/artifactory/oss-snapshot-local
242 |
243 |
244 |
245 |
246 |
247 | release
248 |
249 |
250 |
251 |
252 | org.apache.maven.plugins
253 | maven-source-plugin
254 | 3.2.0
255 |
256 |
257 | attach-sources
258 |
259 | jar
260 |
261 |
262 |
263 |
264 |
265 |
266 | org.apache.maven.plugins
267 | maven-javadoc-plugin
268 | 3.1.1
269 |
270 | false
271 |
272 |
273 |
274 | attach-javadocs
275 |
276 | jar
277 |
278 | package
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/ConnectionInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | public class ConnectionInfo {
17 |
18 | public static ConnectionInfo UNKNOWN_CONNECTION_INFO = new Builder("unknown_peer")
19 | .dbType("unknown_type").dbInstance("unknown_instance").build();
20 |
21 | private final String dbType;
22 | private final String dbUser;
23 | private final String dbInstance;
24 | private final String dbPeer;
25 | private final String dbPeerService;
26 |
27 | private ConnectionInfo(String dbType, String dbUser, String dbInstance, String dbHost,
28 | Integer dbPort) {
29 | this.dbType = dbType;
30 | this.dbUser = dbUser;
31 | this.dbInstance = dbInstance;
32 | if (dbHost != null && dbPort != null) {
33 | this.dbPeer = dbHost + ":" + dbPort;
34 | } else {
35 | this.dbPeer = "";
36 | }
37 |
38 | this.dbPeerService = makePeerService();
39 | }
40 |
41 | private ConnectionInfo(String dbType, String dbUser, String dbInstance, String dbPeer) {
42 | this.dbType = dbType;
43 | this.dbUser = dbUser;
44 | this.dbInstance = dbInstance;
45 | this.dbPeer = dbPeer;
46 |
47 | this.dbPeerService = makePeerService();
48 | }
49 |
50 | /**
51 | * Make a unique serviceName that could be used in dependency diagram.
52 | */
53 | private String makePeerService() {
54 | if (null != dbInstance && !dbInstance.isEmpty()) {
55 | return dbInstance + "[" + dbType + "(" + dbPeer + ")]";
56 | } else {
57 | return dbType + "(" + dbPeer + ")";
58 | }
59 | }
60 |
61 | public String getDbType() {
62 | return dbType;
63 | }
64 |
65 | public String getDbUser() {
66 | return dbUser;
67 | }
68 |
69 | public String getDbInstance() {
70 | return dbInstance;
71 | }
72 |
73 | public String getDbPeer() {
74 | return dbPeer;
75 | }
76 |
77 | public String getPeerService() {
78 | return dbPeerService;
79 | }
80 |
81 | public static class Builder {
82 | private String dbType;
83 | private String dbUser;
84 | private String dbInstance;
85 | private String dbHost;
86 | private Integer dbPort;
87 | private String dbPeer;
88 |
89 | public Builder(String dbPeer) {
90 | this.dbPeer = dbPeer;
91 | }
92 |
93 | public Builder(String dbHost, Integer dbPort) {
94 | this.dbHost = dbHost;
95 | this.dbPort = dbPort;
96 | }
97 |
98 | public Builder dbType(String dbType) {
99 | this.dbType = dbType;
100 | return this;
101 | }
102 |
103 | public Builder dbUser(String dbUser) {
104 | this.dbUser = dbUser;
105 | return this;
106 | }
107 |
108 | public Builder dbInstance(String dbInstance) {
109 | this.dbInstance = dbInstance;
110 | return this;
111 | }
112 |
113 | public ConnectionInfo build() {
114 | if (this.dbPeer != null && !dbPeer.isEmpty()) {
115 | return new ConnectionInfo(this.dbType, this.dbUser, this.dbInstance, this.dbPeer);
116 | }
117 | return new ConnectionInfo(this.dbType, this.dbUser, this.dbInstance, this.dbHost,
118 | this.dbPort);
119 | }
120 |
121 | }
122 |
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/JdbcTracing.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | public class JdbcTracing {
17 | private static boolean traceEnabled = true;
18 |
19 | /**
20 | * Sets the {@code traceEnabled} property to enable or disable traces.
21 | *
22 | * @param traceEnabled The {@code traceEnabled} value.
23 | */
24 | public static void setTraceEnabled(boolean traceEnabled) {
25 | JdbcTracing.traceEnabled = traceEnabled;
26 | }
27 |
28 | public static boolean isTraceEnabled() {
29 | return JdbcTracing.traceEnabled;
30 | }
31 |
32 | /**
33 | * can be modified by application code
34 | */
35 | private static int slowQueryThresholdMs = Integer
36 | .getInteger("io.opentracing.contrib.jdbc.slowQueryThresholdMs", 0);
37 |
38 | public static int getSlowQueryThresholdMs() {
39 | return slowQueryThresholdMs;
40 | }
41 |
42 | public static void setSlowQueryThresholdMs(final int slowQueryThresholdMs) {
43 | JdbcTracing.slowQueryThresholdMs = slowQueryThresholdMs;
44 | }
45 |
46 | private static int excludeFastQueryThresholdMs = Integer
47 | .getInteger("io.opentracing.contrib.jdbc.excludeFastQueryThresholdMs", 0);
48 |
49 | public static int getExcludeFastQueryThresholdMs() {
50 | return excludeFastQueryThresholdMs;
51 | }
52 |
53 | public static void setExcludeFastQueryThresholdMs(final int excludeFastQueryThresholdMs) {
54 | JdbcTracing.excludeFastQueryThresholdMs = excludeFastQueryThresholdMs;
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/JdbcTracingUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 | import io.opentracing.Tracer;
19 | import io.opentracing.noop.NoopSpan;
20 | import io.opentracing.tag.BooleanTag;
21 | import io.opentracing.tag.IntTag;
22 | import io.opentracing.tag.StringTag;
23 | import io.opentracing.tag.Tags;
24 | import java.util.HashMap;
25 | import java.util.Map;
26 | import java.util.Set;
27 | import java.util.concurrent.TimeUnit;
28 |
29 | class JdbcTracingUtils {
30 |
31 | static final String COMPONENT_NAME = "java-jdbc";
32 |
33 | /**
34 | * Opentracing standard tag https://github.com/opentracing/specification/blob/master/semantic_conventions.md
35 | */
36 | static final StringTag PEER_ADDRESS = new StringTag("peer.address");
37 |
38 | static final BooleanTag SLOW = new BooleanTag("slow");
39 | static final IntTag SAMPLING_PRIORITY = new IntTag("sampling.priority");
40 |
41 | static Span buildSpan(String operationName,
42 | String sql,
43 | ConnectionInfo connectionInfo,
44 | boolean withActiveSpanOnly,
45 | Set ignoreStatements,
46 | Tracer tracer) {
47 | if (!JdbcTracing.isTraceEnabled() || (withActiveSpanOnly && tracer.activeSpan() == null)) {
48 | return NoopSpan.INSTANCE;
49 | } else if (ignoreStatements != null && ignoreStatements.contains(sql)) {
50 | return NoopSpan.INSTANCE;
51 | }
52 |
53 | Tracer.SpanBuilder spanBuilder = tracer.buildSpan(operationName)
54 | .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT);
55 |
56 | Span span = spanBuilder.start();
57 | decorate(span, sql, connectionInfo);
58 |
59 | return span;
60 | }
61 |
62 | static void execute(String operationName,
63 | CheckedRunnable runnable,
64 | String sql,
65 | ConnectionInfo connectionInfo,
66 | boolean withActiveSpanOnly,
67 | Set ignoreStatements,
68 | Tracer tracer) throws E {
69 | if (!JdbcTracing.isTraceEnabled() || (withActiveSpanOnly && tracer.activeSpan() == null)) {
70 | runnable.run();
71 | return;
72 | }
73 |
74 | final Span span = buildSpan(operationName, sql, connectionInfo, withActiveSpanOnly,
75 | ignoreStatements, tracer);
76 | long startTime = (JdbcTracing.getSlowQueryThresholdMs() > 0
77 | || JdbcTracing.getExcludeFastQueryThresholdMs() > 0) ? System.nanoTime() : 0;
78 | try (Scope ignored = tracer.activateSpan(span)) {
79 | runnable.run();
80 | } catch (Exception e) {
81 | JdbcTracingUtils.onError(e, span);
82 | throw e;
83 | } finally {
84 | JdbcTracingUtils.queryThresholdChecks(span, startTime);
85 | span.finish();
86 | }
87 | }
88 |
89 | static T call(String operationName,
90 | CheckedCallable callable,
91 | String sql,
92 | ConnectionInfo connectionInfo,
93 | boolean withActiveSpanOnly,
94 | Set ignoreStatements,
95 | Tracer tracer) throws E {
96 | if (!JdbcTracing.isTraceEnabled() || (withActiveSpanOnly && tracer.activeSpan() == null)) {
97 | return callable.call();
98 | }
99 |
100 | final Span span = buildSpan(operationName, sql, connectionInfo, withActiveSpanOnly,
101 | ignoreStatements, tracer);
102 | long startTime = JdbcTracing.getSlowQueryThresholdMs() > 0 ? System.nanoTime() : 0;
103 | try (Scope ignored = tracer.activateSpan(span)) {
104 | return callable.call();
105 | } catch (Exception e) {
106 | JdbcTracingUtils.onError(e, span);
107 | throw e;
108 | } finally {
109 | JdbcTracingUtils.queryThresholdChecks(span, startTime);
110 | span.finish();
111 | }
112 | }
113 |
114 | private static boolean isNotEmpty(CharSequence s) {
115 | return s != null && !"".contentEquals(s);
116 | }
117 |
118 | /**
119 | * Add tags to span. Skip empty tags to avoid reported NPE in tracers.
120 | */
121 | private static void decorate(Span span, String sql, ConnectionInfo connectionInfo) {
122 | Tags.COMPONENT.set(span, COMPONENT_NAME);
123 |
124 | if (isNotEmpty(sql)) {
125 | Tags.DB_STATEMENT.set(span, sql);
126 | }
127 | if (isNotEmpty(connectionInfo.getDbType())) {
128 | Tags.DB_TYPE.set(span, connectionInfo.getDbType());
129 | }
130 | if (isNotEmpty(connectionInfo.getDbPeer())) {
131 | PEER_ADDRESS.set(span, connectionInfo.getDbPeer());
132 | }
133 | if (isNotEmpty(connectionInfo.getDbInstance())) {
134 | Tags.DB_INSTANCE.set(span, connectionInfo.getDbInstance());
135 | }
136 | if (isNotEmpty(connectionInfo.getDbUser())) {
137 | Tags.DB_USER.set(span, connectionInfo.getDbUser());
138 | }
139 | if (isNotEmpty(connectionInfo.getPeerService())) {
140 | Tags.PEER_SERVICE.set(span, connectionInfo.getPeerService());
141 | }
142 | }
143 |
144 | static void onError(Throwable throwable, Span span) {
145 | Tags.ERROR.set(span, Boolean.TRUE);
146 |
147 | if (throwable != null) {
148 | span.log(errorLogs(throwable));
149 | }
150 | }
151 |
152 | private static Map errorLogs(Throwable throwable) {
153 | Map errorLogs = new HashMap<>(3);
154 | errorLogs.put("event", Tags.ERROR.getKey());
155 | errorLogs.put("error.object", throwable);
156 | return errorLogs;
157 | }
158 |
159 | private static void queryThresholdChecks(Span span, long startTime) {
160 | long completionTime = System.nanoTime() - startTime;
161 | if (JdbcTracing.getExcludeFastQueryThresholdMs() > 0 && completionTime < TimeUnit.MILLISECONDS
162 | .toNanos(JdbcTracing.getExcludeFastQueryThresholdMs())) {
163 | SAMPLING_PRIORITY.set(span, 0);
164 | }
165 | if (JdbcTracing.getSlowQueryThresholdMs() > 0 && completionTime > TimeUnit.MILLISECONDS
166 | .toNanos(JdbcTracing.getSlowQueryThresholdMs())) {
167 | SLOW.set(span, true);
168 | }
169 | }
170 |
171 | @FunctionalInterface
172 | interface CheckedRunnable {
173 |
174 | void run() throws E;
175 |
176 | }
177 |
178 | @FunctionalInterface
179 | interface CheckedCallable {
180 |
181 | T call() throws E;
182 |
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/TracingConnection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | import io.opentracing.Tracer;
17 | import io.opentracing.contrib.common.WrapperProxy;
18 | import java.sql.Array;
19 | import java.sql.Blob;
20 | import java.sql.CallableStatement;
21 | import java.sql.Clob;
22 | import java.sql.Connection;
23 | import java.sql.DatabaseMetaData;
24 | import java.sql.NClob;
25 | import java.sql.PreparedStatement;
26 | import java.sql.SQLClientInfoException;
27 | import java.sql.SQLException;
28 | import java.sql.SQLWarning;
29 | import java.sql.SQLXML;
30 | import java.sql.Savepoint;
31 | import java.sql.Statement;
32 | import java.sql.Struct;
33 | import java.util.Map;
34 | import java.util.Properties;
35 | import java.util.Set;
36 | import java.util.concurrent.Executor;
37 |
38 | public class TracingConnection implements Connection {
39 | private final Connection connection;
40 | private final ConnectionInfo connectionInfo;
41 | private final boolean withActiveSpanOnly;
42 | private final Set ignoreStatements;
43 | private final Tracer tracer;
44 |
45 | public TracingConnection(Connection connection, ConnectionInfo connectionInfo,
46 | boolean withActiveSpanOnly, Set ignoreStatements, Tracer tracer) {
47 | this.connection = connection;
48 | this.connectionInfo = connectionInfo;
49 | this.withActiveSpanOnly = withActiveSpanOnly;
50 | this.ignoreStatements = ignoreStatements;
51 | this.tracer = tracer;
52 | }
53 |
54 | @Override
55 | public Statement createStatement() throws SQLException {
56 | final Statement statement = connection.createStatement();
57 | return WrapperProxy
58 | .wrap(statement, new TracingStatement(statement, connectionInfo, withActiveSpanOnly,
59 | ignoreStatements, tracer));
60 | }
61 |
62 | @Override
63 | public Statement createStatement(int resultSetType, int resultSetConcurrency)
64 | throws SQLException {
65 | final Statement statement = connection.createStatement(resultSetType, resultSetConcurrency);
66 | return WrapperProxy.wrap(statement, new TracingStatement(statement,
67 | connectionInfo, withActiveSpanOnly, ignoreStatements, tracer));
68 | }
69 |
70 | @Override
71 | public Statement createStatement(int resultSetType, int resultSetConcurrency,
72 | int resultSetHoldability) throws SQLException {
73 | final Statement statement = connection
74 | .createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
75 | return WrapperProxy.wrap(statement, new TracingStatement(statement,
76 | connectionInfo, withActiveSpanOnly, ignoreStatements, tracer));
77 | }
78 |
79 | @Override
80 | public PreparedStatement prepareStatement(String sql) throws SQLException {
81 | final PreparedStatement statement = connection.prepareStatement(sql);
82 | return WrapperProxy.wrap(statement, new TracingPreparedStatement(statement, sql, connectionInfo,
83 | withActiveSpanOnly, ignoreStatements, tracer));
84 | }
85 |
86 | @Override
87 | public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
88 | throws SQLException {
89 | final PreparedStatement statement = connection
90 | .prepareStatement(sql, resultSetType, resultSetConcurrency);
91 | return WrapperProxy.wrap(statement, new TracingPreparedStatement(statement, sql, connectionInfo,
92 | withActiveSpanOnly, ignoreStatements, tracer));
93 | }
94 |
95 | @Override
96 | public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
97 | int resultSetHoldability) throws SQLException {
98 | final PreparedStatement statement = connection
99 | .prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
100 | return WrapperProxy.wrap(statement, new TracingPreparedStatement(statement,
101 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer));
102 | }
103 |
104 | @Override
105 | public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
106 | final PreparedStatement statement = connection.prepareStatement(sql, autoGeneratedKeys);
107 | return WrapperProxy.wrap(statement, new TracingPreparedStatement(statement, sql,
108 | connectionInfo, withActiveSpanOnly, ignoreStatements, tracer));
109 | }
110 |
111 | @Override
112 | public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
113 | final PreparedStatement statement = connection.prepareStatement(sql, columnIndexes);
114 | return WrapperProxy.wrap(statement, new TracingPreparedStatement(statement, sql,
115 | connectionInfo, withActiveSpanOnly, ignoreStatements, tracer));
116 | }
117 |
118 | @Override
119 | public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
120 | final PreparedStatement statement = connection.prepareStatement(sql, columnNames);
121 | return WrapperProxy.wrap(statement, new TracingPreparedStatement(statement, sql, connectionInfo,
122 | withActiveSpanOnly, ignoreStatements, tracer));
123 | }
124 |
125 | @Override
126 | public CallableStatement prepareCall(String sql) throws SQLException {
127 | final CallableStatement statement = connection.prepareCall(sql);
128 | return WrapperProxy.wrap(statement,
129 | new TracingCallableStatement(statement, sql, connectionInfo,
130 | withActiveSpanOnly, ignoreStatements, tracer));
131 | }
132 |
133 | @Override
134 | public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
135 | throws SQLException {
136 | final CallableStatement statement = connection
137 | .prepareCall(sql, resultSetType, resultSetConcurrency);
138 | return WrapperProxy.wrap(statement, new TracingCallableStatement(statement, sql, connectionInfo,
139 | withActiveSpanOnly, ignoreStatements, tracer));
140 | }
141 |
142 | @Override
143 | public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
144 | int resultSetHoldability) throws SQLException {
145 | final CallableStatement statement = connection
146 | .prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
147 | return WrapperProxy.wrap(statement, new TracingCallableStatement(statement, sql,
148 | connectionInfo, withActiveSpanOnly, ignoreStatements, tracer));
149 | }
150 |
151 | @Override
152 | public void commit() throws SQLException {
153 | JdbcTracingUtils.execute("Commit", connection::commit, null,
154 | connectionInfo, withActiveSpanOnly, null, tracer);
155 | }
156 |
157 | @Override
158 | public void rollback() throws SQLException {
159 | JdbcTracingUtils.execute("Rollback", connection::rollback, null,
160 | connectionInfo, withActiveSpanOnly, null, tracer);
161 | }
162 |
163 | @Override
164 | public void close() throws SQLException {
165 | JdbcTracingUtils.execute("Close", connection::close, null,
166 | connectionInfo, withActiveSpanOnly, null, tracer);
167 | }
168 |
169 | @Override
170 | public String nativeSQL(String sql) throws SQLException {
171 | return connection.nativeSQL(sql);
172 | }
173 |
174 | @Override
175 | public void setAutoCommit(boolean autoCommit) throws SQLException {
176 | connection.setAutoCommit(autoCommit);
177 | }
178 |
179 | @Override
180 | public boolean getAutoCommit() throws SQLException {
181 | return connection.getAutoCommit();
182 | }
183 |
184 | @Override
185 | public boolean isClosed() throws SQLException {
186 | return connection.isClosed();
187 | }
188 |
189 | @Override
190 | public DatabaseMetaData getMetaData() throws SQLException {
191 | return connection.getMetaData();
192 | }
193 |
194 | @Override
195 | public void setReadOnly(boolean readOnly) throws SQLException {
196 | connection.setReadOnly(readOnly);
197 | }
198 |
199 | @Override
200 | public boolean isReadOnly() throws SQLException {
201 | return connection.isReadOnly();
202 | }
203 |
204 | @Override
205 | public void setCatalog(String catalog) throws SQLException {
206 | connection.setCatalog(catalog);
207 | }
208 |
209 | @Override
210 | public String getCatalog() throws SQLException {
211 | return connection.getCatalog();
212 | }
213 |
214 | @Override
215 | public void setTransactionIsolation(int level) throws SQLException {
216 | connection.setTransactionIsolation(level);
217 | }
218 |
219 | @Override
220 | public int getTransactionIsolation() throws SQLException {
221 | return connection.getTransactionIsolation();
222 | }
223 |
224 | @Override
225 | public SQLWarning getWarnings() throws SQLException {
226 | return connection.getWarnings();
227 | }
228 |
229 | @Override
230 | public void clearWarnings() throws SQLException {
231 | connection.clearWarnings();
232 | }
233 |
234 | @Override
235 | public Map> getTypeMap() throws SQLException {
236 | return connection.getTypeMap();
237 | }
238 |
239 | @Override
240 | public void setTypeMap(Map> map) throws SQLException {
241 | connection.setTypeMap(map);
242 | }
243 |
244 | @Override
245 | public void setHoldability(int holdability) throws SQLException {
246 | connection.setHoldability(holdability);
247 | }
248 |
249 | @Override
250 | public int getHoldability() throws SQLException {
251 | return connection.getHoldability();
252 | }
253 |
254 | @Override
255 | public Savepoint setSavepoint() throws SQLException {
256 | return connection.setSavepoint();
257 | }
258 |
259 | @Override
260 | public Savepoint setSavepoint(String name) throws SQLException {
261 | return connection.setSavepoint(name);
262 | }
263 |
264 | @Override
265 | public void rollback(Savepoint savepoint) throws SQLException {
266 | connection.rollback(savepoint);
267 | }
268 |
269 | @Override
270 | public void releaseSavepoint(Savepoint savepoint) throws SQLException {
271 | connection.releaseSavepoint(savepoint);
272 | }
273 |
274 | @Override
275 | public Clob createClob() throws SQLException {
276 | return connection.createClob();
277 | }
278 |
279 | @Override
280 | public Blob createBlob() throws SQLException {
281 | return connection.createBlob();
282 | }
283 |
284 | @Override
285 | public NClob createNClob() throws SQLException {
286 | return connection.createNClob();
287 | }
288 |
289 | @Override
290 | public SQLXML createSQLXML() throws SQLException {
291 | return connection.createSQLXML();
292 | }
293 |
294 | @Override
295 | public boolean isValid(int timeout) throws SQLException {
296 | return connection.isValid(timeout);
297 | }
298 |
299 | @Override
300 | public void setClientInfo(String name, String value) throws SQLClientInfoException {
301 | connection.setClientInfo(name, value);
302 | }
303 |
304 | @Override
305 | public void setClientInfo(Properties properties) throws SQLClientInfoException {
306 | connection.setClientInfo(properties);
307 | }
308 |
309 | @Override
310 | public String getClientInfo(String name) throws SQLException {
311 | return connection.getClientInfo(name);
312 | }
313 |
314 | @Override
315 | public Properties getClientInfo() throws SQLException {
316 | return connection.getClientInfo();
317 | }
318 |
319 | @Override
320 | public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
321 | return connection.createArrayOf(typeName, elements);
322 | }
323 |
324 | @Override
325 | public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
326 | return connection.createStruct(typeName, attributes);
327 | }
328 |
329 | @Override
330 | public void setSchema(String schema) throws SQLException {
331 | connection.setSchema(schema);
332 | }
333 |
334 | @Override
335 | public String getSchema() throws SQLException {
336 | return connection.getSchema();
337 | }
338 |
339 | @Override
340 | public void abort(Executor executor) throws SQLException {
341 | connection.abort(executor);
342 | }
343 |
344 | @Override
345 | public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
346 | connection.setNetworkTimeout(executor, milliseconds);
347 | }
348 |
349 | @Override
350 | public int getNetworkTimeout() throws SQLException {
351 | return connection.getNetworkTimeout();
352 | }
353 |
354 | @Override
355 | public T unwrap(Class iface) throws SQLException {
356 | return connection.unwrap(iface);
357 | }
358 |
359 | @Override
360 | public boolean isWrapperFor(Class> iface) throws SQLException {
361 | return connection.isWrapperFor(iface);
362 | }
363 | }
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/TracingDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 |
17 | import io.opentracing.Tracer;
18 | import io.opentracing.contrib.common.WrapperProxy;
19 | import io.opentracing.contrib.jdbc.parser.URLParser;
20 | import java.io.PrintWriter;
21 | import java.lang.reflect.Method;
22 | import java.sql.Connection;
23 | import java.sql.SQLException;
24 | import java.sql.SQLFeatureNotSupportedException;
25 | import java.util.Collections;
26 | import java.util.Set;
27 | import java.util.logging.Logger;
28 | import javax.sql.DataSource;
29 |
30 | public class TracingDataSource implements DataSource, AutoCloseable {
31 | private static final boolean DEFAULT_WITH_ACTIVE_SPAN_ONLY = false;
32 | private static final Set DEFAULT_IGNORED_STATEMENTS = Collections.emptySet();
33 |
34 | private final Tracer tracer;
35 | private final DataSource underlying;
36 | private final ConnectionInfo connectionInfo;
37 | private final boolean withActiveSpanOnly;
38 | private final Set ignoreStatements;
39 |
40 | public TracingDataSource(final Tracer tracer,
41 | final DataSource underlying) {
42 | this(tracer, underlying, null, DEFAULT_WITH_ACTIVE_SPAN_ONLY,
43 | DEFAULT_IGNORED_STATEMENTS);
44 | }
45 |
46 | public TracingDataSource(final Tracer tracer,
47 | final DataSource underlying,
48 | final ConnectionInfo connectionInfo,
49 | final boolean withActiveSpanOnly,
50 | final Set ignoreStatements) {
51 | this.tracer = tracer;
52 | this.underlying = underlying;
53 | ConnectionInfo info = connectionInfo;
54 | if (info == null) {
55 | try {
56 | Method method;
57 | try {
58 | method = underlying.getClass().getMethod("getJdbcUrl");
59 | } catch (NoSuchMethodException e) {
60 | method = underlying.getClass().getMethod("getUrl");
61 | }
62 | info = URLParser.parse((String) method.invoke(underlying));
63 | } catch (Exception ignored) {
64 | info = ConnectionInfo.UNKNOWN_CONNECTION_INFO;
65 | }
66 | }
67 | this.connectionInfo = info;
68 | this.withActiveSpanOnly = withActiveSpanOnly;
69 | this.ignoreStatements = ignoreStatements;
70 | }
71 |
72 | public DataSource getUnderlying() {
73 | return underlying;
74 | }
75 |
76 | @Override
77 | public Connection getConnection() throws SQLException {
78 | final Connection connection = JdbcTracingUtils
79 | .call("AcquireConnection", underlying::getConnection,
80 | null, connectionInfo, withActiveSpanOnly, null, tracer);
81 |
82 | return WrapperProxy
83 | .wrap(connection, new TracingConnection(connection, connectionInfo, withActiveSpanOnly,
84 | ignoreStatements, tracer));
85 | }
86 |
87 | @Override
88 | public Connection getConnection(final String username, final String password)
89 | throws SQLException {
90 | final Connection connection = JdbcTracingUtils.call("AcquireConnection", () ->
91 | underlying.getConnection(username, password), null, connectionInfo,
92 | withActiveSpanOnly, null, tracer);
93 |
94 | return WrapperProxy
95 | .wrap(connection, new TracingConnection(connection, connectionInfo, withActiveSpanOnly,
96 | ignoreStatements, tracer));
97 | }
98 |
99 | @Override
100 | public PrintWriter getLogWriter() throws SQLException {
101 | return underlying.getLogWriter();
102 | }
103 |
104 | @Override
105 | public void setLogWriter(final PrintWriter out) throws SQLException {
106 | underlying.setLogWriter(out);
107 | }
108 |
109 | @Override
110 | public void setLoginTimeout(final int seconds) throws SQLException {
111 | underlying.setLoginTimeout(seconds);
112 | }
113 |
114 | @Override
115 | public int getLoginTimeout() throws SQLException {
116 | return underlying.getLoginTimeout();
117 | }
118 |
119 | @Override
120 | public Logger getParentLogger() throws SQLFeatureNotSupportedException {
121 | return underlying.getParentLogger();
122 | }
123 |
124 | @Override
125 | public T unwrap(final Class iface) throws SQLException {
126 | return underlying.unwrap(iface);
127 | }
128 |
129 | @Override
130 | public boolean isWrapperFor(final Class> iface) throws SQLException {
131 | return underlying.isWrapperFor(iface);
132 | }
133 |
134 | @Override
135 | public void close() throws Exception {
136 | if (underlying instanceof AutoCloseable) {
137 | ((AutoCloseable) underlying).close();
138 | }
139 | }
140 | }
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/TracingDriver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | import io.opentracing.Tracer;
17 | import io.opentracing.contrib.common.WrapperProxy;
18 | import io.opentracing.contrib.jdbc.parser.URLParser;
19 | import io.opentracing.util.GlobalTracer;
20 | import java.sql.Connection;
21 | import java.sql.Driver;
22 | import java.sql.DriverManager;
23 | import java.sql.DriverPropertyInfo;
24 | import java.sql.SQLException;
25 | import java.sql.SQLFeatureNotSupportedException;
26 | import java.util.ArrayList;
27 | import java.util.Collections;
28 | import java.util.Enumeration;
29 | import java.util.HashSet;
30 | import java.util.List;
31 | import java.util.Properties;
32 | import java.util.Set;
33 | import java.util.logging.Logger;
34 | import java.util.regex.Matcher;
35 | import java.util.regex.Pattern;
36 |
37 | public class TracingDriver implements Driver {
38 |
39 | private static final Driver INSTANCE = new TracingDriver();
40 |
41 | protected static final String TRACE_WITH_ACTIVE_SPAN_ONLY = "traceWithActiveSpanOnly";
42 |
43 | protected static final String WITH_ACTIVE_SPAN_ONLY = TRACE_WITH_ACTIVE_SPAN_ONLY + "=true";
44 |
45 | public static final String IGNORE_FOR_TRACING_REGEX = "ignoreForTracing=\"((?:\\\\\"|[^\"])*)\"[;]*";
46 |
47 | protected static final Pattern PATTERN_FOR_IGNORING = Pattern.compile(IGNORE_FOR_TRACING_REGEX);
48 |
49 | static {
50 | try {
51 | DriverManager.registerDriver(INSTANCE);
52 | } catch (SQLException e) {
53 | throw new IllegalStateException("Could not register TracingDriver with DriverManager", e);
54 | }
55 | }
56 |
57 | /**
58 | * @return The singleton instance of the {@code TracingDriver}.
59 | */
60 | public static Driver load() {
61 | return INSTANCE;
62 | }
63 |
64 | /**
65 | * Ensure {@code TracingDriver} be the first driver of {@link DriverManager} to make sure
66 | * "interceptor mode" works. WARNING: Driver like Oracle JDBC may fail since it's destroyed
67 | * forever after deregistration.
68 | */
69 | public synchronized static void ensureRegisteredAsTheFirstDriver() {
70 | try {
71 | Enumeration enumeration = DriverManager.getDrivers();
72 | List drivers = null;
73 | for (int i = 0; enumeration.hasMoreElements(); ++i) {
74 | Driver driver = enumeration.nextElement();
75 | if (i == 0) {
76 | if (driver == INSTANCE) {
77 | return;
78 | }
79 | drivers = new ArrayList<>();
80 | }
81 | if (driver != INSTANCE) {
82 | drivers.add(driver);
83 | DriverManager.deregisterDriver(driver);
84 | }
85 | }
86 | for (Driver driver : drivers) {
87 | DriverManager.registerDriver(driver);
88 | }
89 | } catch (SQLException e) {
90 | throw new IllegalStateException("Could not register TracingDriver with DriverManager", e);
91 | }
92 | }
93 |
94 | /**
95 | * Sets the {@code traceEnabled} property to enable or disable traces.
96 | *
97 | * @param traceEnabled The {@code traceEnabled} value.
98 | */
99 | public static void setTraceEnabled(boolean traceEnabled) {
100 | JdbcTracing.setTraceEnabled(traceEnabled);
101 | }
102 |
103 | public static boolean isTraceEnabled() {
104 | return JdbcTracing.isTraceEnabled();
105 | }
106 |
107 | private static boolean interceptorMode = false;
108 |
109 | /**
110 | * Turns "interceptor mode" on or off.
111 | *
112 | * @param interceptorMode The {@code interceptorMode} value.
113 | */
114 | public static void setInterceptorMode(final boolean interceptorMode) {
115 | TracingDriver.interceptorMode = interceptorMode;
116 | }
117 |
118 | private static boolean withActiveSpanOnly;
119 |
120 | /**
121 | * Sets the {@code withActiveSpanOnly} property for "interceptor mode".
122 | *
123 | * @param withActiveSpanOnly The {@code withActiveSpanOnly} value.
124 | */
125 | public static void setInterceptorProperty(final boolean withActiveSpanOnly) {
126 | TracingDriver.withActiveSpanOnly = withActiveSpanOnly;
127 | }
128 |
129 | private static Set ignoreStatements;
130 |
131 | /**
132 | * Sets the {@code ignoreStatements} property for "interceptor mode".
133 | *
134 | * @param ignoreStatements The {@code ignoreStatements} value.
135 | */
136 | public static void setInterceptorProperty(final Set ignoreStatements) {
137 | TracingDriver.ignoreStatements = ignoreStatements;
138 | }
139 |
140 | protected Tracer tracer;
141 |
142 | @Override
143 | public Connection connect(String url, Properties info) throws SQLException {
144 | // if there is no url, we have problems
145 | if (url == null) {
146 | throw new SQLException("url is required");
147 | }
148 |
149 | final Set ignoreStatements;
150 | final boolean withActiveSpanOnly;
151 | if (interceptorMode) {
152 | withActiveSpanOnly = TracingDriver.withActiveSpanOnly;
153 | ignoreStatements = TracingDriver.ignoreStatements;
154 | } else if (acceptsURL(url)) {
155 | withActiveSpanOnly = url.contains(WITH_ACTIVE_SPAN_ONLY);
156 | ignoreStatements = extractIgnoredStatements(url);
157 | } else {
158 | return null;
159 | }
160 |
161 | url = extractRealUrl(url);
162 |
163 | // find the real driver for the URL
164 | final Driver wrappedDriver = findDriver(url);
165 |
166 | final Tracer currentTracer = getTracer();
167 | final ConnectionInfo connectionInfo = URLParser.parse(url);
168 | final String realUrl = url;
169 | final Connection connection = JdbcTracingUtils.call("AcquireConnection", () ->
170 | wrappedDriver.connect(realUrl, info), null, connectionInfo, withActiveSpanOnly,
171 | null, currentTracer);
172 |
173 | return WrapperProxy
174 | .wrap(connection, new TracingConnection(connection, connectionInfo, withActiveSpanOnly,
175 | ignoreStatements, currentTracer));
176 | }
177 |
178 | @Override
179 | public boolean acceptsURL(String url) throws SQLException {
180 | return url != null && (
181 | url.startsWith(getUrlPrefix()) ||
182 | (interceptorMode && url.startsWith("jdbc:"))
183 | );
184 | }
185 |
186 | @Override
187 | public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
188 | return findDriver(url).getPropertyInfo(url, info);
189 | }
190 |
191 | @Override
192 | public int getMajorVersion() {
193 | // There is no way to get it from wrapped driver
194 | return 1;
195 | }
196 |
197 | @Override
198 | public int getMinorVersion() {
199 | // There is no way to get it from wrapped driver
200 | return 0;
201 | }
202 |
203 | @Override
204 | public boolean jdbcCompliant() {
205 | return true;
206 | }
207 |
208 | @Override
209 | public Logger getParentLogger() throws SQLFeatureNotSupportedException {
210 | // There is no way to get it from wrapped driver
211 | return null;
212 | }
213 |
214 | public void setTracer(Tracer tracer) {
215 | this.tracer = tracer;
216 | }
217 |
218 | protected String getUrlPrefix() {
219 | return "jdbc:tracing:";
220 | }
221 |
222 | protected Driver findDriver(String realUrl) throws SQLException {
223 | if (realUrl == null || realUrl.trim().length() == 0) {
224 | throw new IllegalArgumentException("url is required");
225 | }
226 |
227 | for (Driver candidate : Collections.list(DriverManager.getDrivers())) {
228 | try {
229 | if (!(candidate instanceof TracingDriver) && candidate.acceptsURL(realUrl)) {
230 | return candidate;
231 | }
232 | } catch (SQLException ignored) {
233 | // intentionally ignore exception
234 | }
235 | }
236 |
237 | throw new SQLException("Unable to find a driver that accepts url: " + realUrl);
238 | }
239 |
240 | protected String extractRealUrl(String url) {
241 | String extracted = url.startsWith(getUrlPrefix()) ? url.replace(getUrlPrefix(), "jdbc:") : url;
242 | return extracted.replaceAll(TRACE_WITH_ACTIVE_SPAN_ONLY + "=(true|false)[;]*", "")
243 | .replaceAll(IGNORE_FOR_TRACING_REGEX, "")
244 | .replaceAll("\\?$", "");
245 | }
246 |
247 | protected Set extractIgnoredStatements(String url) {
248 |
249 | final Matcher matcher = PATTERN_FOR_IGNORING.matcher(url);
250 |
251 | Set results = new HashSet<>(8);
252 |
253 | while (matcher.find()) {
254 | String rawValue = matcher.group(1);
255 | String finalValue = rawValue.replace("\\\"", "\"");
256 | results.add(finalValue);
257 | }
258 |
259 | return results;
260 | }
261 |
262 | Tracer getTracer() {
263 | if (tracer == null) {
264 | return GlobalTracer.get();
265 | }
266 | return tracer;
267 | }
268 | }
269 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/TracingPreparedStatement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 |
17 | import io.opentracing.Tracer;
18 | import java.io.InputStream;
19 | import java.io.Reader;
20 | import java.math.BigDecimal;
21 | import java.net.URL;
22 | import java.sql.Array;
23 | import java.sql.Blob;
24 | import java.sql.Clob;
25 | import java.sql.Date;
26 | import java.sql.NClob;
27 | import java.sql.ParameterMetaData;
28 | import java.sql.PreparedStatement;
29 | import java.sql.Ref;
30 | import java.sql.ResultSet;
31 | import java.sql.ResultSetMetaData;
32 | import java.sql.RowId;
33 | import java.sql.SQLException;
34 | import java.sql.SQLXML;
35 | import java.sql.Time;
36 | import java.sql.Timestamp;
37 | import java.util.Calendar;
38 | import java.util.Set;
39 |
40 | public class TracingPreparedStatement extends TracingStatement implements PreparedStatement {
41 |
42 | private final PreparedStatement preparedStatement;
43 | private final String query;
44 |
45 | public TracingPreparedStatement(PreparedStatement preparedStatement, String query,
46 | ConnectionInfo connectionInfo, boolean withActiveSpanOnly, Set ignoreStatements,
47 | Tracer tracer) {
48 | super(preparedStatement, query, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
49 | this.preparedStatement = preparedStatement;
50 | this.query = query;
51 | }
52 |
53 | @Override
54 | public ResultSet executeQuery() throws SQLException {
55 | return JdbcTracingUtils.call("Query", preparedStatement::executeQuery,
56 | query, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
57 | }
58 |
59 | @Override
60 | public int executeUpdate() throws SQLException {
61 | return JdbcTracingUtils.call("Update", preparedStatement::executeUpdate,
62 | query, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
63 | }
64 |
65 | @Override
66 | public boolean execute() throws SQLException {
67 | return JdbcTracingUtils.call("Execute", preparedStatement::execute,
68 | query, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
69 | }
70 |
71 | @Override
72 | public void setNull(int parameterIndex, int sqlType) throws SQLException {
73 | preparedStatement.setNull(parameterIndex, sqlType);
74 | }
75 |
76 | @Override
77 | public void setBoolean(int parameterIndex, boolean x) throws SQLException {
78 | preparedStatement.setBoolean(parameterIndex, x);
79 | }
80 |
81 | @Override
82 | public void setByte(int parameterIndex, byte x) throws SQLException {
83 | preparedStatement.setByte(parameterIndex, x);
84 | }
85 |
86 | @Override
87 | public void setShort(int parameterIndex, short x) throws SQLException {
88 | preparedStatement.setShort(parameterIndex, x);
89 | }
90 |
91 | @Override
92 | public void setInt(int parameterIndex, int x) throws SQLException {
93 | preparedStatement.setInt(parameterIndex, x);
94 | }
95 |
96 | @Override
97 | public void setLong(int parameterIndex, long x) throws SQLException {
98 | preparedStatement.setLong(parameterIndex, x);
99 | }
100 |
101 | @Override
102 | public void setFloat(int parameterIndex, float x) throws SQLException {
103 | preparedStatement.setFloat(parameterIndex, x);
104 | }
105 |
106 | @Override
107 | public void setDouble(int parameterIndex, double x) throws SQLException {
108 | preparedStatement.setDouble(parameterIndex, x);
109 | }
110 |
111 | @Override
112 | public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
113 | preparedStatement.setBigDecimal(parameterIndex, x);
114 | }
115 |
116 | @Override
117 | public void setString(int parameterIndex, String x) throws SQLException {
118 | preparedStatement.setString(parameterIndex, x);
119 | }
120 |
121 | @Override
122 | public void setBytes(int parameterIndex, byte[] x) throws SQLException {
123 | preparedStatement.setBytes(parameterIndex, x);
124 | }
125 |
126 | @Override
127 | public void setDate(int parameterIndex, Date x) throws SQLException {
128 | preparedStatement.setDate(parameterIndex, x);
129 | }
130 |
131 | @Override
132 | public void setTime(int parameterIndex, Time x) throws SQLException {
133 | preparedStatement.setTime(parameterIndex, x);
134 | }
135 |
136 | @Override
137 | public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
138 | preparedStatement.setTimestamp(parameterIndex, x);
139 | }
140 |
141 | @Override
142 | public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
143 | preparedStatement.setAsciiStream(parameterIndex, x, length);
144 | }
145 |
146 | @Override
147 | @Deprecated
148 | public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
149 | preparedStatement.setUnicodeStream(parameterIndex, x, length);
150 | }
151 |
152 | @Override
153 | public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
154 | preparedStatement.setBinaryStream(parameterIndex, x, length);
155 | }
156 |
157 | @Override
158 | public void clearParameters() throws SQLException {
159 | preparedStatement.clearParameters();
160 | }
161 |
162 | @Override
163 | public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
164 | preparedStatement.setObject(parameterIndex, x, targetSqlType);
165 | }
166 |
167 | @Override
168 | public void setObject(int parameterIndex, Object x) throws SQLException {
169 | preparedStatement.setObject(parameterIndex, x);
170 | }
171 |
172 | @Override
173 | public void addBatch() throws SQLException {
174 | preparedStatement.addBatch();
175 | }
176 |
177 | @Override
178 | public void setCharacterStream(int parameterIndex, Reader reader, int length)
179 | throws SQLException {
180 | preparedStatement.setCharacterStream(parameterIndex, reader, length);
181 | }
182 |
183 | @Override
184 | public void setRef(int parameterIndex, Ref x) throws SQLException {
185 | preparedStatement.setRef(parameterIndex, x);
186 | }
187 |
188 | @Override
189 | public void setBlob(int parameterIndex, Blob x) throws SQLException {
190 | preparedStatement.setBlob(parameterIndex, x);
191 | }
192 |
193 | @Override
194 | public void setClob(int parameterIndex, Clob x) throws SQLException {
195 | preparedStatement.setClob(parameterIndex, x);
196 | }
197 |
198 | @Override
199 | public void setArray(int parameterIndex, Array x) throws SQLException {
200 | preparedStatement.setArray(parameterIndex, x);
201 | }
202 |
203 | @Override
204 | public ResultSetMetaData getMetaData() throws SQLException {
205 | return preparedStatement.getMetaData();
206 | }
207 |
208 | @Override
209 | public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
210 | preparedStatement.setDate(parameterIndex, x, cal);
211 | }
212 |
213 | @Override
214 | public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
215 | preparedStatement.setTime(parameterIndex, x, cal);
216 | }
217 |
218 | @Override
219 | public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
220 | preparedStatement.setTimestamp(parameterIndex, x, cal);
221 | }
222 |
223 | @Override
224 | public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
225 | preparedStatement.setNull(parameterIndex, sqlType, typeName);
226 | }
227 |
228 | @Override
229 | public void setURL(int parameterIndex, URL x) throws SQLException {
230 | preparedStatement.setURL(parameterIndex, x);
231 | }
232 |
233 | @Override
234 | public ParameterMetaData getParameterMetaData() throws SQLException {
235 | return preparedStatement.getParameterMetaData();
236 | }
237 |
238 | @Override
239 | public void setRowId(int parameterIndex, RowId x) throws SQLException {
240 | preparedStatement.setRowId(parameterIndex, x);
241 | }
242 |
243 | @Override
244 | public void setNString(int parameterIndex, String value) throws SQLException {
245 | preparedStatement.setNString(parameterIndex, value);
246 | }
247 |
248 | @Override
249 | public void setNCharacterStream(int parameterIndex, Reader value, long length)
250 | throws SQLException {
251 | preparedStatement.setNCharacterStream(parameterIndex, value, length);
252 | }
253 |
254 | @Override
255 | public void setNClob(int parameterIndex, NClob value) throws SQLException {
256 | preparedStatement.setNClob(parameterIndex, value);
257 | }
258 |
259 | @Override
260 | public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
261 | preparedStatement.setClob(parameterIndex, reader, length);
262 | }
263 |
264 | @Override
265 | public void setBlob(int parameterIndex, InputStream inputStream, long length)
266 | throws SQLException {
267 | preparedStatement.setBlob(parameterIndex, inputStream, length);
268 | }
269 |
270 | @Override
271 | public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
272 | preparedStatement.setNClob(parameterIndex, reader, length);
273 | }
274 |
275 | @Override
276 | public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
277 | preparedStatement.setSQLXML(parameterIndex, xmlObject);
278 | }
279 |
280 | @Override
281 | public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength)
282 | throws SQLException {
283 | preparedStatement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
284 | }
285 |
286 | @Override
287 | public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
288 | preparedStatement.setAsciiStream(parameterIndex, x, length);
289 | }
290 |
291 | @Override
292 | public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
293 | preparedStatement.setBinaryStream(parameterIndex, x, length);
294 | }
295 |
296 | @Override
297 | public void setCharacterStream(int parameterIndex, Reader reader, long length)
298 | throws SQLException {
299 | preparedStatement.setCharacterStream(parameterIndex, reader, length);
300 | }
301 |
302 | @Override
303 | public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
304 | preparedStatement.setAsciiStream(parameterIndex, x);
305 | }
306 |
307 | @Override
308 | public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
309 | preparedStatement.setBinaryStream(parameterIndex, x);
310 | }
311 |
312 | @Override
313 | public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
314 | preparedStatement.setCharacterStream(parameterIndex, reader);
315 | }
316 |
317 | @Override
318 | public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
319 | preparedStatement.setNCharacterStream(parameterIndex, value);
320 | }
321 |
322 | @Override
323 | public void setClob(int parameterIndex, Reader reader) throws SQLException {
324 | preparedStatement.setClob(parameterIndex, reader);
325 | }
326 |
327 | @Override
328 | public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
329 | preparedStatement.setBlob(parameterIndex, inputStream);
330 | }
331 |
332 | @Override
333 | public void setNClob(int parameterIndex, Reader reader) throws SQLException {
334 | preparedStatement.setNClob(parameterIndex, reader);
335 | }
336 |
337 | }
338 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/TracingStatement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 |
17 | import io.opentracing.Tracer;
18 | import java.sql.Connection;
19 | import java.sql.ResultSet;
20 | import java.sql.SQLException;
21 | import java.sql.SQLWarning;
22 | import java.sql.Statement;
23 | import java.util.ArrayList;
24 | import java.util.Set;
25 |
26 | public class TracingStatement implements Statement {
27 |
28 | private final Statement statement;
29 | private final String query;
30 | private final ArrayList batchCommands = new ArrayList<>();
31 | final ConnectionInfo connectionInfo;
32 | final boolean withActiveSpanOnly;
33 | final Set ignoreStatements;
34 | final Tracer tracer;
35 |
36 | TracingStatement(Statement statement, ConnectionInfo connectionInfo, boolean withActiveSpanOnly,
37 | Set ignoreStatements, Tracer tracer) {
38 | this(statement, null, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
39 | }
40 |
41 | TracingStatement(Statement statement, String query, ConnectionInfo connectionInfo,
42 | boolean withActiveSpanOnly, Set ignoreStatements, Tracer tracer) {
43 | this.statement = statement;
44 | this.query = query;
45 | this.connectionInfo = connectionInfo;
46 | this.withActiveSpanOnly = withActiveSpanOnly;
47 | this.ignoreStatements = ignoreStatements;
48 | this.tracer = tracer;
49 | }
50 |
51 | @Override
52 | public ResultSet executeQuery(String sql) throws SQLException {
53 | return JdbcTracingUtils.call("Query", () -> statement.executeQuery(sql),
54 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
55 | }
56 |
57 | @Override
58 | public int executeUpdate(String sql) throws SQLException {
59 | return JdbcTracingUtils.call("Update", () -> statement.executeUpdate(sql),
60 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
61 | }
62 |
63 | @Override
64 | public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
65 | return JdbcTracingUtils.call("Update", () -> statement.executeUpdate(sql, autoGeneratedKeys),
66 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
67 | }
68 |
69 | @Override
70 | public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
71 | return JdbcTracingUtils.call("Update", () -> statement.executeUpdate(sql, columnIndexes),
72 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
73 | }
74 |
75 | @Override
76 | public int executeUpdate(String sql, String[] columnNames) throws SQLException {
77 | return JdbcTracingUtils.call("Update", () -> statement.executeUpdate(sql, columnNames),
78 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
79 | }
80 |
81 | @Override
82 | public boolean execute(String sql) throws SQLException {
83 | return JdbcTracingUtils.call("Execute", () -> statement.execute(sql),
84 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
85 | }
86 |
87 | @Override
88 | public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
89 | return JdbcTracingUtils.call("Execute", () -> statement.execute(sql, autoGeneratedKeys),
90 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
91 | }
92 |
93 | @Override
94 | public boolean execute(String sql, int[] columnIndexes) throws SQLException {
95 | return JdbcTracingUtils.call("Execute", () -> statement.execute(sql, columnIndexes),
96 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
97 | }
98 |
99 | @Override
100 | public boolean execute(String sql, String[] columnNames) throws SQLException {
101 | return JdbcTracingUtils.call("Execute", () -> statement.execute(sql, columnNames),
102 | sql, connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
103 | }
104 |
105 | @Override
106 | public int[] executeBatch() throws SQLException {
107 | return JdbcTracingUtils.call("Update", statement::executeBatch,
108 | buildSqlForBatch(), connectionInfo, withActiveSpanOnly, ignoreStatements, tracer);
109 | }
110 |
111 | @Override
112 | public void close() throws SQLException {
113 | statement.close();
114 | }
115 |
116 | @Override
117 | public int getMaxFieldSize() throws SQLException {
118 | return statement.getMaxFieldSize();
119 | }
120 |
121 | @Override
122 | public void setMaxFieldSize(int max) throws SQLException {
123 | statement.setMaxFieldSize(max);
124 | }
125 |
126 | @Override
127 | public int getMaxRows() throws SQLException {
128 | return statement.getMaxRows();
129 | }
130 |
131 | @Override
132 | public void setMaxRows(int max) throws SQLException {
133 | statement.setMaxRows(max);
134 | }
135 |
136 | @Override
137 | public void setEscapeProcessing(boolean enable) throws SQLException {
138 | statement.setEscapeProcessing(enable);
139 | }
140 |
141 | @Override
142 | public int getQueryTimeout() throws SQLException {
143 | return statement.getQueryTimeout();
144 | }
145 |
146 | @Override
147 | public void setQueryTimeout(int seconds) throws SQLException {
148 | statement.setQueryTimeout(seconds);
149 | }
150 |
151 | @Override
152 | public void cancel() throws SQLException {
153 | statement.cancel();
154 | }
155 |
156 | @Override
157 | public SQLWarning getWarnings() throws SQLException {
158 | return statement.getWarnings();
159 | }
160 |
161 | @Override
162 | public void clearWarnings() throws SQLException {
163 | statement.clearWarnings();
164 | }
165 |
166 | @Override
167 | public void setCursorName(String name) throws SQLException {
168 | statement.setCursorName(name);
169 | }
170 |
171 | @Override
172 | public ResultSet getResultSet() throws SQLException {
173 | return statement.getResultSet();
174 | }
175 |
176 | @Override
177 | public int getUpdateCount() throws SQLException {
178 | return statement.getUpdateCount();
179 | }
180 |
181 | @Override
182 | public boolean getMoreResults() throws SQLException {
183 | return statement.getMoreResults();
184 | }
185 |
186 | @Override
187 | public void setFetchDirection(int direction) throws SQLException {
188 | statement.setFetchDirection(direction);
189 | }
190 |
191 | @Override
192 | public int getFetchDirection() throws SQLException {
193 | return statement.getFetchDirection();
194 | }
195 |
196 | @Override
197 | public void setFetchSize(int rows) throws SQLException {
198 | statement.setFetchSize(rows);
199 | }
200 |
201 | @Override
202 | public int getFetchSize() throws SQLException {
203 | return statement.getFetchSize();
204 | }
205 |
206 | @Override
207 | public int getResultSetConcurrency() throws SQLException {
208 | return statement.getResultSetConcurrency();
209 | }
210 |
211 | @Override
212 | public int getResultSetType() throws SQLException {
213 | return statement.getResultSetType();
214 | }
215 |
216 | @Override
217 | public void addBatch(String sql) throws SQLException {
218 | statement.addBatch(sql);
219 | batchCommands.add(sql);
220 | }
221 |
222 | @Override
223 | public void clearBatch() throws SQLException {
224 | statement.clearBatch();
225 | batchCommands.clear();
226 | }
227 |
228 | @Override
229 | public Connection getConnection() throws SQLException {
230 | return statement.getConnection();
231 | }
232 |
233 | @Override
234 | public boolean getMoreResults(int current) throws SQLException {
235 | return statement.getMoreResults(current);
236 | }
237 |
238 | @Override
239 | public ResultSet getGeneratedKeys() throws SQLException {
240 | return statement.getGeneratedKeys();
241 | }
242 |
243 | @Override
244 | public int getResultSetHoldability() throws SQLException {
245 | return statement.getResultSetHoldability();
246 | }
247 |
248 | @Override
249 | public boolean isClosed() throws SQLException {
250 | return statement.isClosed();
251 | }
252 |
253 | @Override
254 | public void setPoolable(boolean poolable) throws SQLException {
255 | statement.setPoolable(poolable);
256 | }
257 |
258 | @Override
259 | public boolean isPoolable() throws SQLException {
260 | return statement.isPoolable();
261 | }
262 |
263 | @Override
264 | public void closeOnCompletion() throws SQLException {
265 | statement.closeOnCompletion();
266 | }
267 |
268 | @Override
269 | public boolean isCloseOnCompletion() throws SQLException {
270 | return statement.isCloseOnCompletion();
271 | }
272 |
273 | @Override
274 | public T unwrap(Class iface) throws SQLException {
275 | return statement.unwrap(iface);
276 | }
277 |
278 | @Override
279 | public boolean isWrapperFor(Class> iface) throws SQLException {
280 | return statement.isWrapperFor(iface);
281 | }
282 |
283 | public String getQuery() {
284 | return query;
285 | }
286 |
287 | @Override
288 | public String toString() {
289 | return getQuery();
290 | }
291 |
292 | private String buildSqlForBatch() {
293 | StringBuilder sqlBuilder = new StringBuilder();
294 | if (query != null) {
295 | sqlBuilder.append(query);
296 | }
297 |
298 | for (String batchCommand : batchCommands) {
299 | sqlBuilder.append(batchCommand);
300 | }
301 |
302 | return sqlBuilder.toString();
303 | }
304 | }
305 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/AS400URLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 |
17 | import java.util.regex.Pattern;
18 |
19 |
20 | /**
21 | * Parser for AS400
22 | *
23 | * @author oburgosm
24 | * @since 0.2.12
25 | */
26 | public class AS400URLParser extends AbstractMatcherURLParser {
27 |
28 | private static final Pattern AS400_URL_PATTERN = Pattern
29 | .compile(
30 | "jdbc:as400:\\/\\/(?[^\\/;]+)(\\/(?[^;\\/]*))?\\/?(;(?.*))?");
31 |
32 | private static final String AS400_TYPE = "as400";
33 |
34 | public AS400URLParser() {
35 | super(AS400_URL_PATTERN, AS400_TYPE);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/AbstractMatcherURLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import io.opentracing.contrib.jdbc.ConnectionInfo;
17 | import java.util.regex.Matcher;
18 | import java.util.regex.Pattern;
19 |
20 | /**
21 | * Parser based on regular expression
22 | *
23 | * @author oburgosm
24 | * @since 0.2.12
25 | */
26 | public abstract class AbstractMatcherURLParser implements ConnectionURLParser {
27 |
28 | private final Pattern pattern;
29 |
30 | private final String dbType;
31 |
32 | public AbstractMatcherURLParser(Pattern pattern, String dbType) {
33 | this.pattern = pattern;
34 | this.dbType = dbType;
35 | }
36 |
37 | /**
38 | * Useful to modify ConnectionInfo before build
39 | *
40 | * @param matcher The matcher to apply. Note that the matcher must have a group named host, and
41 | * optionally, a group named port and another named instance
42 | * @return
43 | */
44 | protected ConnectionInfo.Builder initBuilder(Matcher matcher) {
45 | String host = matcher.group("host");
46 | String port = null;
47 | try {
48 | port = matcher.group("port");
49 | } catch (IllegalArgumentException e) {
50 | // The pattern has no instance port
51 | }
52 | ConnectionInfo.Builder builder;
53 | if (port == null || "".equals(port)) {
54 | builder = new ConnectionInfo.Builder(host);
55 | } else {
56 | builder = new ConnectionInfo.Builder(host, Integer.valueOf(port));
57 | }
58 | String instance = ConnectionInfo.UNKNOWN_CONNECTION_INFO.getDbInstance();
59 | try {
60 | instance = matcher.group("instance");
61 | if (instance == null || "".equals(instance)) {
62 | instance = ConnectionInfo.UNKNOWN_CONNECTION_INFO.getDbInstance();
63 | }
64 | } catch (IllegalArgumentException e) {
65 | // The pattern has no instance group
66 | }
67 | return builder
68 | .dbType(this.dbType)
69 | .dbInstance(instance);
70 | }
71 |
72 |
73 | @Override
74 | public ConnectionInfo parse(String url) {
75 | Matcher matcher = this.pattern.matcher(url);
76 | if (matcher.matches()) {
77 | return this.initBuilder(matcher).build();
78 | } else {
79 | return ConnectionInfo.UNKNOWN_CONNECTION_INFO;
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/AbstractURLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | public abstract class AbstractURLParser implements ConnectionURLParser {
17 |
18 | /**
19 | * Fetch the index range that database host and port from connection url.
20 | *
21 | * @return index range that database hosts.
22 | */
23 | protected abstract URLLocation fetchDatabaseHostsIndexRange(final String url);
24 |
25 | /**
26 | * Fetch the index range that database name from connection url.
27 | *
28 | * @return index range that database name.
29 | */
30 | protected abstract URLLocation fetchDatabaseNameIndexRange(final String url);
31 |
32 | /**
33 | * Fetch database host(s) from connection url.
34 | *
35 | * @return database host(s).
36 | */
37 | protected String fetchDatabaseHostsFromURL(String url) {
38 | URLLocation hostsLocation = fetchDatabaseHostsIndexRange(url);
39 | return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
40 | }
41 |
42 | /**
43 | * Fetch database name from connection url.
44 | *
45 | * @return database name.
46 | */
47 | protected String fetchDatabaseNameFromURL(String url) {
48 | URLLocation hostsLocation = fetchDatabaseNameIndexRange(url);
49 | return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
50 | }
51 |
52 | /**
53 | * Fetch database name from connection url.
54 | *
55 | * @return database name.
56 | */
57 | protected String fetchDatabaseNameFromURL(String url, int[] indexRange) {
58 | return url.substring(indexRange[0], indexRange[1]);
59 | }
60 |
61 | }
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/ConnectionURLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import io.opentracing.contrib.jdbc.ConnectionInfo;
17 |
18 | public interface ConnectionURLParser {
19 | ConnectionInfo parse(final String url);
20 | }
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/DB2URLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import java.util.regex.Pattern;
17 |
18 |
19 | /**
20 | * Parser for DB2
21 | *
22 | * @author oburgosm
23 | * @since 0.2.12
24 | */
25 | public class DB2URLParser extends AbstractMatcherURLParser {
26 |
27 |
28 | private static final Pattern DB2_URL_PATTERN = Pattern
29 | .compile(
30 | "jdbc:db2:\\/\\/(?[^:\\/]+)(:(?\\d+))?\\/(?[^:]+)(:(?.*))?");
31 |
32 | private static final String DB2_TYPE = "db2";
33 |
34 | public DB2URLParser() {
35 | super(DB2_URL_PATTERN, DB2_TYPE);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/H2URLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import io.opentracing.contrib.jdbc.ConnectionInfo;
17 |
18 | public class H2URLParser extends AbstractURLParser {
19 |
20 | private static final String LOCALHOST = "localhost";
21 | private static final int DEFAULT_PORT = 8084;
22 | /**
23 | * Flag that H2 running with memory mode.
24 | */
25 | private static final String MEMORY_MODE_FLAG = "mem";
26 | /**
27 | * Flag that H2 running with tcp mode.
28 | */
29 | private static final String TCP_MODE_FLAG = "h2:tcp";
30 | /**
31 | * Flag that H2 running with file mode.
32 | */
33 | private static final String FILE_MODE_FLAG = "file";
34 | /**
35 | * Flag that H2 running with implicit file mode.
36 | */
37 | private static final String IMPLICIT_FILE_MODE_FLAG = "jdbc:h2";
38 | private static final String H2_DB_TYPE = "h2";
39 |
40 | @Override
41 | protected URLLocation fetchDatabaseHostsIndexRange(String url) {
42 | int hostLabelStartIndex = url.indexOf("//");
43 | int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
44 | return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
45 | }
46 |
47 | @Override
48 | protected URLLocation fetchDatabaseNameIndexRange(String url) {
49 | int databaseStartTag = url.lastIndexOf("/");
50 | int databaseEndTag = url.indexOf(";");
51 | if (databaseEndTag == -1) {
52 | databaseEndTag = url.length();
53 | }
54 | return new URLLocation(databaseStartTag + 1, databaseEndTag);
55 | }
56 |
57 | @Override
58 | public ConnectionInfo parse(String url) {
59 | int[] databaseNameRangeIndex = fetchDatabaseNameRangeIndexFromURLForH2FileMode(url);
60 | if (databaseNameRangeIndex != null) {
61 | return new ConnectionInfo.Builder(LOCALHOST, -1).dbType(H2_DB_TYPE)
62 | .dbInstance(fetchDatabaseNameFromURL(url, databaseNameRangeIndex)).build();
63 | }
64 |
65 | databaseNameRangeIndex = fetchDatabaseNameRangeIndexFromURLForH2MemMode(url);
66 | if (databaseNameRangeIndex != null) {
67 | return new ConnectionInfo.Builder(LOCALHOST, -1).dbType(H2_DB_TYPE)
68 | .dbInstance(fetchDatabaseNameFromURL(url, databaseNameRangeIndex)).build();
69 | }
70 |
71 | databaseNameRangeIndex = fetchDatabaseNameRangeIndexFromURLForH2ImplicitFileMode(url);
72 | if (databaseNameRangeIndex != null) {
73 | return new ConnectionInfo.Builder(LOCALHOST, -1).dbType(H2_DB_TYPE)
74 | .dbInstance(fetchDatabaseNameFromURL(url, databaseNameRangeIndex)).build();
75 | }
76 |
77 | String[] hostAndPort = fetchDatabaseHostsFromURL(url).split(":");
78 | if (hostAndPort.length == 1) {
79 | return new ConnectionInfo.Builder(hostAndPort[0], DEFAULT_PORT).dbType(H2_DB_TYPE)
80 | .dbInstance(fetchDatabaseNameFromURL(url)).build();
81 | } else {
82 | return new ConnectionInfo.Builder(hostAndPort[0], Integer.valueOf(hostAndPort[1]))
83 | .dbType(H2_DB_TYPE).dbInstance(fetchDatabaseNameFromURL(url)).build();
84 | }
85 | }
86 |
87 | /**
88 | * Fetch range index that the database name from connection url if H2 database running with file
89 | * mode.
90 | *
91 | * @return range index that the database name.
92 | */
93 | private int[] fetchDatabaseNameRangeIndexFromURLForH2FileMode(String url) {
94 | int fileLabelIndex = url.indexOf(FILE_MODE_FLAG);
95 | int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
96 | if (parameterLabelIndex == -1) {
97 | parameterLabelIndex = url.length();
98 | }
99 |
100 | if (fileLabelIndex != -1) {
101 | return new int[]{fileLabelIndex + FILE_MODE_FLAG.length() + 1, parameterLabelIndex};
102 | } else {
103 | return null;
104 | }
105 | }
106 |
107 | /**
108 | * Fetch range index that the database name from connection url if H2 database running with
109 | * implicit file mode.
110 | *
111 | * @return range index that the database name.
112 | */
113 | private int[] fetchDatabaseNameRangeIndexFromURLForH2ImplicitFileMode(String url) {
114 | if (url.contains(TCP_MODE_FLAG)) {
115 | return null;
116 | }
117 | int fileLabelIndex = url.indexOf(IMPLICIT_FILE_MODE_FLAG);
118 | int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
119 | if (parameterLabelIndex == -1) {
120 | parameterLabelIndex = url.length();
121 | }
122 |
123 | if (fileLabelIndex != -1) {
124 | return new int[]{fileLabelIndex + IMPLICIT_FILE_MODE_FLAG.length() + 1, parameterLabelIndex};
125 | } else {
126 | return null;
127 | }
128 | }
129 |
130 | /**
131 | * Fetch range index that the database name from connection url if H2 database running with memory
132 | * mode.
133 | *
134 | * @return range index that the database name.
135 | */
136 | private int[] fetchDatabaseNameRangeIndexFromURLForH2MemMode(String url) {
137 | int fileLabelIndex = url.indexOf(MEMORY_MODE_FLAG);
138 | int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
139 | if (parameterLabelIndex == -1) {
140 | parameterLabelIndex = url.length();
141 | }
142 |
143 | if (fileLabelIndex != -1) {
144 | return new int[]{fileLabelIndex + MEMORY_MODE_FLAG.length() + 1, parameterLabelIndex};
145 | } else {
146 | return null;
147 | }
148 | }
149 |
150 |
151 | }
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/MariadbURLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | public class MariadbURLParser extends MysqlURLParser {
17 |
18 | protected String dbType() {
19 | return "mariadb";
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/MysqlURLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import io.opentracing.contrib.jdbc.ConnectionInfo;
17 |
18 | public class MysqlURLParser extends AbstractURLParser {
19 |
20 | private static final String DEFAULT_HOST = "localhost";
21 |
22 | private static final int DEFAULT_PORT = 3306;
23 |
24 | protected String dbType() {
25 | return "mysql";
26 | }
27 |
28 | @Override
29 | protected URLLocation fetchDatabaseHostsIndexRange(String url) {
30 | int hostLabelStartIndex = url.indexOf("//") + 2;
31 | int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex);
32 | if (hostLabelEndIndex == -1) {
33 | int queryStringStartIndex = url.indexOf("?", hostLabelStartIndex);
34 | if (queryStringStartIndex == -1) {
35 | hostLabelEndIndex = url.length();
36 | } else {
37 | hostLabelEndIndex = queryStringStartIndex;
38 | }
39 | }
40 | return new URLLocation(hostLabelStartIndex, hostLabelEndIndex);
41 | }
42 |
43 | protected String fetchDatabaseNameFromURL(String url, int startSize) {
44 | URLLocation hostsLocation = fetchDatabaseNameIndexRange(url, startSize);
45 | if (hostsLocation == null) {
46 | return "";
47 | }
48 | return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
49 | }
50 |
51 | protected URLLocation fetchDatabaseNameIndexRange(String url, int startSize) {
52 | int databaseStartTag = url.indexOf("/", startSize);
53 | if (databaseStartTag == -1) {
54 | return null;
55 | }
56 | int databaseEndTag = url.indexOf("?", databaseStartTag);
57 | if (databaseEndTag == -1) {
58 | databaseEndTag = url.length();
59 | }
60 | return new URLLocation(databaseStartTag + 1, databaseEndTag);
61 | }
62 |
63 | @Override
64 | protected URLLocation fetchDatabaseNameIndexRange(String url) {
65 | int databaseStartTag = url.lastIndexOf("/");
66 | int databaseEndTag = url.indexOf("?", databaseStartTag);
67 | if (databaseEndTag == -1) {
68 | databaseEndTag = url.length();
69 | }
70 | return new URLLocation(databaseStartTag + 1, databaseEndTag);
71 | }
72 |
73 | @Override
74 | public ConnectionInfo parse(String url) {
75 | URLLocation location = fetchDatabaseHostsIndexRange(url);
76 | String hosts = url.substring(location.startIndex(), location.endIndex());
77 | if (hosts.isEmpty()) {
78 | hosts = DEFAULT_HOST;
79 | }
80 | String[] hostSegment = hosts.split(",");
81 | if (hostSegment.length > 1) {
82 | StringBuilder sb = new StringBuilder();
83 | for (String host : hostSegment) {
84 | if (host.split(":").length == 1) {
85 | sb.append(host + ":" + DEFAULT_PORT + ",");
86 | } else {
87 | sb.append(host + ",");
88 | }
89 | }
90 | if (',' == sb.charAt(sb.length() - 1)) {
91 | sb.deleteCharAt(sb.length() - 1);
92 | }
93 | return new ConnectionInfo.Builder(sb.toString()).dbType(dbType())
94 | .dbInstance(fetchDatabaseNameFromURL(url)).build();
95 | } else {
96 | String[] hostAndPort = hostSegment[0].split(":");
97 | if (hostAndPort.length != 1) {
98 | return new ConnectionInfo.Builder(hostAndPort[0], Integer.valueOf(hostAndPort[1]))
99 | .dbType(dbType()).dbInstance(fetchDatabaseNameFromURL(url, location.endIndex()))
100 | .build();
101 | } else {
102 |
103 | return new ConnectionInfo.Builder(hostAndPort[0], DEFAULT_PORT).dbType(dbType())
104 | .dbInstance(fetchDatabaseNameFromURL(url, location.endIndex())).build();
105 | }
106 | }
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/OracleURLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import java.util.ArrayList;
17 | import java.util.List;
18 | import java.util.regex.Matcher;
19 | import java.util.regex.Pattern;
20 |
21 | import io.opentracing.contrib.jdbc.ConnectionInfo;
22 |
23 | public class OracleURLParser implements ConnectionURLParser {
24 | public static final String DB_TYPE = "oracle";
25 | public static final String PREFIX_THIN = "jdbc:oracle:thin:";
26 | public static final String PREFIX_OCI = "jdbc:oracle:oci:";
27 | public static final int DEFAULT_PORT = 1521;
28 | private static Pattern EASY_CONNECT_PATTERN = Pattern.compile(
29 | "(?.*)@(?ldap:)?(//)?(?[^:/]+)(?:[0-9]+)?(?[:/][^:/]+)?(?:[^:/]+)?(?/[^:/]+)?");
30 |
31 | @Override
32 | public ConnectionInfo parse(final String url) {
33 | if (url!= null) {
34 | String lowerCaseUrl = url.toLowerCase();
35 | if ((lowerCaseUrl.startsWith(PREFIX_THIN) || lowerCaseUrl.startsWith(PREFIX_OCI))) {
36 | String trimmedURL;
37 | if (lowerCaseUrl.startsWith(PREFIX_THIN)) {
38 | trimmedURL = url.substring(PREFIX_THIN.length());
39 | } else {
40 | trimmedURL = url.substring(PREFIX_OCI.length());
41 | }
42 | OracleConnectionInfo connectionInfo = parseTnsName(trimmedURL);
43 | if (connectionInfo == null) {
44 | connectionInfo = parseEasyConnect(trimmedURL);
45 | }
46 | if (connectionInfo != null) {
47 | return new ConnectionInfo.Builder(connectionInfo.getDbPeer()) //
48 | .dbType(DB_TYPE) //
49 | .dbInstance(connectionInfo.getDbInstance()) //
50 | .build();
51 | }
52 | }
53 | }
54 | return null;
55 | }
56 |
57 | private OracleConnectionInfo parseTnsName(final String url) {
58 | final String hosts = parseDatabaseHostsFromTnsUrl(url);
59 | if (hosts != null) {
60 | final int idxServiceName = url.indexOf("SERVICE_NAME");
61 | final int start = url.indexOf('=', idxServiceName) + 1;
62 | final int end = url.indexOf(")", start);
63 | final String serviceName = url.substring(start, end);
64 | return new OracleConnectionInfo() //
65 | .setDbPeer(hosts) //
66 | .setDbInstance(serviceName);
67 | }
68 | return null;
69 | }
70 |
71 | public static String parseDatabaseHostsFromTnsUrl(String url) {
72 | int beginIndex = url.indexOf("DESCRIPTION");
73 | if (beginIndex == -1) {
74 | return null;
75 | }
76 | List hosts = new ArrayList();
77 | do {
78 | int hostStartIndex = url.indexOf("HOST", beginIndex);
79 | if (hostStartIndex == -1) {
80 | break;
81 | }
82 | int equalStartIndex = url.indexOf("=", hostStartIndex);
83 | int hostEndIndex = url.indexOf(")", hostStartIndex);
84 | String host = url.substring(equalStartIndex + 1, hostEndIndex);
85 |
86 | int port = DEFAULT_PORT;
87 | int portStartIndex = url.indexOf("PORT", hostEndIndex);
88 | int portEndIndex = url.length();
89 | if (portStartIndex != -1) {
90 | int portEqualStartIndex = url.indexOf("=", portStartIndex);
91 | portEndIndex = url.indexOf(")", portEqualStartIndex);
92 | port = Integer.parseInt(url.substring(portEqualStartIndex + 1, portEndIndex).trim());
93 | }
94 | hosts.add(host.trim() + ":" + port);
95 | beginIndex = portEndIndex;
96 | } while (true);
97 | return join(",", hosts);
98 | }
99 |
100 | private static String join(String delimiter, List list) {
101 | if (list == null || list.isEmpty()) {
102 | return "";
103 | }
104 | StringBuilder builder = new StringBuilder();
105 | for (int i = 0, len = list.size(); i < len; i++) {
106 | if (i == (len - 1)) {
107 | builder.append(list.get(i));
108 | } else {
109 | builder.append(list.get(i)).append(delimiter);
110 | }
111 | }
112 | return builder.toString();
113 | }
114 |
115 | /**
116 | * Implementation according to https://www.oracle.com/technetwork/database/enterprise-edition/oraclenetservices-neteasyconnect-133058.pdf
117 | *
118 | * @param url the url without the oracle jdbc prefix
119 | * @return the oracle connection info if the url could be parsed, or null otherwise.
120 | */
121 | public static OracleConnectionInfo parseEasyConnect(final String url) {
122 | final Matcher matcher = EASY_CONNECT_PATTERN.matcher(url);
123 | if (matcher.matches()) {
124 | final OracleConnectionInfo result = new OracleConnectionInfo();
125 | final String host = matcher.group("host");
126 | final String portGroup = matcher.group("port");
127 | final int dbPort =
128 | portGroup != null ? Integer.parseInt(portGroup.substring(1)) : DEFAULT_PORT;
129 | result.setDbPeer(host + ":" + dbPort);
130 | final String service = matcher.group("service");
131 | if (service != null) {
132 | result.setDbInstance(service.substring(1));
133 | } else {
134 | result.setDbInstance(host);
135 | }
136 | return result;
137 | }
138 | return null;
139 | }
140 |
141 | public static class OracleConnectionInfo {
142 | private String dbInstance;
143 | private String dbPeer;
144 |
145 | public String getDbInstance() {
146 | return dbInstance;
147 | }
148 |
149 | public OracleConnectionInfo setDbInstance(final String dbInstance) {
150 | this.dbInstance = dbInstance;
151 | return this;
152 | }
153 |
154 | public String getDbPeer() {
155 | return dbPeer;
156 | }
157 |
158 | public OracleConnectionInfo setDbPeer(final String dbPeer) {
159 | this.dbPeer = dbPeer;
160 | return this;
161 | }
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/PostgreSQLURLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import io.opentracing.contrib.jdbc.ConnectionInfo;
17 | import java.net.URI;
18 | import java.net.URISyntaxException;
19 |
20 | public class PostgreSQLURLParser extends AbstractURLParser {
21 |
22 | private static final int DEFAULT_PORT = 5432;
23 | private static final String DB_TYPE = "postgresql";
24 |
25 | @Override
26 | protected URLLocation fetchDatabaseHostsIndexRange(String url) {
27 | int hostLabelStartIndex = url.indexOf("//");
28 | int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
29 | return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
30 | }
31 |
32 | @Override
33 | protected URLLocation fetchDatabaseNameIndexRange(String url) {
34 | int hostLabelStartIndex = url.indexOf("//");
35 | int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
36 | int databaseStartTag = url.indexOf("/", hostLabelEndIndex);
37 | int databaseEndTag = url.indexOf("?", databaseStartTag);
38 | if (databaseEndTag == -1) {
39 | databaseEndTag = url.length();
40 | }
41 | return new URLLocation(databaseStartTag + 1, databaseEndTag);
42 | }
43 |
44 | @Override
45 | public ConnectionInfo parse(String url) {
46 | URLLocation location = fetchDatabaseHostsIndexRange(url);
47 | String hosts = url.substring(location.startIndex(), location.endIndex());
48 | String[] hostSegment = hosts.split(",");
49 | if (hostSegment.length > 1) {
50 | StringBuilder sb = new StringBuilder();
51 | for (String host : hostSegment) {
52 | URI uri = parseHost(host);
53 | int port = uri.getPort() == -1 ? DEFAULT_PORT : uri.getPort();
54 |
55 | sb.append(uri.getHost() + ":" + port + ",");
56 | }
57 | if (',' == sb.charAt(sb.length() - 1)) {
58 | sb.deleteCharAt(sb.length() - 1);
59 | }
60 | return new ConnectionInfo.Builder(sb.toString()).dbType(DB_TYPE)
61 | .dbInstance(fetchDatabaseNameFromURL(url)).build();
62 | } else {
63 | URI uri = parseHost(hostSegment[0]);
64 | int port = uri.getPort() == -1 ? DEFAULT_PORT : uri.getPort();
65 |
66 | return new ConnectionInfo.Builder(uri.getHost(), port)
67 | .dbType(DB_TYPE).dbInstance(fetchDatabaseNameFromURL(url)).build();
68 | }
69 | }
70 |
71 | private URI parseHost(String host) {
72 | try {
73 | return new URI("proto://" + host);
74 | } catch (URISyntaxException e) {
75 | throw new IllegalArgumentException(e);
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/SqlServerURLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import io.opentracing.contrib.jdbc.ConnectionInfo;
17 | import java.io.UnsupportedEncodingException;
18 | import java.net.URLDecoder;
19 | import java.nio.charset.StandardCharsets;
20 | import java.util.Collections;
21 | import java.util.LinkedHashMap;
22 | import java.util.Map;
23 |
24 | public class SqlServerURLParser implements ConnectionURLParser {
25 |
26 | private static final int DEFAULT_PORT = 1433;
27 |
28 | protected String dbType() {
29 | return "sqlserver";
30 | }
31 |
32 | @Override
33 | public ConnectionInfo parse(String url) {
34 | String serverName = "";
35 | Integer port = DEFAULT_PORT;
36 | String dbInstance = null;
37 | int hostIndex = url.indexOf("://");
38 | if (hostIndex <= 0) {
39 | return null;
40 | }
41 |
42 | String[] split = url.split(";", 2);
43 | if (split.length > 1) {
44 | Map props = parseQueryParams(split[1], ";");
45 | serverName = props.get("serverName");
46 | dbInstance = props.get("databaseName");
47 | if (props.containsKey("portNumber")) {
48 | String portNumber = props.get("portNumber");
49 | try {
50 | port = Integer.parseInt(portNumber);
51 | } catch (NumberFormatException e) {
52 | }
53 | }
54 | }
55 |
56 | String urlServerName = split[0].substring(hostIndex + 3);
57 | if (!urlServerName.isEmpty()) {
58 | serverName = urlServerName;
59 | }
60 |
61 | int portLoc = serverName.indexOf(":");
62 | if (portLoc > 1) {
63 | port = Integer.parseInt(serverName.substring(portLoc + 1));
64 | serverName = serverName.substring(0, portLoc);
65 | }
66 |
67 | int instanceLoc = serverName.indexOf("\\");
68 | if (instanceLoc > 1) {
69 | serverName = serverName.substring(0, instanceLoc);
70 | }
71 |
72 | if (serverName.isEmpty()) {
73 | return null;
74 | }
75 |
76 | return new ConnectionInfo.Builder(serverName, port).dbType(dbType())
77 | .dbInstance(dbInstance).build();
78 | }
79 |
80 | private Map parseQueryParams(String query, String separator) {
81 | if (query == null || query.isEmpty()) {
82 | return Collections.emptyMap();
83 | }
84 | Map queryParams = new LinkedHashMap<>();
85 | String[] pairs = query.split(separator);
86 | for (String pair : pairs) {
87 | try {
88 | int idx = pair.indexOf("=");
89 | String key =
90 | idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8.name())
91 | : pair;
92 | if (!queryParams.containsKey(key)) {
93 | String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder
94 | .decode(pair.substring(idx + 1), StandardCharsets.UTF_8.name()) : null;
95 | queryParams.put(key, value);
96 | }
97 | } catch (UnsupportedEncodingException e) {
98 | // Ignore.
99 | }
100 | }
101 | return queryParams;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/URLLocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | public class URLLocation {
17 | private final int startIndex;
18 | private final int endIndex;
19 |
20 | public URLLocation(int startIndex, int endIndex) {
21 | this.startIndex = startIndex;
22 | this.endIndex = endIndex;
23 | }
24 |
25 | public int startIndex() {
26 | return startIndex;
27 | }
28 |
29 | public int endIndex() {
30 | return endIndex;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/io/opentracing/contrib/jdbc/parser/URLParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import io.opentracing.contrib.jdbc.ConnectionInfo;
17 | import java.util.LinkedHashMap;
18 | import java.util.Map;
19 | import java.util.logging.Level;
20 | import java.util.logging.Logger;
21 |
22 | public class URLParser {
23 | private static final Logger log = Logger.getLogger(URLParser.class.getName());
24 |
25 | private static final String MYSQL_JDBC_URL_PREFIX = "jdbc:mysql";
26 | private static final String ORACLE_JDBC_URL_PREFIX = "jdbc:oracle";
27 | private static final String H2_JDBC_URL_PREFIX = "jdbc:h2";
28 | private static final String POSTGRESQL_JDBC_URL_PREFIX = "jdbc:postgresql";
29 | private static final String MARIADB_JDBC_URL_PREFIX = "jdbc:mariadb";
30 | private static final String SQLSERVER_JDBC_URL_PREFIX = "jdbc:sqlserver";
31 | private static final String DB2_JDBC_URL_PREFIX = "jdbc:db2";
32 | private static final String AS400_JDBC_URL_PREFIX = "jdbc:as400";
33 | private static final Map parserRegister = new LinkedHashMap<>();
34 |
35 | static {
36 | // put mysql parser firstly
37 | parserRegister.put(MYSQL_JDBC_URL_PREFIX, new MysqlURLParser());
38 | parserRegister.put(ORACLE_JDBC_URL_PREFIX, new OracleURLParser());
39 | parserRegister.put(H2_JDBC_URL_PREFIX, new H2URLParser());
40 | parserRegister.put(POSTGRESQL_JDBC_URL_PREFIX, new PostgreSQLURLParser());
41 | parserRegister.put(MARIADB_JDBC_URL_PREFIX, new MariadbURLParser());
42 | parserRegister.put(SQLSERVER_JDBC_URL_PREFIX, new SqlServerURLParser());
43 | parserRegister.put(DB2_JDBC_URL_PREFIX, new DB2URLParser());
44 | parserRegister.put(AS400_JDBC_URL_PREFIX, new AS400URLParser());
45 | }
46 |
47 | /**
48 | * parse the url to the ConnectionInfo
49 | */
50 | public static ConnectionInfo parse(String url) {
51 | if (null == url) {
52 | return ConnectionInfo.UNKNOWN_CONNECTION_INFO;
53 | }
54 | String lowerCaseUrl = url.toLowerCase();
55 | ConnectionURLParser parser = findURLParser(lowerCaseUrl);
56 | if (parser == null) {
57 | return ConnectionInfo.UNKNOWN_CONNECTION_INFO;
58 | }
59 | try {
60 | return parser.parse(url);
61 | } catch (Exception e) {
62 | log.log(Level.WARNING, "error occurs when parsing jdbc url");
63 | }
64 | return ConnectionInfo.UNKNOWN_CONNECTION_INFO;
65 | }
66 |
67 | /**
68 | * @deprecated use {@link #parse(String)} instead
69 | */
70 | @Deprecated
71 | public static ConnectionInfo parser(String url) {
72 | return parse(url);
73 | }
74 |
75 | private static ConnectionURLParser findURLParser(String lowerCaseUrl) {
76 | for (Map.Entry entry : parserRegister.entrySet()) {
77 | if (lowerCaseUrl.startsWith(entry.getKey())) {
78 | return entry.getValue();
79 | }
80 | }
81 | return null;
82 | }
83 |
84 | /**
85 | * register new ConnectionURLParser. Can override existing parser.
86 | */
87 | public static void registerConnectionParser(String urlPrefix, ConnectionURLParser parser) {
88 | if (null == urlPrefix || parser == null) {
89 | throw new IllegalArgumentException("urlPrefix and parser can not be null");
90 | }
91 | parserRegister.put(urlPrefix.toLowerCase(), parser);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/java.sql.Driver:
--------------------------------------------------------------------------------
1 | io.opentracing.contrib.jdbc.TracingDriver
2 |
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/HibernateTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 |
17 | import static io.opentracing.contrib.jdbc.TestUtil.checkNoEmptyTags;
18 | import static io.opentracing.contrib.jdbc.TestUtil.checkSameTrace;
19 | import static org.junit.Assert.assertEquals;
20 | import static org.junit.Assert.assertFalse;
21 | import static org.junit.Assert.assertNotNull;
22 | import static org.junit.Assert.assertNull;
23 |
24 | import io.opentracing.Scope;
25 | import io.opentracing.mock.MockSpan;
26 | import io.opentracing.mock.MockTracer;
27 | import io.opentracing.tag.Tags;
28 | import io.opentracing.util.GlobalTracerTestUtil;
29 | import io.opentracing.util.ThreadLocalScopeManager;
30 | import java.util.ArrayList;
31 | import java.util.Collections;
32 | import java.util.List;
33 | import javax.persistence.Column;
34 | import javax.persistence.Entity;
35 | import javax.persistence.EntityManager;
36 | import javax.persistence.EntityManagerFactory;
37 | import javax.persistence.GeneratedValue;
38 | import javax.persistence.GenerationType;
39 | import javax.persistence.Id;
40 | import javax.persistence.Persistence;
41 | import javax.persistence.Table;
42 | import org.hibernate.Session;
43 | import org.hibernate.SessionFactory;
44 | import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
45 | import org.hibernate.cfg.Configuration;
46 | import org.junit.Before;
47 | import org.junit.BeforeClass;
48 | import org.junit.Test;
49 |
50 | public class HibernateTest {
51 |
52 | private static final MockTracer mockTracer = new MockTracer(new ThreadLocalScopeManager(),
53 | MockTracer.Propagator.TEXT_MAP);
54 |
55 | @BeforeClass
56 | public static void init() {
57 | GlobalTracerTestUtil.setGlobalTracerUnconditionally(mockTracer);
58 | }
59 |
60 | @Before
61 | public void before() {
62 | mockTracer.reset();
63 | }
64 |
65 | @Test
66 | public void jpa() {
67 | EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jpa");
68 |
69 | Employee employee = new Employee();
70 | EntityManager entityManager = entityManagerFactory.createEntityManager();
71 | entityManager.getTransaction().begin();
72 | entityManager.persist(employee);
73 | entityManager.getTransaction().commit();
74 | entityManager.close();
75 | entityManagerFactory.close();
76 |
77 | assertNotNull(employee.id);
78 |
79 | List finishedSpans = mockTracer.finishedSpans();
80 | assertEquals(14, finishedSpans.size());
81 |
82 | checkSpans(finishedSpans, "jpa");
83 | assertNull(mockTracer.activeSpan());
84 | }
85 |
86 | @Test
87 | public void jpa_with_active_span_only() {
88 | EntityManagerFactory entityManagerFactory = Persistence
89 | .createEntityManagerFactory("jpa_active_span_only");
90 |
91 | Employee employee = new Employee();
92 | EntityManager entityManager = entityManagerFactory.createEntityManager();
93 | entityManager.getTransaction().begin();
94 | entityManager.persist(employee);
95 | entityManager.getTransaction().commit();
96 | entityManager.close();
97 | entityManagerFactory.close();
98 |
99 | assertNotNull(employee.id);
100 |
101 | List finishedSpans = mockTracer.finishedSpans();
102 | assertEquals(0, finishedSpans.size());
103 |
104 | assertNull(mockTracer.activeSpan());
105 | }
106 |
107 | @Test
108 | public void jpa_with_parent() {
109 | final MockSpan parent = mockTracer.buildSpan("parent").start();
110 | try (Scope ignored = mockTracer.activateSpan(parent)) {
111 | EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jpa");
112 |
113 | EntityManager entityManager = entityManagerFactory.createEntityManager();
114 |
115 | entityManager.getTransaction().begin();
116 | entityManager.persist(new Employee());
117 | entityManager.persist(new Employee());
118 | entityManager.getTransaction().commit();
119 | entityManager.close();
120 | entityManagerFactory.close();
121 | }
122 | parent.finish();
123 |
124 | List spans = mockTracer.finishedSpans();
125 | assertEquals(17, spans.size());
126 | checkSameTrace(spans);
127 | assertNull(mockTracer.activeSpan());
128 | }
129 |
130 | @Test
131 | public void jpa_with_parent_and_active_span_only() {
132 | final MockSpan parent = mockTracer.buildSpan("parent").start();
133 | try (Scope ignored = mockTracer.activateSpan(parent)) {
134 | EntityManagerFactory entityManagerFactory = Persistence
135 | .createEntityManagerFactory("jpa_active_span_only");
136 |
137 | EntityManager entityManager = entityManagerFactory.createEntityManager();
138 |
139 | entityManager.getTransaction().begin();
140 | entityManager.persist(new Employee());
141 | entityManager.persist(new Employee());
142 | entityManager.getTransaction().commit();
143 | entityManager.close();
144 | entityManagerFactory.close();
145 | }
146 | parent.finish();
147 |
148 | List spans = mockTracer.finishedSpans();
149 | assertEquals(17, spans.size());
150 | checkSameTrace(spans);
151 | assertNull(mockTracer.activeSpan());
152 | }
153 |
154 | @Test
155 | public void hibernate() {
156 | SessionFactory sessionFactory = createSessionFactory(false);
157 | Session session = sessionFactory.openSession();
158 |
159 | Employee employee = new Employee();
160 | session.beginTransaction();
161 | session.save(employee);
162 | session.getTransaction().commit();
163 | session.close();
164 | sessionFactory.close();
165 |
166 | assertNotNull(employee.id);
167 |
168 | List finishedSpans = mockTracer.finishedSpans();
169 | assertEquals(14, finishedSpans.size());
170 |
171 | checkSpans(finishedSpans, "hibernate");
172 | assertNull(mockTracer.activeSpan());
173 | }
174 |
175 | @Test
176 | public void hibernate_with_active_span_only() {
177 | SessionFactory sessionFactory = createSessionFactory(true);
178 | Session session = sessionFactory.openSession();
179 |
180 | Employee employee = new Employee();
181 | session.beginTransaction();
182 | session.save(employee);
183 | session.getTransaction().commit();
184 | session.close();
185 | sessionFactory.close();
186 |
187 | assertNotNull(employee.id);
188 |
189 | List finishedSpans = mockTracer.finishedSpans();
190 | assertEquals(0, finishedSpans.size());
191 |
192 | assertNull(mockTracer.activeSpan());
193 | }
194 |
195 | @Test
196 | public void hibernate_with_parent() {
197 | final MockSpan parent = mockTracer.buildSpan("parent").start();
198 | try (Scope ignored = mockTracer.activateSpan(parent)) {
199 | SessionFactory sessionFactory = createSessionFactory(false);
200 | Session session = sessionFactory.openSession();
201 |
202 | session.beginTransaction();
203 | session.save(new Employee());
204 | session.save(new Employee());
205 | session.getTransaction().commit();
206 | session.close();
207 | sessionFactory.close();
208 | }
209 | parent.finish();
210 |
211 | List spans = mockTracer.finishedSpans();
212 | assertEquals(17, spans.size());
213 | checkSameTrace(spans);
214 | assertNull(mockTracer.activeSpan());
215 | }
216 |
217 | @Test
218 | public void hibernate_with_parent_and_active_span_only() {
219 | final MockSpan parent = mockTracer.buildSpan("parent").start();
220 | try (Scope ignored = mockTracer.activateSpan(parent)) {
221 | SessionFactory sessionFactory = createSessionFactory(true);
222 | Session session = sessionFactory.openSession();
223 |
224 | session.beginTransaction();
225 | session.save(new Employee());
226 | session.save(new Employee());
227 | session.getTransaction().commit();
228 | session.close();
229 | sessionFactory.close();
230 | }
231 | parent.finish();
232 |
233 | List spans = mockTracer.finishedSpans();
234 | assertEquals(17, spans.size());
235 | checkSameTrace(spans);
236 | assertNull(mockTracer.activeSpan());
237 | }
238 |
239 | @Test
240 | public void hibernate_with_ignored_statement() {
241 | SessionFactory sessionFactory = createSessionFactory(false,
242 | Collections.singletonList("insert into Employee (id) values (?)"));
243 | Session session = sessionFactory.openSession();
244 |
245 | Employee employee = new Employee();
246 | session.beginTransaction();
247 | session.save(employee);
248 | session.getTransaction().commit();
249 | session.close();
250 | sessionFactory.close();
251 |
252 | assertNotNull(employee.id);
253 |
254 | List finishedSpans = mockTracer.finishedSpans();
255 | assertEquals(13, finishedSpans.size());
256 |
257 | checkSpans(finishedSpans, "hibernate");
258 | assertNull(mockTracer.activeSpan());
259 | }
260 |
261 | private void checkSpans(List mockSpans, String dbInstance) {
262 | checkNoEmptyTags(mockSpans);
263 | for (MockSpan mockSpan : mockSpans) {
264 | assertEquals(Tags.SPAN_KIND_CLIENT, mockSpan.tags().get(Tags.SPAN_KIND.getKey()));
265 | assertEquals(JdbcTracingUtils.COMPONENT_NAME, mockSpan.tags().get(Tags.COMPONENT.getKey()));
266 | assertEquals("h2", mockSpan.tags().get(Tags.DB_TYPE.getKey()));
267 |
268 | assertEquals(dbInstance, mockSpan.tags().get(Tags.DB_INSTANCE.getKey()));
269 | assertEquals("localhost:-1", mockSpan.tags().get("peer.address"));
270 |
271 | final String sql = (String) mockSpan.tags().get(Tags.DB_STATEMENT.getKey());
272 | if (sql != null) {
273 | // empty sql should not be added to avoid NPE in tracers
274 | assertFalse(sql.trim().isEmpty());
275 | }
276 | assertEquals(0, mockSpan.generatedErrors().size());
277 | }
278 | }
279 |
280 | private SessionFactory createSessionFactory(boolean traceWithActiveSpanOnly) {
281 | return createSessionFactory(traceWithActiveSpanOnly, new ArrayList());
282 | }
283 |
284 | private SessionFactory createSessionFactory(boolean traceWithActiveSpanOnly,
285 | List ignored) {
286 | String ignoredForTrace = TestUtil.buildIgnoredString(ignored);
287 | Configuration configuration = new Configuration();
288 | configuration.addAnnotatedClass(Employee.class);
289 | configuration.setProperty("hibernate.connection.driver_class",
290 | "io.opentracing.contrib.jdbc.TracingDriver");
291 | configuration.setProperty("hibernate.connection.url",
292 | "jdbc:tracing:h2:mem:hibernate?" + ignoredForTrace + "traceWithActiveSpanOnly="
293 | + traceWithActiveSpanOnly);
294 | configuration.setProperty("hibernate.connection.username", "sa");
295 | configuration.setProperty("hibernate.connection.password", "");
296 | configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
297 | configuration.setProperty("hibernate.hbm2ddl.auto", "create-drop");
298 | configuration.setProperty("hibernate.show_sql", "true");
299 | configuration.setProperty("hibernate.connection.pool_size", "10");
300 |
301 | StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
302 | .applySettings(configuration.getProperties());
303 | return configuration.buildSessionFactory(builder.build());
304 | }
305 |
306 |
307 | @Entity
308 | @Table(name = "Employee")
309 | private static class Employee {
310 |
311 | @Id
312 | @Column(name = "id")
313 | @GeneratedValue(strategy = GenerationType.AUTO)
314 | private Long id;
315 | }
316 | }
317 |
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/JdbcTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | import static io.opentracing.contrib.jdbc.TestUtil.checkNoEmptyTags;
17 | import static org.junit.Assert.assertEquals;
18 | import static org.junit.Assert.assertTrue;
19 |
20 | import io.opentracing.mock.MockSpan;
21 | import io.opentracing.mock.MockTracer;
22 | import io.opentracing.tag.Tags;
23 | import io.opentracing.util.GlobalTracerTestUtil;
24 | import java.sql.Connection;
25 | import java.sql.Driver;
26 | import java.sql.DriverManager;
27 | import java.sql.SQLException;
28 | import java.sql.Statement;
29 | import java.util.Enumeration;
30 | import java.util.List;
31 | import org.junit.Before;
32 | import org.junit.BeforeClass;
33 | import org.junit.Test;
34 |
35 | public class JdbcTest {
36 | private static void assertGetDriver(final Connection connection) throws SQLException {
37 | final String originalURL = connection.getMetaData().getURL();
38 | final Driver driver = getUnderlyingDriver(originalURL);
39 | assertEquals("org.h2.Driver", driver.getClass().getName());
40 | }
41 |
42 | private static Driver getUnderlyingDriver(final String url) throws SQLException {
43 | final Enumeration enumeration = DriverManager.getDrivers();
44 | while (enumeration.hasMoreElements()) {
45 | final Driver driver = enumeration.nextElement();
46 | if (driver.acceptsURL(url) && !(driver instanceof TracingDriver)) {
47 | return driver;
48 | }
49 | }
50 | return null;
51 | }
52 |
53 | private static final MockTracer mockTracer = new MockTracer();
54 |
55 | @BeforeClass
56 | public static void init() {
57 | GlobalTracerTestUtil.setGlobalTracerUnconditionally(mockTracer);
58 | }
59 |
60 | @Before
61 | public void before() {
62 | mockTracer.reset();
63 | }
64 |
65 | @Test
66 | public void testPassTracingUrl() throws Exception {
67 | TracingDriver.setInterceptorMode(false);
68 | try (Connection connection = DriverManager.getConnection("jdbc:tracing:h2:mem:jdbc")) {
69 | Statement statement = connection.createStatement();
70 | statement.executeUpdate("CREATE TABLE employer (id INTEGER)");
71 | assertGetDriver(connection);
72 | }
73 |
74 | List spans = mockTracer.finishedSpans();
75 | assertEquals(3, spans.size());
76 | checkNoEmptyTags(spans);
77 | }
78 |
79 | @Test
80 | public void testFailTracingUrl() throws Exception {
81 | try (Connection connection = DriverManager.getConnection("jdbc:tracing:h2:mem:jdbc")) {
82 | Statement statement = connection.createStatement();
83 | try {
84 | statement.executeUpdate("CREATE TABLE employer (id INTEGER2)");
85 | } catch (Exception ignore) {
86 | }
87 | assertGetDriver(connection);
88 | }
89 |
90 | List spans = mockTracer.finishedSpans();
91 | assertEquals(3, spans.size());
92 | MockSpan span = spans.get(1);
93 | assertTrue(span.tags().containsKey(Tags.ERROR.getKey()));
94 | checkNoEmptyTags(spans);
95 | }
96 |
97 | @Test
98 | public void testPassOriginalUrl() throws Exception {
99 | TracingDriver.ensureRegisteredAsTheFirstDriver();
100 | TracingDriver.setInterceptorMode(true);
101 | try (Connection connection = DriverManager.getConnection("jdbc:h2:mem:jdbc")) {
102 | Statement statement = connection.createStatement();
103 | statement.executeUpdate("CREATE TABLE employer (id INTEGER)");
104 | assertGetDriver(connection);
105 | }
106 |
107 | List spans = mockTracer.finishedSpans();
108 | assertEquals(3, spans.size());
109 | checkNoEmptyTags(spans);
110 | }
111 |
112 | @Test
113 | public void testFailOriginalUrl() throws Exception {
114 | TracingDriver.ensureRegisteredAsTheFirstDriver();
115 | TracingDriver.setInterceptorMode(true);
116 | try (Connection connection = DriverManager.getConnection("jdbc:h2:mem:jdbc")) {
117 | Statement statement = connection.createStatement();
118 | try {
119 | statement.executeUpdate("CREATE TABLE employer (id INTEGER2)");
120 | } catch (Exception ignore) {
121 | }
122 | assertGetDriver(connection);
123 | }
124 |
125 | List spans = mockTracer.finishedSpans();
126 | assertEquals(3, spans.size());
127 | MockSpan span = spans.get(1);
128 | assertTrue(span.tags().containsKey(Tags.ERROR.getKey()));
129 | checkNoEmptyTags(spans);
130 | }
131 |
132 | @Test
133 | public void testFailInterceptor() throws Exception {
134 | TracingDriver.setInterceptorMode(false);
135 | try (Connection connection = DriverManager.getConnection("jdbc:h2:mem:jdbc")) {
136 | Statement statement = connection.createStatement();
137 | try {
138 | statement.executeUpdate("CREATE TABLE employer (id INTEGER2)");
139 | } catch (Exception ignore) {
140 | }
141 | assertGetDriver(connection);
142 | }
143 |
144 | List spans = mockTracer.finishedSpans();
145 | assertEquals(0, spans.size());
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/JdbcTracingUtilsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | import static io.opentracing.contrib.jdbc.TestUtil.checkNoEmptyTags;
17 | import static org.junit.Assert.assertEquals;
18 | import static org.junit.Assert.assertTrue;
19 |
20 | import io.opentracing.mock.MockSpan;
21 | import io.opentracing.mock.MockTracer;
22 | import io.opentracing.util.GlobalTracerTestUtil;
23 | import java.sql.Connection;
24 | import java.sql.DriverManager;
25 | import java.sql.Statement;
26 | import java.util.Collections;
27 | import java.util.List;
28 | import org.junit.AfterClass;
29 | import org.junit.Before;
30 | import org.junit.BeforeClass;
31 | import org.junit.Test;
32 |
33 | public class JdbcTracingUtilsTest {
34 |
35 | private static final MockTracer mockTracer = new MockTracer();
36 |
37 | @BeforeClass
38 | public static void init() {
39 | GlobalTracerTestUtil.setGlobalTracerUnconditionally(mockTracer);
40 | }
41 |
42 | @Before
43 | public void before() {
44 | mockTracer.reset();
45 | JdbcTracing.setSlowQueryThresholdMs(0);
46 | }
47 |
48 | @AfterClass
49 | public static void afterClass() {
50 | TracingDriver.setTraceEnabled(true);
51 | JdbcTracing.setSlowQueryThresholdMs(0);
52 | }
53 |
54 | @Test
55 | public void buildSpanWithTracedEnabled() throws Exception {
56 | TracingDriver.setInterceptorMode(false);
57 | TracingDriver.setTraceEnabled(true);
58 | try (Connection connection = DriverManager.getConnection("jdbc:tracing:h2:mem:jdbc")) {
59 | Statement statement = connection.createStatement();
60 | statement.executeUpdate("CREATE TABLE employer (id INTEGER)");
61 | }
62 |
63 | List spans = mockTracer.finishedSpans();
64 | assertEquals(3, spans.size());
65 | checkNoEmptyTags(spans);
66 | }
67 |
68 | @Test
69 | public void buildSpanWithoutTraceEnabled() throws Exception {
70 | TracingDriver.setInterceptorMode(false);
71 | TracingDriver.setTraceEnabled(false);
72 | try (Connection connection = DriverManager.getConnection("jdbc:tracing:h2:mem:jdbc")) {
73 | Statement statement = connection.createStatement();
74 | statement.executeUpdate("CREATE TABLE employer (id INTEGER)");
75 | }
76 |
77 | assertTrue(mockTracer.finishedSpans().isEmpty());
78 | }
79 |
80 | @Test
81 | public void setSlowTagCorrectly() throws Exception {
82 | final int slowQueryThresholdMs = 100;
83 | JdbcTracing.setSlowQueryThresholdMs(slowQueryThresholdMs);
84 |
85 | JdbcTracingUtils.execute(
86 | "SlowQuery",
87 | () -> Thread.sleep(slowQueryThresholdMs * 2),
88 | null,
89 | ConnectionInfo.UNKNOWN_CONNECTION_INFO,
90 | false,
91 | Collections.emptySet(),
92 | mockTracer);
93 |
94 | final List finishedSpans = mockTracer.finishedSpans();
95 | assertEquals("Should have traced a query execution", 1, finishedSpans.size());
96 | final MockSpan slowQuerySpan = finishedSpans.get(0);
97 | assertTrue("Span should be tagged slow",
98 | slowQuerySpan.tags().containsKey(JdbcTracingUtils.SLOW.getKey()));
99 | }
100 |
101 | @Test
102 | public void setExcludeFastTagCorrectly() throws Exception {
103 | final int excludeFastQueryThresholdMs = 100;
104 | JdbcTracing.setExcludeFastQueryThresholdMs(excludeFastQueryThresholdMs);
105 |
106 | JdbcTracingUtils.execute(
107 | "FastQuery",
108 | () -> Thread.sleep(excludeFastQueryThresholdMs / 2),
109 | null,
110 | ConnectionInfo.UNKNOWN_CONNECTION_INFO,
111 | false,
112 | Collections.emptySet(),
113 | mockTracer);
114 |
115 | final List finishedSpans = mockTracer.finishedSpans();
116 | assertEquals("Should have traced a query execution", 1, finishedSpans.size());
117 | final MockSpan fastQuerySpan = finishedSpans.get(0);
118 | assertTrue("Span should be tagged with sampling.priority=0",
119 | fastQuerySpan.tags().containsKey(JdbcTracingUtils.SAMPLING_PRIORITY.getKey()));
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/SpringTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 |
17 | import static io.opentracing.contrib.jdbc.TestUtil.checkNoEmptyTags;
18 | import static io.opentracing.contrib.jdbc.TestUtil.checkSameTrace;
19 | import static org.assertj.core.api.Assertions.assertThat;
20 | import static org.junit.Assert.assertEquals;
21 | import static org.junit.Assert.assertNull;
22 |
23 | import io.opentracing.Scope;
24 | import io.opentracing.mock.MockSpan;
25 | import io.opentracing.mock.MockTracer;
26 | import io.opentracing.tag.Tags;
27 | import io.opentracing.util.GlobalTracerTestUtil;
28 | import java.sql.PreparedStatement;
29 | import java.sql.SQLException;
30 | import java.util.ArrayList;
31 | import java.util.Arrays;
32 | import java.util.List;
33 | import org.apache.commons.dbcp2.BasicDataSource;
34 | import org.junit.Before;
35 | import org.junit.BeforeClass;
36 | import org.junit.Test;
37 | import org.springframework.jdbc.core.BatchPreparedStatementSetter;
38 | import org.springframework.jdbc.core.JdbcTemplate;
39 |
40 | public class SpringTest {
41 |
42 | private static final MockTracer mockTracer = new MockTracer();
43 |
44 | private final int DB_CONNECTION_SPAN_COUNT = 2;
45 |
46 | @BeforeClass
47 | public static void init() {
48 | GlobalTracerTestUtil.setGlobalTracerUnconditionally(mockTracer);
49 | }
50 |
51 | @Before
52 | public void before() {
53 | mockTracer.reset();
54 | }
55 |
56 | @Test
57 | public void batch() throws SQLException {
58 | BasicDataSource dataSource = getDataSource(false);
59 |
60 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
61 | jdbcTemplate.execute("CREATE TABLE batch (id INTEGER)");
62 |
63 | final List ids = Arrays.asList(1, 2, 3, 4, 5);
64 | jdbcTemplate.batchUpdate("INSERT INTO batch (id) VALUES (?)",
65 | new BatchPreparedStatementSetter() {
66 | @Override
67 | public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
68 | preparedStatement.setInt(1, ids.get(i));
69 | }
70 |
71 | @Override
72 | public int getBatchSize() {
73 | return ids.size();
74 | }
75 | }
76 | );
77 |
78 | dataSource.close();
79 |
80 | List spans = mockTracer.finishedSpans();
81 | assertEquals(DB_CONNECTION_SPAN_COUNT + 4, spans.size());
82 |
83 | for (MockSpan span : spans.subList(DB_CONNECTION_SPAN_COUNT + 2, spans.size() - 1)) {
84 | assertEquals(Tags.SPAN_KIND_CLIENT, span.tags().get(Tags.SPAN_KIND.getKey()));
85 | assertEquals(JdbcTracingUtils.COMPONENT_NAME, span.tags().get(Tags.COMPONENT.getKey()));
86 | assertThat(span.tags().get(Tags.DB_STATEMENT.getKey()).toString()).isNotEmpty();
87 | assertEquals("h2", span.tags().get(Tags.DB_TYPE.getKey()));
88 | assertEquals("spring", span.tags().get(Tags.DB_INSTANCE.getKey()));
89 | assertEquals("localhost:-1", span.tags().get("peer.address"));
90 | assertEquals(0, span.generatedErrors().size());
91 | }
92 |
93 | assertNull(mockTracer.activeSpan());
94 | checkNoEmptyTags(spans);
95 | }
96 |
97 | @Test
98 | public void spring() throws SQLException {
99 | BasicDataSource dataSource = getDataSource(false);
100 |
101 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
102 | jdbcTemplate.execute("CREATE TABLE employee (id INTEGER)");
103 |
104 | dataSource.close();
105 |
106 | List finishedSpans = mockTracer.finishedSpans();
107 | assertEquals(DB_CONNECTION_SPAN_COUNT + 3, finishedSpans.size());
108 | MockSpan mockSpan = finishedSpans.get(DB_CONNECTION_SPAN_COUNT + 1);
109 |
110 | assertEquals(Tags.SPAN_KIND_CLIENT, mockSpan.tags().get(Tags.SPAN_KIND.getKey()));
111 | assertEquals(JdbcTracingUtils.COMPONENT_NAME, mockSpan.tags().get(Tags.COMPONENT.getKey()));
112 | assertThat(mockSpan.tags().get(Tags.DB_STATEMENT.getKey()).toString()).isNotEmpty();
113 | assertEquals("h2", mockSpan.tags().get(Tags.DB_TYPE.getKey()));
114 | assertEquals("spring", mockSpan.tags().get(Tags.DB_INSTANCE.getKey()));
115 | assertEquals("localhost:-1", mockSpan.tags().get("peer.address"));
116 |
117 | assertEquals(0, mockSpan.generatedErrors().size());
118 |
119 | assertNull(mockTracer.activeSpan());
120 | checkNoEmptyTags(finishedSpans);
121 | }
122 |
123 | @Test
124 | public void spring_active_span_only() throws Exception {
125 | BasicDataSource dataSource = getDataSource(true);
126 |
127 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
128 | jdbcTemplate.execute("CREATE TABLE skip_new_spans (id INTEGER)");
129 |
130 | dataSource.close();
131 |
132 | List finishedSpans = mockTracer.finishedSpans();
133 | assertEquals(0, finishedSpans.size());
134 | checkNoEmptyTags(finishedSpans);
135 | }
136 |
137 | @Test
138 | public void spring_with_parent() throws Exception {
139 | final MockSpan parent = mockTracer.buildSpan("parent").start();
140 | try (Scope ignored = mockTracer.activateSpan(parent)) {
141 | BasicDataSource dataSource = getDataSource(false);
142 |
143 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
144 | jdbcTemplate.execute("CREATE TABLE with_parent_1 (id INTEGER)");
145 | jdbcTemplate.execute("CREATE TABLE with_parent_2 (id INTEGER)");
146 |
147 | dataSource.close();
148 | }
149 | parent.finish();
150 |
151 | List spans = mockTracer.finishedSpans();
152 | assertEquals(DB_CONNECTION_SPAN_COUNT + 5, spans.size());
153 |
154 | checkSameTrace(spans);
155 | checkNoEmptyTags(spans);
156 | }
157 |
158 | @Test
159 | public void spring_with_parent_and_active_span_only() throws Exception {
160 | final MockSpan parent = mockTracer.buildSpan("parent").start();
161 | try (Scope ignored = mockTracer.activateSpan(parent)) {
162 | BasicDataSource dataSource = getDataSource(true);
163 |
164 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
165 | jdbcTemplate.execute("CREATE TABLE with_parent_skip_1 (id INTEGER)");
166 | jdbcTemplate.execute("CREATE TABLE with_parent_skip_2 (id INTEGER)");
167 |
168 | dataSource.close();
169 | }
170 | parent.finish();
171 |
172 | List spans = mockTracer.finishedSpans();
173 | assertEquals(DB_CONNECTION_SPAN_COUNT + 5, spans.size());
174 |
175 | checkSameTrace(spans);
176 | checkNoEmptyTags(spans);
177 | }
178 |
179 | @Test
180 | public void spring_with_ignored_statement() throws Exception {
181 | BasicDataSource dataSource = getDataSource(false, Arrays.asList(
182 | "CREATE TABLE ignored (id INTEGER, TEST VARCHAR)",
183 | "INSERT INTO ignored (id, \\\"TEST\\\") VALUES (1, 'value')"
184 | ));
185 |
186 | JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
187 | jdbcTemplate.execute("CREATE TABLE ignored (id INTEGER, TEST VARCHAR)");
188 | jdbcTemplate.execute("INSERT INTO ignored (id, \"TEST\") VALUES (1, 'value')");
189 | jdbcTemplate.execute("CREATE TABLE not_ignored (id INTEGER)");
190 |
191 | dataSource.close();
192 |
193 | List finishedSpans = mockTracer.finishedSpans();
194 | assertEquals(DB_CONNECTION_SPAN_COUNT + 3, finishedSpans.size());
195 | checkNoEmptyTags(finishedSpans);
196 | }
197 |
198 | private static BasicDataSource getDataSource(boolean traceWithActiveSpanOnly) {
199 | return getDataSource(traceWithActiveSpanOnly, new ArrayList());
200 | }
201 |
202 | private static BasicDataSource getDataSource(boolean traceWithActiveSpanOnly,
203 | List ignored) {
204 |
205 | String ignoreForTracing = TestUtil.buildIgnoredString(ignored);
206 |
207 | BasicDataSource dataSource = new BasicDataSource();
208 | dataSource
209 | .setUrl("jdbc:tracing:h2:mem:spring?" + ignoreForTracing +
210 | "traceWithActiveSpanOnly=" + traceWithActiveSpanOnly);
211 | dataSource.setUsername("sa");
212 | dataSource.setPassword("");
213 | return dataSource;
214 | }
215 |
216 | }
217 |
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/TestUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | import static org.junit.Assert.assertEquals;
17 | import static org.junit.Assert.assertFalse;
18 | import static org.junit.Assert.assertNotNull;
19 |
20 | import io.opentracing.mock.MockSpan;
21 | import java.util.Collection;
22 | import java.util.List;
23 | import java.util.Map.Entry;
24 |
25 | class TestUtil {
26 |
27 | static void checkSameTrace(List spans) {
28 | for (int i = 0; i < spans.size() - 1; i++) {
29 | assertEquals(spans.get(i).context().traceId(), spans.get(i + 1).context().traceId());
30 | assertEquals(spans.get(spans.size() - 1).context().spanId(), spans.get(i).parentId());
31 | }
32 | }
33 |
34 | static void checkNoEmptyTags(List spans) {
35 | for (MockSpan span : spans) {
36 | for (Entry entry : span.tags().entrySet()) {
37 | assertNotNull(entry.getValue());
38 | if (entry.getValue() instanceof String) {
39 | String tagValue = (String) entry.getValue();
40 | assertFalse(tagValue.trim().isEmpty());
41 | }
42 | }
43 | }
44 | }
45 |
46 | static String buildIgnoredString(Collection ignored) {
47 | StringBuilder ignoreForTracing = new StringBuilder();
48 | for (String query : ignored) {
49 | ignoreForTracing.append("ignoreForTracing=\"");
50 | ignoreForTracing.append(query.replaceAll("\"", "\\\""));
51 | ignoreForTracing.append("\";");
52 | }
53 | return ignoreForTracing.toString();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/TracingDataSourceTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 | import static org.junit.Assert.assertEquals;
17 | import static org.junit.Assert.assertFalse;
18 | import static org.junit.Assert.assertNull;
19 | import static org.junit.Assert.assertTrue;
20 |
21 | import io.opentracing.mock.MockSpan;
22 | import io.opentracing.mock.MockTracer;
23 | import io.opentracing.tag.Tags;
24 | import java.sql.Connection;
25 | import java.sql.SQLException;
26 | import org.apache.commons.dbcp2.BasicDataSource;
27 | import org.junit.Test;
28 |
29 | public class TracingDataSourceTest {
30 | @Test
31 | public void traces_acquiring_connection() throws Exception {
32 | final BasicDataSource dataSource = getDataSource();
33 | final MockTracer mockTracer = new MockTracer();
34 | try (final TracingDataSource tracingDataSource = new TracingDataSource(mockTracer,
35 | dataSource)) {
36 | try (final Connection connection = tracingDataSource.getConnection()) {
37 | assertFalse(mockTracer.finishedSpans().isEmpty());
38 | }
39 | }
40 | }
41 |
42 | @Test
43 | public void sets_error() throws Exception {
44 | final BasicDataSource dataSource = getErroneousDataSource();
45 | final MockTracer mockTracer = new MockTracer();
46 | try (final TracingDataSource tracingDataSource = new TracingDataSource(mockTracer,
47 | dataSource)) {
48 | try (final Connection connection = tracingDataSource.getConnection()) {
49 | assertNull("Get connection", connection);
50 | } catch (SQLException ignored) {
51 | }
52 | }
53 |
54 | assertFalse(mockTracer.finishedSpans().isEmpty());
55 | MockSpan finishedSpan = mockTracer.finishedSpans().get(0);
56 | assertTrue("Span contains error tag", finishedSpan.tags().containsKey(Tags.ERROR.getKey()));
57 | }
58 |
59 | @Test(expected = SQLException.class)
60 | public void rethrows_any_error() throws Exception {
61 | final BasicDataSource dataSource = getErroneousDataSource();
62 | final MockTracer mockTracer = new MockTracer();
63 | try (final TracingDataSource tracingDataSource = new TracingDataSource(mockTracer,
64 | dataSource)) {
65 | tracingDataSource.getConnection();
66 | }
67 | }
68 |
69 | @Test
70 | public void detect_connection_info() throws Exception {
71 | final BasicDataSource dataSource = getDataSource();
72 | final MockTracer mockTracer = new MockTracer();
73 | try (final TracingDataSource tracingDataSource = new TracingDataSource(mockTracer,
74 | dataSource)) {
75 | tracingDataSource.getConnection();
76 | }
77 | assertFalse(mockTracer.finishedSpans().isEmpty());
78 | MockSpan finishedSpan = mockTracer.finishedSpans().get(0);
79 | assertEquals("Span contains tag db.type=h2", "h2",
80 | finishedSpan.tags().get(Tags.DB_TYPE.getKey()));
81 | }
82 |
83 | private static BasicDataSource getDataSource() {
84 | BasicDataSource dataSource = new BasicDataSource();
85 | dataSource.setUrl("jdbc:h2:mem:dataSourceTest");
86 | return dataSource;
87 | }
88 |
89 | private static BasicDataSource getErroneousDataSource() {
90 | BasicDataSource dataSource = new BasicDataSource();
91 | dataSource.setUrl("jdbc:invalid");
92 | return dataSource;
93 | }
94 | }
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/TracingDriverTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc;
15 |
16 |
17 | import static org.junit.Assert.assertEquals;
18 | import static org.junit.Assert.assertNotNull;
19 |
20 | import io.opentracing.Tracer;
21 | import io.opentracing.mock.MockTracer;
22 | import io.opentracing.util.GlobalTracer;
23 | import io.opentracing.util.GlobalTracerTestUtil;
24 | import org.junit.Before;
25 | import org.junit.Test;
26 |
27 | public class TracingDriverTest {
28 |
29 | @Before
30 | public void before() {
31 | GlobalTracerTestUtil.resetGlobalTracer();
32 | }
33 |
34 | @Test
35 | public void testGlobalTracer() {
36 | TracingDriver tracingDriver = new TracingDriver();
37 | assertNotNull(tracingDriver.getTracer());
38 | }
39 |
40 | @Test
41 | public void testExplicitTracer() {
42 | Tracer tracer = new MockTracer();
43 | GlobalTracer.registerIfAbsent(tracer);
44 | Tracer tracer2 = new MockTracer();
45 | TracingDriver tracingDriver = new TracingDriver();
46 | tracingDriver.setTracer(tracer2);
47 | assertEquals(tracer2, tracingDriver.getTracer());
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/parser/AS400URLParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import static org.hamcrest.CoreMatchers.equalTo;
17 | import static org.hamcrest.CoreMatchers.is;
18 | import static org.hamcrest.CoreMatchers.not;
19 | import static org.hamcrest.MatcherAssert.assertThat;
20 |
21 | import io.opentracing.contrib.jdbc.ConnectionInfo;
22 | import org.junit.Test;
23 |
24 | /**
25 | * Test for {@link AS400URLParser}
26 | *
27 | * @author Capgemini
28 | */
29 | public class AS400URLParserTest {
30 |
31 | @Test
32 | public void testMatchShort() {
33 | String url = "jdbc:as400://myhost";
34 | ConnectionInfo connectionInfo = URLParser.parse(url);
35 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
36 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost")));
37 | assertThat(connectionInfo.getDbInstance(),
38 | is(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO.getDbInstance())));
39 | assertThat(connectionInfo.getDbType(), is(equalTo("as400")));
40 | }
41 |
42 | @Test
43 | public void testMatchShortWithSlash() {
44 | String url = "jdbc:as400://myhost/";
45 | ConnectionInfo connectionInfo = URLParser.parse(url);
46 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
47 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost")));
48 | assertThat(connectionInfo.getDbInstance(),
49 | is(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO.getDbInstance())));
50 | assertThat(connectionInfo.getDbType(), is(equalTo("as400")));
51 | }
52 |
53 | @Test
54 | public void testMatchShortWithSlashAnsOptions() {
55 | String url = "jdbc:as400://myhost/;naming=sql;errors=full";
56 | ConnectionInfo connectionInfo = URLParser.parse(url);
57 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
58 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost")));
59 | assertThat(connectionInfo.getDbInstance(),
60 | is(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO.getDbInstance())));
61 | assertThat(connectionInfo.getDbType(), is(equalTo("as400")));
62 | }
63 |
64 |
65 | @Test
66 | public void testWithOptions() {
67 | String url = "jdbc:as400://myhost.mydomain.com;naming=sql;errors=full";
68 | ConnectionInfo connectionInfo = URLParser.parse(url);
69 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
70 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost.mydomain.com")));
71 | assertThat(connectionInfo.getDbInstance(),
72 | is(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO.getDbInstance())));
73 | assertThat(connectionInfo.getDbType(), is(equalTo("as400")));
74 | }
75 |
76 | @Test
77 | public void testFull() {
78 | String url = "jdbc:as400://myhost.mydomain.com/myinstance;naming=sql;errors=full";
79 | ConnectionInfo connectionInfo = URLParser.parse(url);
80 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
81 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost.mydomain.com")));
82 | assertThat(connectionInfo.getDbInstance(), is(equalTo("myinstance")));
83 | assertThat(connectionInfo.getDbType(), is(equalTo("as400")));
84 | }
85 |
86 | @Test
87 | public void testFullWithSlash() {
88 | String url = "jdbc:as400://myhost.mydomain.com/myinstance/;naming=sql;errors=full";
89 | ConnectionInfo connectionInfo = URLParser.parse(url);
90 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
91 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost.mydomain.com")));
92 | assertThat(connectionInfo.getDbInstance(), is(equalTo("myinstance")));
93 | assertThat(connectionInfo.getDbType(), is(equalTo("as400")));
94 | }
95 |
96 |
97 | @Test
98 | public void testNotMatch() {
99 | String url = "jdbc:as400:notmatching";
100 | ConnectionInfo connectionInfo = URLParser.parse(url);
101 | assertThat(connectionInfo, is(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO)));
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/parser/DB2URLParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import static org.hamcrest.CoreMatchers.equalTo;
17 | import static org.hamcrest.CoreMatchers.is;
18 | import static org.hamcrest.CoreMatchers.not;
19 | import static org.hamcrest.MatcherAssert.assertThat;
20 |
21 | import io.opentracing.contrib.jdbc.ConnectionInfo;
22 | import org.junit.Test;
23 |
24 | /**
25 | * Test for {@link DB2URLParser}
26 | *
27 | * @author oburgosm
28 | * @since 0.2.12
29 | */
30 | public class DB2URLParserTest {
31 |
32 | @Test
33 | public void testMatchFull() {
34 | String url = "jdbc:db2://myhost.mydomain.com:50000/MYINSTANCE:retrieveMessagesFromServerOnGetMessage=true;useIdentityValLocalForAutoGeneratedKeys=true;";
35 | ConnectionInfo connectionInfo = URLParser.parse(url);
36 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
37 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost.mydomain.com:50000")));
38 | assertThat(connectionInfo.getDbInstance(), is(equalTo("MYINSTANCE")));
39 | assertThat(connectionInfo.getDbType(), is(equalTo("db2")));
40 | }
41 |
42 | @Test
43 | public void testMatchWithoutOptions() {
44 | String url = "jdbc:db2://myhost.mydomain.com:50000/MYINSTANCE";
45 | ConnectionInfo connectionInfo = URLParser.parse(url);
46 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
47 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost.mydomain.com:50000")));
48 | assertThat(connectionInfo.getDbInstance(), is(equalTo("MYINSTANCE")));
49 | assertThat(connectionInfo.getDbType(), is(equalTo("db2")));
50 | }
51 |
52 | @Test
53 | public void testMatchWithoutPort() {
54 | String url = "jdbc:db2://myhost.mydomain.com/MYINSTANCE";
55 | ConnectionInfo connectionInfo = URLParser.parse(url);
56 | assertThat(connectionInfo, is(not(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO))));
57 | assertThat(connectionInfo.getDbPeer(), is(equalTo("myhost.mydomain.com")));
58 | assertThat(connectionInfo.getDbInstance(), is(equalTo("MYINSTANCE")));
59 | assertThat(connectionInfo.getDbType(), is(equalTo("db2")));
60 | }
61 |
62 | @Test
63 | public void testNotMatch() {
64 | String url = "jdbc:db2:notmatching";
65 | ConnectionInfo connectionInfo = URLParser.parse(url);
66 | assertThat(connectionInfo, is(equalTo(ConnectionInfo.UNKNOWN_CONNECTION_INFO)));
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/parser/OracleURLParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import java.util.stream.Stream;
17 |
18 | import io.opentracing.contrib.jdbc.ConnectionInfo;
19 | import org.junit.jupiter.params.ParameterizedTest;
20 | import org.junit.jupiter.params.provider.Arguments;
21 | import org.junit.jupiter.params.provider.MethodSource;
22 |
23 | import static org.assertj.core.api.Assertions.assertThat;
24 |
25 | class OracleURLParserTest {
26 | private static final String ORACLE = "oracle";
27 | private final OracleURLParser testee = new OracleURLParser();
28 |
29 | private static Stream easyConnectUrls() {
30 | return Stream.of( //
31 | Arguments
32 | .of("jdbc:oracle:thin:@192.168.105.100", "192.168.105.100:1521", "192.168.105.100"), //
33 | Arguments.of("jdbc:oracle:thin:@192.168.105.100:1234", "192.168.105.100:1234",
34 | "192.168.105.100"), //
35 | Arguments.of("jdbc:oracle:thin:@localhost/XEPDB1", "localhost:1521", "XEPDB1"), //
36 | Arguments.of("jdbc:oracle:thin:@localhost:1234/XEPDB1", "localhost:1234", "XEPDB1"), //
37 | Arguments.of("jdbc:oracle:thin:@//localhost:1234/XEPDB1", "localhost:1234", "XEPDB1"), //
38 | Arguments.of("jdbc:oracle:thin:@//localhost:1234/XEPDB1:server/instance", "localhost:1234",
39 | "XEPDB1"), //
40 | Arguments.of("jdbc:oracle:oci:@//localhost:1234/XEPDB1:server/instance", "localhost:1234",
41 | "XEPDB1"), //
42 | Arguments
43 | .of("jdbc:oracle:thin:@ldap://localhost:1234/XEPDB1,cn=OracleContext,dc=myco,dc=com",
44 | "localhost:1234", "XEPDB1,cn=OracleContext,dc=myco,dc=com") //
45 | );
46 | }
47 |
48 | private static Stream tnsNameUrls() {
49 | return Stream.of( //
50 | Arguments
51 | .of("jdbc:Oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= localhost )(PORT= 1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)))",
52 | "localhost:1521", "orcl"), //
53 | Arguments
54 | .of("jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= localhost )(PORT= 1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)))",
55 | "localhost:1521", "orcl"), //
56 | Arguments
57 | .of("jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL= TCP)(HOST=hostA)(PORT= 1523 ))(ADDRESS=(PROTOCOL=TCP)(HOST=hostB)(PORT= 1521 )))(SOURCE_ROUTE=yes)(CONNECT_DATA=(SERVICE_NAME=orcl)))",
58 | "hostA:1523,hostB:1521", "orcl"), //
59 | Arguments
60 | .of("jdbc:oracle:oci:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL= TCP)(HOST=hostA)(PORT= 1523 ))(ADDRESS=(PROTOCOL=TCP)(HOST=hostB)(PORT= 1521 )))(SOURCE_ROUTE=yes)(CONNECT_DATA=(SERVICE_NAME=orcl)))",
61 | "hostA:1523,hostB:1521", "orcl") //
62 | );
63 | }
64 |
65 | private static Stream otherUrls() {
66 | return Stream.of( //
67 | Arguments.of("jdbc:Oracle:thin:@localhost:orcl", "localhost:1521", "orcl"), //
68 | Arguments.of("jdbc:oracle:thin:@localhost:orcl", "localhost:1521", "orcl"), //
69 | Arguments.of("jdbc:oracle:thin:@localhost:1522:orcl", "localhost:1522", "orcl"), //
70 | Arguments.of("jdbc:oracle:thin:@//localhost:1521/orcl", "localhost:1521", "orcl"), //
71 | Arguments.of("jdbc:oracle:thin:scott/tiger@myhost:1521:orcl", "myhost:1521", "orcl"), //
72 | Arguments.of("jdbc:oracle:thin:@orcl", "orcl:1521", "orcl"), //
73 | Arguments.of("jdbc:oracle:oci:@orcl", "orcl:1521", "orcl"), //
74 | Arguments.of("jdbc:Oracle:oci:@orcl", "orcl:1521", "orcl"), //
75 | Arguments.of("jdbc:oracle:thin:@ldap://localhost/orcl,cn=OracleContext,dc=myco,dc=com",
76 | "localhost:1521", "orcl,cn=OracleContext,dc=myco,dc=com"), //
77 | Arguments.of("jdbc:Oracle:thin:@ldap://localhost/orcl,cn=OracleContext,dc=myco,dc=com",
78 | "localhost:1521", "orcl,cn=OracleContext,dc=myco,dc=com") //
79 | );
80 | }
81 |
82 | @ParameterizedTest(name = "[{0}]")
83 | @MethodSource("easyConnectUrls")
84 | void parseEasyConnect(final String url, final String dbPeer, final String dbInstance) {
85 | final ConnectionInfo result = testee.parse(url);
86 | assertThat(result.getDbType()).isEqualTo(ORACLE);
87 | assertThat(result.getDbPeer()).isEqualTo(dbPeer);
88 | assertThat(result.getDbInstance()).isEqualTo(dbInstance);
89 | }
90 |
91 | @ParameterizedTest(name = "[{0}]")
92 | @MethodSource("tnsNameUrls")
93 | void parseTnsName(final String url, final String dbPeer, final String dbInstance) {
94 | final ConnectionInfo result = testee.parse(url);
95 | assertThat(result.getDbType()).isEqualTo(ORACLE);
96 | assertThat(result.getDbPeer()).isEqualTo(dbPeer);
97 | assertThat(result.getDbInstance()).isEqualTo(dbInstance);
98 | }
99 |
100 | @ParameterizedTest(name = "[{0}]")
101 | @MethodSource("otherUrls")
102 | void parseOther(final String url, final String dbPeer, final String dbInstance) {
103 | final ConnectionInfo result = testee.parse(url);
104 | assertThat(result).isNotNull();
105 | assertThat(result.getDbType()).isEqualTo(ORACLE);
106 | assertThat(result.getDbPeer()).isEqualTo(dbPeer);
107 | assertThat(result.getDbInstance()).isEqualTo(dbInstance);
108 | }
109 | }
--------------------------------------------------------------------------------
/src/test/java/io/opentracing/contrib/jdbc/parser/SqlServerURLParserTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2021 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. 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 distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.contrib.jdbc.parser;
15 |
16 | import static org.assertj.core.api.Assertions.assertThat;
17 |
18 | import io.opentracing.contrib.jdbc.ConnectionInfo;
19 | import java.util.stream.Stream;
20 | import org.junit.jupiter.params.ParameterizedTest;
21 | import org.junit.jupiter.params.provider.Arguments;
22 | import org.junit.jupiter.params.provider.MethodSource;
23 |
24 | class SqlServerURLParserTest {
25 | private static final String SQLSERVER = "sqlserver";
26 | private final SqlServerURLParser urlParser = new SqlServerURLParser();
27 |
28 | private static Stream connectUrls() {
29 | return Stream.of(
30 | Arguments.of("jdbc:sqlserver://localhost\\instanceName:1435", "localhost:1435", null),
31 | Arguments.of("jdbc:sqlserver://localhost;integratedSecurity=true;", "localhost:1433", null),
32 | Arguments
33 | .of("jdbc:sqlserver://localhost;databaseName=AdventureWorks;integratedSecurity=true;",
34 | "localhost:1433", "AdventureWorks"),
35 | Arguments
36 | .of("jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks;integratedSecurity=true;",
37 | "localhost:1433", "AdventureWorks"),
38 | Arguments
39 | .of("jdbc:sqlserver://localhost;databaseName=AdventureWorks;integratedSecurity=true;applicationName=MyApp;",
40 | "localhost:1433", "AdventureWorks")
41 | );
42 | }
43 |
44 | @ParameterizedTest(name = "[{0}]")
45 | @MethodSource("connectUrls")
46 | void parseConnectUrls(final String url, final String dbPeer, final String dbInstance) {
47 | final ConnectionInfo result = urlParser.parse(url);
48 | assertThat(result.getDbType()).isEqualTo(SQLSERVER);
49 | assertThat(result.getDbPeer()).isEqualTo(dbPeer);
50 | assertThat(result.getDbInstance()).isEqualTo(dbInstance);
51 | }
52 | }
--------------------------------------------------------------------------------
/src/test/resources/META-INF/persistence.xml:
--------------------------------------------------------------------------------
1 |
16 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
37 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/travis/publish.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2017-2021 The OpenTracing Authors
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | # in compliance with the License. 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 distributed under the License
10 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | # or implied. See the License for the specific language governing permissions and limitations under
12 | # the License.
13 | #
14 |
15 | set -euo pipefail
16 | set -x
17 |
18 | build_started_by_tag() {
19 | if [ "${TRAVIS_TAG}" == "" ]; then
20 | echo "[Publishing] This build was not started by a tag, publishing snapshot"
21 | return 1
22 | else
23 | echo "[Publishing] This build was started by the tag ${TRAVIS_TAG}, publishing release"
24 | return 0
25 | fi
26 | }
27 |
28 | is_pull_request() {
29 | if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then
30 | echo "[Not Publishing] This is a Pull Request"
31 | return 0
32 | else
33 | echo "[Publishing] This is not a Pull Request"
34 | return 1
35 | fi
36 | }
37 |
38 | is_travis_branch_master() {
39 | if [ "${TRAVIS_BRANCH}" = master ]; then
40 | echo "[Publishing] Travis branch is master"
41 | return 0
42 | else
43 | echo "[Not Publishing] Travis branch is not master"
44 | return 1
45 | fi
46 | }
47 |
48 | check_travis_branch_equals_travis_tag() {
49 | #Weird comparison comparing branch to tag because when you 'git push --tags'
50 | #the branch somehow becomes the tag value
51 | #github issue: https://github.com/travis-ci/travis-ci/issues/1675
52 | if [ "${TRAVIS_BRANCH}" != "${TRAVIS_TAG}" ]; then
53 | echo "Travis branch does not equal Travis tag, which it should, bailing out."
54 | echo " github issue: https://github.com/travis-ci/travis-ci/issues/1675"
55 | exit 1
56 | else
57 | echo "[Publishing] Branch (${TRAVIS_BRANCH}) same as Tag (${TRAVIS_TAG})"
58 | fi
59 | }
60 |
61 | check_release_tag() {
62 | tag="${TRAVIS_TAG}"
63 | if [[ "$tag" =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then
64 | echo "Build started by version tag $tag. During the release process tags like this"
65 | echo "are created by the 'release' Maven plugin. Nothing to do here."
66 | exit 0
67 | elif [[ ! "$tag" =~ ^release-[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then
68 | echo "You must specify a tag of the format 'release-0.0.0' to release this project."
69 | echo "The provided tag ${tag} doesn't match that. Aborting."
70 | exit 1
71 | fi
72 | }
73 |
74 | is_release_commit() {
75 | project_version=$(./mvnw help:evaluate -N -Dexpression=project.version | grep -v '\[')
76 | if [[ "$project_version" =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then
77 | echo "Build started by release commit $project_version. Will synchronize to maven central."
78 | return 0
79 | else
80 | return 1
81 | fi
82 | }
83 |
84 | release_version() {
85 | echo "${TRAVIS_TAG}" | sed 's/^release-//'
86 | }
87 |
88 | safe_checkout_master() {
89 | # We need to be on a branch for release:perform to be able to create commits, and we want that branch to be master.
90 | # But we also want to make sure that we build and release exactly the tagged version, so we verify that the remote
91 | # master is where our tag is.
92 | git checkout -B master
93 | git fetch origin master:origin/master
94 | commit_local_master="$(git show --pretty='format:%H' master)"
95 | commit_remote_master="$(git show --pretty='format:%H' origin/master)"
96 | if [ "$commit_local_master" != "$commit_remote_master" ]; then
97 | echo "Master on remote 'origin' has commits since the version under release, aborting"
98 | exit 1
99 | fi
100 | }
101 |
102 | #----------------------
103 | # MAIN
104 | #----------------------
105 |
106 | if ! is_pull_request && build_started_by_tag; then
107 | check_travis_branch_equals_travis_tag
108 | check_release_tag
109 | fi
110 |
111 | ./mvnw install -nsu
112 |
113 | # If we are on a pull request, our only job is to run tests, which happened above via ./mvnw install
114 | if is_pull_request; then
115 | true
116 | # If we are on master, we will deploy the latest snapshot or release version
117 | # - If a release commit fails to deploy for a transient reason, delete the broken version from bintray and click rebuild
118 | elif is_travis_branch_master; then
119 | ./mvnw --batch-mode -s ./.settings.xml -Prelease -nsu -DskipTests deploy
120 |
121 | # If the deployment succeeded, sync it to Maven Central. Note: this needs to be done once per project, not module, hence -N
122 | if is_release_commit; then
123 | ./mvnw --batch-mode -s ./.settings.xml -nsu -N io.zipkin.centralsync-maven-plugin:centralsync-maven-plugin:sync
124 | fi
125 |
126 | # If we are on a release tag, the following will update any version references and push a version tag for deployment.
127 | elif build_started_by_tag; then
128 | safe_checkout_master
129 | ./mvnw --batch-mode -s ./.settings.xml -Prelease -nsu -DreleaseVersion="$(release_version)" -Darguments="-DskipTests" release:prepare
130 | fi
131 |
--------------------------------------------------------------------------------