├── .github └── workflows │ └── gradle.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── THIRD-PARTY ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── sdk ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── amazonaws │ │ │ └── xray │ │ │ └── opentelemetry │ │ │ └── tracing │ │ │ ├── EntitySpan.java │ │ │ ├── EntitySpanBuilder.java │ │ │ ├── RecorderBackedTracer.java │ │ │ ├── RecorderBackedTracerFactory.java │ │ │ ├── TracingProvider.java │ │ │ ├── metadata │ │ │ ├── EntityMetadata.java │ │ │ ├── EntityMetadataEvent.java │ │ │ └── EntityMetadataFactory.java │ │ │ ├── propagation │ │ │ └── HttpTraceContext.java │ │ │ ├── serializers │ │ │ └── EntityMetadataEventSerializer.java │ │ │ └── utils │ │ │ ├── ContextUtils.java │ │ │ └── TimeUtils.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── io.opentelemetry.trace.spi.TracerFactoryProvider │ └── test │ └── java │ └── com │ └── amazonaws │ └── xray │ └── opentelemetry │ └── tracing │ ├── EntitySpanTest.java │ ├── metadata │ └── EntityMetadataEventTest.java │ └── utils │ └── ContextUtilsTest.java └── settings.gradle /.github/workflows/gradle.yaml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-16.04 8 | strategy: 9 | matrix: 10 | # test against latest update of each major Java version, as well as specific updates of LTS versions: 11 | java: [ 8, 11 ] 12 | name: Java ${{ matrix.java }} 13 | steps: 14 | - uses: actions/checkout@master 15 | - name: Setup java 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: ${{ matrix.java }} 19 | - name: Build with Gradle 20 | run: ./gradlew build --info --stacktrace --continue 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/* 2 | **/target/* 3 | .gradle/* 4 | **/.gradle/* 5 | .settings/ 6 | .project 7 | .classpath 8 | build 9 | .DS_Store 10 | *.iml 11 | /.idea 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | AWS X-Ray SDK with OpenTelemetry 2 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## AWS X-Ray SDK w/ OpenTelemetry API 2 | 3 | The purpose of this repository is to serve as the central location for the development of the AWS X-Ray SDK for Java that is compatible with the [OpenTelemetry API](https://github.com/open-telemetry/opentelemetry-java/tree/master/api) currently under development. Our goal is to enable usage of both AWS X-Ray APIs and OpenTelemetry APIs within the same trace and enable usage of OpenTelemetry contrib integrations with AWS X-Ray. This enables open experimentation and sharing of ideas between these overlapping customer segments. 4 | 5 | Currently, the SDK release is 0.1.0-SNAPSHOT and supports the 0.2.0-SNAPSHOT release of OpenTelemetry. 6 | 7 | ## Objective 8 | 9 | Our goal is to address the following use cases on behalf of customers want to trace workloads: 10 | 11 | * Enable workloads instrumented using OpenTelemetry APIs to send data to services such as AWS X-Ray and Amazon CloudWatch. 12 | * Automate code instrumentation by making the use of agent frameworks such that developers no longer need to make manual code changes to instrument their applications. 13 | 14 | ## Roadmap 15 | 16 | * Proof of concept showing the use of X-Ray and OpenTelemetry libraries for code instrumentation. 17 | * Proof of concept showing the use of OpenTelemetry libraries with existing applications instrumented with the AWS X-Ray SDKs enabling support for a broader set of libraries 18 | * Alpha version of OpenTelemetry exporters for AWS X-Ray and Amazon CloudWatch 19 | * Alpha version of instrumentation agent for Java. 20 | 21 | ## Getting Started 22 | 23 | [See It In Action - Sample App](https://github.com/aws-samples/aws-xray-sdk-with-opentelemetry-sample) 24 | 25 | ### Adding the SDK To Your Project 26 | 27 | 1. Add snapshot builds and dependencies via your project’s dependency manager 28 | 2. Set the io.opentelemetry.trace.spi.TracerProvider Java property to com.amazonaws.xray.opentelemetry.tracing.TracingProvider 29 | 30 | ### Getting Started With Maven 31 | 32 | ```xml 33 | 34 | 35 | 36 | aws-snapshots 37 | https://aws.oss.sonatype.org/content/repositories/snapshots 38 | 39 | 40 | 41 | 42 | com.amazonaws 43 | aws-xray-sdk-opentelemetry 44 | 0.1.0-SNAPSHOT 45 | 46 | 47 | 48 | ``` 49 | 50 | ### Getting Started with Gradle 51 | 52 | ```groovy 53 | repositories { 54 | maven { 55 | url 'https://aws.oss.sonatype.org/content/repositories/snapshots' 56 | } 57 | } 58 | 59 | dependencies { 60 | runtimeOnly('com.amazonaws:aws-xray-sdk-opentelemetry:0.1.0-SNAPSHOT') 61 | } 62 | ``` 63 | 64 | ## Building From Source 65 | 66 | ```shell 67 | ./gradlew build 68 | ./gradlew publishToMavenLocal #if desired 69 | ``` 70 | 71 | ## Getting Help 72 | 73 | Please use these community resources for getting help. 74 | 75 | * If you think you may have found a bug or need assistance, please [open an issue](https://github.com/awslabs/aws-xray-sdk-with-opentelemetry/issues/new). 76 | * Open a support ticket with [AWS Support](http://docs.aws.amazon.com/awssupport/latest/user/getting-started.html). 77 | * Ask a question in the [AWS X-Ray Forum](https://forums.aws.amazon.com/forum.jspa?forumID=241&start=0). 78 | * For contributing guidelines refer [CONTRIBUTING.md](https://github.com/awslabs/aws-xray-sdk-with-opentelemetry/blob/master/CONTRIBUTING.md). 79 | 80 | ## License 81 | 82 | The AWS X-Ray SDK with OpenTelemetry is licensed under the Apache 2.0 License. See LICENSE and NOTICE.txt for more information. 83 | -------------------------------------------------------------------------------- /THIRD-PARTY: -------------------------------------------------------------------------------- 1 | ** aws-xray-sdk-java; version 2.4.0 -- https://github.com/aws/aws-xray-sdk-java 2 | Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | ** OpenTelemetry; version 0.2.0 -- 4 | https://github.com/open-telemetry/opentelemetry-java 5 | Apache License 6 | Version 2.0, January 2004 7 | http://www.apache.org/licenses/ 8 | 9 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 10 | 11 | 1. Definitions. 12 | 13 | "License" shall mean the terms and conditions for use, reproduction, 14 | and distribution as defined by Sections 1 through 9 of this document. 15 | 16 | "Licensor" shall mean the copyright owner or entity authorized by 17 | the copyright owner that is granting the License. 18 | 19 | "Legal Entity" shall mean the union of the acting entity and all 20 | other entities that control, are controlled by, or are under common 21 | control with that entity. For the purposes of this definition, 22 | "control" means (i) the power, direct or indirect, to cause the 23 | direction or management of such entity, whether by contract or 24 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 25 | outstanding shares, or (iii) beneficial ownership of such entity. 26 | 27 | "You" (or "Your") shall mean an individual or Legal Entity 28 | exercising permissions granted by this License. 29 | 30 | "Source" form shall mean the preferred form for making modifications, 31 | including but not limited to software source code, documentation 32 | source, and configuration files. 33 | 34 | "Object" form shall mean any form resulting from mechanical 35 | transformation or translation of a Source form, including but 36 | not limited to compiled object code, generated documentation, 37 | and conversions to other media types. 38 | 39 | "Work" shall mean the work of authorship, whether in Source or 40 | Object form, made available under the License, as indicated by a 41 | copyright notice that is included in or attached to the work 42 | (an example is provided in the Appendix below). 43 | 44 | "Derivative Works" shall mean any work, whether in Source or Object 45 | form, that is based on (or derived from) the Work and for which the 46 | editorial revisions, annotations, elaborations, or other modifications 47 | represent, as a whole, an original work of authorship. For the purposes 48 | of this License, Derivative Works shall not include works that remain 49 | separable from, or merely link (or bind by name) to the interfaces of, 50 | the Work and Derivative Works thereof. 51 | 52 | "Contribution" shall mean any work of authorship, including 53 | the original version of the Work and any modifications or additions 54 | to that Work or Derivative Works thereof, that is intentionally 55 | submitted to Licensor for inclusion in the Work by the copyright owner 56 | or by an individual or Legal Entity authorized to submit on behalf of 57 | the copyright owner. For the purposes of this definition, "submitted" 58 | means any form of electronic, verbal, or written communication sent 59 | to the Licensor or its representatives, including but not limited to 60 | communication on electronic mailing lists, source code control systems, 61 | and issue tracking systems that are managed by, or on behalf of, the 62 | Licensor for the purpose of discussing and improving the Work, but 63 | excluding communication that is conspicuously marked or otherwise 64 | designated in writing by the copyright owner as "Not a Contribution." 65 | 66 | "Contributor" shall mean Licensor and any individual or Legal Entity 67 | on behalf of whom a Contribution has been received by Licensor and 68 | subsequently incorporated within the Work. 69 | 70 | 2. Grant of Copyright License. Subject to the terms and conditions of 71 | this License, each Contributor hereby grants to You a perpetual, 72 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 73 | copyright license to reproduce, prepare Derivative Works of, 74 | publicly display, publicly perform, sublicense, and distribute the 75 | Work and such Derivative Works in Source or Object form. 76 | 77 | 3. Grant of Patent License. Subject to the terms and conditions of 78 | this License, each Contributor hereby grants to You a perpetual, 79 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 80 | (except as stated in this section) patent license to make, have made, 81 | use, offer to sell, sell, import, and otherwise transfer the Work, 82 | where such license applies only to those patent claims licensable 83 | by such Contributor that are necessarily infringed by their 84 | Contribution(s) alone or by combination of their Contribution(s) 85 | with the Work to which such Contribution(s) was submitted. If You 86 | institute patent litigation against any entity (including a 87 | cross-claim or counterclaim in a lawsuit) alleging that the Work 88 | or a Contribution incorporated within the Work constitutes direct 89 | or contributory patent infringement, then any patent licenses 90 | granted to You under this License for that Work shall terminate 91 | as of the date such litigation is filed. 92 | 93 | 4. Redistribution. You may reproduce and distribute copies of the 94 | Work or Derivative Works thereof in any medium, with or without 95 | modifications, and in Source or Object form, provided that You 96 | meet the following conditions: 97 | 98 | (a) You must give any other recipients of the Work or 99 | Derivative Works a copy of this License; and 100 | 101 | (b) You must cause any modified files to carry prominent notices 102 | stating that You changed the files; and 103 | 104 | (c) You must retain, in the Source form of any Derivative Works 105 | that You distribute, all copyright, patent, trademark, and 106 | attribution notices from the Source form of the Work, 107 | excluding those notices that do not pertain to any part of 108 | the Derivative Works; and 109 | 110 | (d) If the Work includes a "NOTICE" text file as part of its 111 | distribution, then any Derivative Works that You distribute must 112 | include a readable copy of the attribution notices contained 113 | within such NOTICE file, excluding those notices that do not 114 | pertain to any part of the Derivative Works, in at least one 115 | of the following places: within a NOTICE text file distributed 116 | as part of the Derivative Works; within the Source form or 117 | documentation, if provided along with the Derivative Works; or, 118 | within a display generated by the Derivative Works, if and 119 | wherever such third-party notices normally appear. The contents 120 | of the NOTICE file are for informational purposes only and 121 | do not modify the License. You may add Your own attribution 122 | notices within Derivative Works that You distribute, alongside 123 | or as an addendum to the NOTICE text from the Work, provided 124 | that such additional attribution notices cannot be construed 125 | as modifying the License. 126 | 127 | You may add Your own copyright statement to Your modifications and 128 | may provide additional or different license terms and conditions 129 | for use, reproduction, or distribution of Your modifications, or 130 | for any such Derivative Works as a whole, provided Your use, 131 | reproduction, and distribution of the Work otherwise complies with 132 | the conditions stated in this License. 133 | 134 | 5. Submission of Contributions. Unless You explicitly state otherwise, 135 | any Contribution intentionally submitted for inclusion in the Work 136 | by You to the Licensor shall be under the terms and conditions of 137 | this License, without any additional terms or conditions. 138 | Notwithstanding the above, nothing herein shall supersede or modify 139 | the terms of any separate license agreement you may have executed 140 | with Licensor regarding such Contributions. 141 | 142 | 6. Trademarks. This License does not grant permission to use the trade 143 | names, trademarks, service marks, or product names of the Licensor, 144 | except as required for reasonable and customary use in describing the 145 | origin of the Work and reproducing the content of the NOTICE file. 146 | 147 | 7. Disclaimer of Warranty. Unless required by applicable law or 148 | agreed to in writing, Licensor provides the Work (and each 149 | Contributor provides its Contributions) on an "AS IS" BASIS, 150 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 151 | implied, including, without limitation, any warranties or conditions 152 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 153 | PARTICULAR PURPOSE. You are solely responsible for determining the 154 | appropriateness of using or redistributing the Work and assume any 155 | risks associated with Your exercise of permissions under this License. 156 | 157 | 8. Limitation of Liability. In no event and under no legal theory, 158 | whether in tort (including negligence), contract, or otherwise, 159 | unless required by applicable law (such as deliberate and grossly 160 | negligent acts) or agreed to in writing, shall any Contributor be 161 | liable to You for damages, including any direct, indirect, special, 162 | incidental, or consequential damages of any character arising as a 163 | result of this License or out of the use or inability to use the 164 | Work (including but not limited to damages for loss of goodwill, 165 | work stoppage, computer failure or malfunction, or any and all 166 | other commercial damages or losses), even if such Contributor 167 | has been advised of the possibility of such damages. 168 | 169 | 9. Accepting Warranty or Additional Liability. While redistributing 170 | the Work or Derivative Works thereof, You may choose to offer, 171 | and charge a fee for, acceptance of support, warranty, indemnity, 172 | or other liability obligations and/or rights consistent with this 173 | License. However, in accepting such obligations, You may act only 174 | on Your own behalf and on Your sole responsibility, not on behalf 175 | of any other Contributor, and only if You agree to indemnify, 176 | defend, and hold each Contributor harmless for any liability 177 | incurred by, or claims asserted against, such Contributor by reason 178 | of your accepting any such warranty or additional liability. 179 | 180 | END OF TERMS AND CONDITIONS 181 | 182 | APPENDIX: How to apply the Apache License to your work. 183 | 184 | To apply the Apache License to your work, attach the following 185 | boilerplate notice, with the fields enclosed by brackets "[]" 186 | replaced with your own identifying information. (Don't include 187 | the brackets!) The text should be enclosed in the appropriate 188 | comment syntax for the file format. We also recommend that a 189 | file or class name and description of purpose be included on the 190 | same "printed page" as the copyright notice for easier 191 | identification within third-party archives. 192 | 193 | Copyright [yyyy] [name of copyright owner] 194 | 195 | Licensed under the Apache License, Version 2.0 (the "License"); 196 | you may not use this file except in compliance with the License. 197 | You may obtain a copy of the License at 198 | 199 | http://www.apache.org/licenses/LICENSE-2.0 200 | 201 | Unless required by applicable law or agreed to in writing, software 202 | distributed under the License is distributed on an "AS IS" BASIS, 203 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 204 | See the License for the specific language governing permissions and 205 | limitations under the License. 206 | 207 | Apache License 208 | 209 | Version 2.0, January 2004 210 | 211 | http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND 212 | DISTRIBUTION 213 | 214 | 1. Definitions. 215 | 216 | "License" shall mean the terms and conditions for use, reproduction, and 217 | distribution as defined by Sections 1 through 9 of this document. 218 | 219 | "Licensor" shall mean the copyright owner or entity authorized by the 220 | copyright owner that is granting the License. 221 | 222 | "Legal Entity" shall mean the union of the acting entity and all other 223 | entities that control, are controlled by, or are under common control 224 | with that entity. For the purposes of this definition, "control" means 225 | (i) the power, direct or indirect, to cause the direction or management 226 | of such entity, whether by contract or otherwise, or (ii) ownership of 227 | fifty percent (50%) or more of the outstanding shares, or (iii) 228 | beneficial ownership of such entity. 229 | 230 | "You" (or "Your") shall mean an individual or Legal Entity exercising 231 | permissions granted by this License. 232 | 233 | "Source" form shall mean the preferred form for making modifications, 234 | including but not limited to software source code, documentation source, 235 | and configuration files. 236 | 237 | "Object" form shall mean any form resulting from mechanical 238 | transformation or translation of a Source form, including but not limited 239 | to compiled object code, generated documentation, and conversions to 240 | other media types. 241 | 242 | "Work" shall mean the work of authorship, whether in Source or Object 243 | form, made available under the License, as indicated by a copyright 244 | notice that is included in or attached to the work (an example is 245 | provided in the Appendix below). 246 | 247 | "Derivative Works" shall mean any work, whether in Source or Object form, 248 | that is based on (or derived from) the Work and for which the editorial 249 | revisions, annotations, elaborations, or other modifications represent, 250 | as a whole, an original work of authorship. For the purposes of this 251 | License, Derivative Works shall not include works that remain separable 252 | from, or merely link (or bind by name) to the interfaces of, the Work and 253 | Derivative Works thereof. 254 | 255 | "Contribution" shall mean any work of authorship, including the original 256 | version of the Work and any modifications or additions to that Work or 257 | Derivative Works thereof, that is intentionally submitted to Licensor for 258 | inclusion in the Work by the copyright owner or by an individual or Legal 259 | Entity authorized to submit on behalf of the copyright owner. For the 260 | purposes of this definition, "submitted" means any form of electronic, 261 | verbal, or written communication sent to the Licensor or its 262 | representatives, including but not limited to communication on electronic 263 | mailing lists, source code control systems, and issue tracking systems 264 | that are managed by, or on behalf of, the Licensor for the purpose of 265 | discussing and improving the Work, but excluding communication that is 266 | conspicuously marked or otherwise designated in writing by the copyright 267 | owner as "Not a Contribution." 268 | 269 | "Contributor" shall mean Licensor and any individual or Legal Entity on 270 | behalf of whom a Contribution has been received by Licensor and 271 | subsequently incorporated within the Work. 272 | 273 | 2. Grant of Copyright License. Subject to the terms and conditions of this 274 | License, each Contributor hereby grants to You a perpetual, worldwide, 275 | non-exclusive, no-charge, royalty-free, irrevocable copyright license to 276 | reproduce, prepare Derivative Works of, publicly display, publicly perform, 277 | sublicense, and distribute the Work and such Derivative Works in Source or 278 | Object form. 279 | 280 | 3. Grant of Patent License. Subject to the terms and conditions of this 281 | License, each Contributor hereby grants to You a perpetual, worldwide, 282 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in 283 | this section) patent license to make, have made, use, offer to sell, sell, 284 | import, and otherwise transfer the Work, where such license applies only to 285 | those patent claims licensable by such Contributor that are necessarily 286 | infringed by their Contribution(s) alone or by combination of their 287 | Contribution(s) with the Work to which such Contribution(s) was submitted. 288 | If You institute patent litigation against any entity (including a 289 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 290 | Contribution incorporated within the Work constitutes direct or contributory 291 | patent infringement, then any patent licenses granted to You under this 292 | License for that Work shall terminate as of the date such litigation is 293 | filed. 294 | 295 | 4. Redistribution. You may reproduce and distribute copies of the Work or 296 | Derivative Works thereof in any medium, with or without modifications, and 297 | in Source or Object form, provided that You meet the following conditions: 298 | 299 | (a) You must give any other recipients of the Work or Derivative Works a 300 | copy of this License; and 301 | 302 | (b) You must cause any modified files to carry prominent notices stating 303 | that You changed the files; and 304 | 305 | (c) You must retain, in the Source form of any Derivative Works that You 306 | distribute, all copyright, patent, trademark, and attribution notices 307 | from the Source form of the Work, excluding those notices that do not 308 | pertain to any part of the Derivative Works; and 309 | 310 | (d) If the Work includes a "NOTICE" text file as part of its 311 | distribution, then any Derivative Works that You distribute must include 312 | a readable copy of the attribution notices contained within such NOTICE 313 | file, excluding those notices that do not pertain to any part of the 314 | Derivative Works, in at least one of the following places: within a 315 | NOTICE text file distributed as part of the Derivative Works; within the 316 | Source form or documentation, if provided along with the Derivative 317 | Works; or, within a display generated by the Derivative Works, if and 318 | wherever such third-party notices normally appear. The contents of the 319 | NOTICE file are for informational purposes only and do not modify the 320 | License. You may add Your own attribution notices within Derivative Works 321 | that You distribute, alongside or as an addendum to the NOTICE text from 322 | the Work, provided that such additional attribution notices cannot be 323 | construed as modifying the License. 324 | 325 | You may add Your own copyright statement to Your modifications and may 326 | provide additional or different license terms and conditions for use, 327 | reproduction, or distribution of Your modifications, or for any such 328 | Derivative Works as a whole, provided Your use, reproduction, and 329 | distribution of the Work otherwise complies with the conditions stated in 330 | this License. 331 | 332 | 5. Submission of Contributions. Unless You explicitly state otherwise, any 333 | Contribution intentionally submitted for inclusion in the Work by You to the 334 | Licensor shall be under the terms and conditions of this License, without 335 | any additional terms or conditions. Notwithstanding the above, nothing 336 | herein shall supersede or modify the terms of any separate license agreement 337 | you may have executed with Licensor regarding such Contributions. 338 | 339 | 6. Trademarks. This License does not grant permission to use the trade 340 | names, trademarks, service marks, or product names of the Licensor, except 341 | as required for reasonable and customary use in describing the origin of the 342 | Work and reproducing the content of the NOTICE file. 343 | 344 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in 345 | writing, Licensor provides the Work (and each Contributor provides its 346 | Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 347 | KIND, either express or implied, including, without limitation, any 348 | warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or 349 | FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining 350 | the appropriateness of using or redistributing the Work and assume any risks 351 | associated with Your exercise of permissions under this License. 352 | 353 | 8. Limitation of Liability. In no event and under no legal theory, whether 354 | in tort (including negligence), contract, or otherwise, unless required by 355 | applicable law (such as deliberate and grossly negligent acts) or agreed to 356 | in writing, shall any Contributor be liable to You for damages, including 357 | any direct, indirect, special, incidental, or consequential damages of any 358 | character arising as a result of this License or out of the use or inability 359 | to use the Work (including but not limited to damages for loss of goodwill, 360 | work stoppage, computer failure or malfunction, or any and all other 361 | commercial damages or losses), even if such Contributor has been advised of 362 | the possibility of such damages. 363 | 364 | 9. Accepting Warranty or Additional Liability. While redistributing the Work 365 | or Derivative Works thereof, You may choose to offer, and charge a fee for, 366 | acceptance of support, warranty, indemnity, or other liability obligations 367 | and/or rights consistent with this License. However, in accepting such 368 | obligations, You may act only on Your own behalf and on Your sole 369 | responsibility, not on behalf of any other Contributor, and only if You 370 | agree to indemnify, defend, and hold each Contributor harmless for any 371 | liability incurred by, or claims asserted against, such Contributor by 372 | reason of your accepting any such warranty or additional liability. END OF 373 | TERMS AND CONDITIONS 374 | 375 | APPENDIX: How to apply the Apache License to your work. 376 | 377 | To apply the Apache License to your work, attach the following boilerplate 378 | notice, with the fields enclosed by brackets "[]" replaced with your own 379 | identifying information. (Don't include the brackets!) The text should be 380 | enclosed in the appropriate comment syntax for the file format. We also 381 | recommend that a file or class name and description of purpose be included on 382 | the same "printed page" as the copyright notice for easier identification 383 | within third-party archives. 384 | 385 | Copyright [yyyy] [name of copyright owner] 386 | 387 | Licensed under the Apache License, Version 2.0 (the "License"); 388 | 389 | you may not use this file except in compliance with the License. 390 | 391 | You may obtain a copy of the License at 392 | 393 | http://www.apache.org/licenses/LICENSE-2.0 394 | 395 | Unless required by applicable law or agreed to in writing, software 396 | 397 | distributed under the License is distributed on an "AS IS" BASIS, 398 | 399 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 400 | 401 | See the License for the specific language governing permissions and 402 | 403 | limitations under the License. 404 | 405 | * For aws-xray-sdk-java see also this required NOTICE: 406 | Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 407 | * For OpenTelemetry see also this required NOTICE: 408 | Apache License 409 | Version 2.0, January 2004 410 | http://www.apache.org/licenses/ 411 | 412 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 413 | 414 | 1. Definitions. 415 | 416 | "License" shall mean the terms and conditions for use, reproduction, 417 | and distribution as defined by Sections 1 through 9 of this document. 418 | 419 | "Licensor" shall mean the copyright owner or entity authorized by 420 | the copyright owner that is granting the License. 421 | 422 | "Legal Entity" shall mean the union of the acting entity and all 423 | other entities that control, are controlled by, or are under common 424 | control with that entity. For the purposes of this definition, 425 | "control" means (i) the power, direct or indirect, to cause the 426 | direction or management of such entity, whether by contract or 427 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 428 | outstanding shares, or (iii) beneficial ownership of such entity. 429 | 430 | "You" (or "Your") shall mean an individual or Legal Entity 431 | exercising permissions granted by this License. 432 | 433 | "Source" form shall mean the preferred form for making modifications, 434 | including but not limited to software source code, documentation 435 | source, and configuration files. 436 | 437 | "Object" form shall mean any form resulting from mechanical 438 | transformation or translation of a Source form, including but 439 | not limited to compiled object code, generated documentation, 440 | and conversions to other media types. 441 | 442 | "Work" shall mean the work of authorship, whether in Source or 443 | Object form, made available under the License, as indicated by a 444 | copyright notice that is included in or attached to the work 445 | (an example is provided in the Appendix below). 446 | 447 | "Derivative Works" shall mean any work, whether in Source or Object 448 | form, that is based on (or derived from) the Work and for which the 449 | editorial revisions, annotations, elaborations, or other 450 | modifications 451 | represent, as a whole, an original work of authorship. For the 452 | purposes 453 | of this License, Derivative Works shall not include works that remain 454 | separable from, or merely link (or bind by name) to the interfaces 455 | of, 456 | the Work and Derivative Works thereof. 457 | 458 | "Contribution" shall mean any work of authorship, including 459 | the original version of the Work and any modifications or additions 460 | to that Work or Derivative Works thereof, that is intentionally 461 | submitted to Licensor for inclusion in the Work by the copyright 462 | owner 463 | or by an individual or Legal Entity authorized to submit on behalf of 464 | the copyright owner. For the purposes of this definition, "submitted" 465 | means any form of electronic, verbal, or written communication sent 466 | to the Licensor or its representatives, including but not limited to 467 | communication on electronic mailing lists, source code control 468 | systems, 469 | and issue tracking systems that are managed by, or on behalf of, the 470 | Licensor for the purpose of discussing and improving the Work, but 471 | excluding communication that is conspicuously marked or otherwise 472 | designated in writing by the copyright owner as "Not a Contribution." 473 | 474 | "Contributor" shall mean Licensor and any individual or Legal Entity 475 | on behalf of whom a Contribution has been received by Licensor and 476 | subsequently incorporated within the Work. 477 | 478 | 2. Grant of Copyright License. Subject to the terms and conditions of 479 | this License, each Contributor hereby grants to You a perpetual, 480 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 481 | copyright license to reproduce, prepare Derivative Works of, 482 | publicly display, publicly perform, sublicense, and distribute the 483 | Work and such Derivative Works in Source or Object form. 484 | 485 | 3. Grant of Patent License. Subject to the terms and conditions of 486 | this License, each Contributor hereby grants to You a perpetual, 487 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 488 | (except as stated in this section) patent license to make, have made, 489 | use, offer to sell, sell, import, and otherwise transfer the Work, 490 | where such license applies only to those patent claims licensable 491 | by such Contributor that are necessarily infringed by their 492 | Contribution(s) alone or by combination of their Contribution(s) 493 | with the Work to which such Contribution(s) was submitted. If You 494 | institute patent litigation against any entity (including a 495 | cross-claim or counterclaim in a lawsuit) alleging that the Work 496 | or a Contribution incorporated within the Work constitutes direct 497 | or contributory patent infringement, then any patent licenses 498 | granted to You under this License for that Work shall terminate 499 | as of the date such litigation is filed. 500 | 501 | 4. Redistribution. You may reproduce and distribute copies of the 502 | Work or Derivative Works thereof in any medium, with or without 503 | modifications, and in Source or Object form, provided that You 504 | meet the following conditions: 505 | 506 | (a) You must give any other recipients of the Work or 507 | Derivative Works a copy of this License; and 508 | 509 | (b) You must cause any modified files to carry prominent notices 510 | stating that You changed the files; and 511 | 512 | (c) You must retain, in the Source form of any Derivative Works 513 | that You distribute, all copyright, patent, trademark, and 514 | attribution notices from the Source form of the Work, 515 | excluding those notices that do not pertain to any part of 516 | the Derivative Works; and 517 | 518 | (d) If the Work includes a "NOTICE" text file as part of its 519 | distribution, then any Derivative Works that You distribute must 520 | include a readable copy of the attribution notices contained 521 | within such NOTICE file, excluding those notices that do not 522 | pertain to any part of the Derivative Works, in at least one 523 | of the following places: within a NOTICE text file distributed 524 | as part of the Derivative Works; within the Source form or 525 | documentation, if provided along with the Derivative Works; or, 526 | within a display generated by the Derivative Works, if and 527 | wherever such third-party notices normally appear. The contents 528 | of the NOTICE file are for informational purposes only and 529 | do not modify the License. You may add Your own attribution 530 | notices within Derivative Works that You distribute, alongside 531 | or as an addendum to the NOTICE text from the Work, provided 532 | that such additional attribution notices cannot be construed 533 | as modifying the License. 534 | 535 | You may add Your own copyright statement to Your modifications and 536 | may provide additional or different license terms and conditions 537 | for use, reproduction, or distribution of Your modifications, or 538 | for any such Derivative Works as a whole, provided Your use, 539 | reproduction, and distribution of the Work otherwise complies with 540 | the conditions stated in this License. 541 | 542 | 5. Submission of Contributions. Unless You explicitly state otherwise, 543 | any Contribution intentionally submitted for inclusion in the Work 544 | by You to the Licensor shall be under the terms and conditions of 545 | this License, without any additional terms or conditions. 546 | Notwithstanding the above, nothing herein shall supersede or modify 547 | the terms of any separate license agreement you may have executed 548 | with Licensor regarding such Contributions. 549 | 550 | 6. Trademarks. This License does not grant permission to use the trade 551 | names, trademarks, service marks, or product names of the Licensor, 552 | except as required for reasonable and customary use in describing the 553 | origin of the Work and reproducing the content of the NOTICE file. 554 | 555 | 7. Disclaimer of Warranty. Unless required by applicable law or 556 | agreed to in writing, Licensor provides the Work (and each 557 | Contributor provides its Contributions) on an "AS IS" BASIS, 558 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 559 | implied, including, without limitation, any warranties or conditions 560 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 561 | PARTICULAR PURPOSE. You are solely responsible for determining the 562 | appropriateness of using or redistributing the Work and assume any 563 | risks associated with Your exercise of permissions under this 564 | License. 565 | 566 | 8. Limitation of Liability. In no event and under no legal theory, 567 | whether in tort (including negligence), contract, or otherwise, 568 | unless required by applicable law (such as deliberate and grossly 569 | negligent acts) or agreed to in writing, shall any Contributor be 570 | liable to You for damages, including any direct, indirect, special, 571 | incidental, or consequential damages of any character arising as a 572 | result of this License or out of the use or inability to use the 573 | Work (including but not limited to damages for loss of goodwill, 574 | work stoppage, computer failure or malfunction, or any and all 575 | other commercial damages or losses), even if such Contributor 576 | has been advised of the possibility of such damages. 577 | 578 | 9. Accepting Warranty or Additional Liability. While redistributing 579 | the Work or Derivative Works thereof, You may choose to offer, 580 | and charge a fee for, acceptance of support, warranty, indemnity, 581 | or other liability obligations and/or rights consistent with this 582 | License. However, in accepting such obligations, You may act only 583 | on Your own behalf and on Your sole responsibility, not on behalf 584 | of any other Contributor, and only if You agree to indemnify, 585 | defend, and hold each Contributor harmless for any liability 586 | incurred by, or claims asserted against, such Contributor by reason 587 | of your accepting any such warranty or additional liability. 588 | 589 | END OF TERMS AND CONDITIONS 590 | 591 | APPENDIX: How to apply the Apache License to your work. 592 | 593 | To apply the Apache License to your work, attach the following 594 | boilerplate notice, with the fields enclosed by brackets "[]" 595 | replaced with your own identifying information. (Don't include 596 | the brackets!) The text should be enclosed in the appropriate 597 | comment syntax for the file format. We also recommend that a 598 | file or class name and description of purpose be included on the 599 | same "printed page" as the copyright notice for easier 600 | identification within third-party archives. 601 | 602 | Copyright [yyyy] [name of copyright owner] 603 | 604 | Licensed under the Apache License, Version 2.0 (the "License"); 605 | you may not use this file except in compliance with the License. 606 | You may obtain a copy of the License at 607 | 608 | http://www.apache.org/licenses/LICENSE-2.0 609 | 610 | Unless required by applicable law or agreed to in writing, software 611 | distributed under the License is distributed on an "AS IS" BASIS, 612 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 613 | See the License for the specific language governing permissions and 614 | limitations under the License. 615 | 616 | ------ 617 | 618 | ** Mockito 3.1.0; version 3.1.0 -- https://github.com/mockito/mockito 619 | Copyright (c) 2007 Mockito contributors 620 | 621 | The MIT License 622 | 623 | Copyright (c) 2007 Mockito contributors 624 | 625 | Permission is hereby granted, free of charge, to any person obtaining a copy 626 | of this software and associated documentation files (the "Software"), to deal 627 | in the Software without restriction, including without limitation the rights 628 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 629 | copies of the Software, and to permit persons to whom the Software is 630 | furnished to do so, subject to the following conditions: 631 | 632 | The above copyright notice and this permission notice shall be included in 633 | all copies or substantial portions of the Software. 634 | 635 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 636 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 637 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 638 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 639 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 640 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 641 | THE SOFTWARE. 642 | 643 | ------ 644 | 645 | ** junit 5.3.1; version 5.3.1 -- https://github.com/junit-team/junit5 646 | Open Source Licenses 647 | This product may include a number of subcomponents with separate copyright 648 | notices and license terms. Your use of the source code for these subcomponents 649 | is subject to the terms and conditions of the subcomponent's license, as noted 650 | in the LICENSE-.md files. 651 | 652 | Eclipse Public License - v 2.0 653 | ============================== 654 | 655 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 656 | LICENSE (“AGREEMENT”). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 657 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 658 | 659 | ### 1. Definitions 660 | 661 | “Contribution” means: 662 | * **a)** in the case of the initial Contributor, the initial content 663 | Distributed under this Agreement, and 664 | * **b)** in the case of each subsequent Contributor: 665 | * **i)** changes to the Program, and 666 | * **ii)** additions to the Program; 667 | where such changes and/or additions to the Program originate from and are 668 | Distributed by that particular Contributor. A Contribution “originates” from a 669 | Contributor if it was added to the Program by such Contributor itself or anyone 670 | acting on such Contributor's behalf. Contributions do not include changes or 671 | additions to the Program that are not Modified Works. 672 | 673 | “Contributor” means any person or entity that Distributes the Program. 674 | 675 | “Licensed Patents” mean patent claims licensable by a Contributor which are 676 | necessarily infringed by the use or sale of its Contribution alone or when 677 | combined with the Program. 678 | 679 | “Program” means the Contributions Distributed in accordance with this 680 | Agreement. 681 | 682 | “Recipient” means anyone who receives the Program under this Agreement or any 683 | Secondary License (as applicable), including Contributors. 684 | 685 | “Derivative Works” shall mean any work, whether in Source Code or other form, 686 | that is based on (or derived from) the Program and for which the editorial 687 | revisions, annotations, elaborations, or other modifications represent, as a 688 | whole, an original work of authorship. 689 | 690 | “Modified Works” shall mean any work in Source Code or other form that results 691 | from an addition to, deletion from, or modification of the contents of the 692 | Program, including, for purposes of clarity any new file in Source Code form 693 | that contains any contents of the Program. Modified Works shall not include 694 | works that contain only declarations, interfaces, types, classes, structures, 695 | or files of the Program solely in each case in order to link to, bind by name, 696 | or subclass the Program or Modified Works thereof. 697 | 698 | “Distribute” means the acts of **a)** distributing or **b)** making available 699 | in any manner that enables the transfer of a copy. 700 | 701 | “Source Code” means the form of a Program preferred for making modifications, 702 | including but not limited to software source code, documentation source, and 703 | configuration files. 704 | 705 | “Secondary License” means either the GNU General Public License, Version 2.0, 706 | or any later versions of that license, including any exceptions or additional 707 | permissions as identified by the initial Contributor. 708 | 709 | ### 2. Grant of Rights 710 | 711 | **a)** Subject to the terms of this Agreement, each Contributor hereby grants 712 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 713 | reproduce, prepare Derivative Works of, publicly display, publicly perform, 714 | Distribute and sublicense the Contribution of such Contributor, if any, and 715 | such Derivative Works. 716 | 717 | **b)** Subject to the terms of this Agreement, each Contributor hereby grants 718 | Recipient a non-exclusive, worldwide, royalty-free patent license under 719 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 720 | transfer the Contribution of such Contributor, if any, in Source Code or other 721 | form. This patent license shall apply to the combination of the Contribution 722 | and the Program if, at the time the Contribution is added by the Contributor, 723 | such addition of the Contribution causes such combination to be covered by the 724 | Licensed Patents. The patent license shall not apply to any other combinations 725 | which include the Contribution. No hardware per se is licensed hereunder. 726 | 727 | **c)** Recipient understands that although each Contributor grants the licenses 728 | to its Contributions set forth herein, no assurances are provided by any 729 | Contributor that the Program does not infringe the patent or other intellectual 730 | property rights of any other entity. Each Contributor disclaims any liability 731 | to Recipient for claims brought by any other entity based on infringement of 732 | intellectual property rights or otherwise. As a condition to exercising the 733 | rights and licenses granted hereunder, each Recipient hereby assumes sole 734 | responsibility to secure any other intellectual property rights needed, if any. 735 | For example, if a third party patent license is required to allow Recipient to 736 | Distribute the Program, it is Recipient's responsibility to acquire that 737 | license before distributing the Program. 738 | 739 | **d)** Each Contributor represents that to its knowledge it has sufficient 740 | copyright rights in its Contribution, if any, to grant the copyright license 741 | set forth in this Agreement. 742 | 743 | **e)** Notwithstanding the terms of any Secondary License, no Contributor makes 744 | additional grants to any Recipient (other than those set forth in this 745 | Agreement) as a result of such Recipient's receipt of the Program under the 746 | terms of a Secondary License (if permitted under the terms of Section 3). 747 | 748 | ### 3. Requirements 749 | 750 | **3.1** If a Contributor Distributes the Program in any form, then: 751 | 752 | * **a)** the Program must also be made available as Source Code, in accordance 753 | with section 3.2, and the Contributor must accompany the Program with a 754 | statement that the Source Code for the Program is available under this 755 | Agreement, and informs Recipients how to obtain it in a reasonable manner on or 756 | through a medium customarily used for software exchange; and 757 | 758 | * **b)** the Contributor may Distribute the Program under a license different 759 | than this Agreement, provided that such license: 760 | * **i)** effectively disclaims on behalf of all other Contributors all 761 | warranties and conditions, express and implied, including warranties or 762 | conditions of title and non-infringement, and implied warranties or conditions 763 | of merchantability and fitness for a particular purpose; 764 | * **ii)** effectively excludes on behalf of all other Contributors all 765 | liability for damages, including direct, indirect, special, incidental and 766 | consequential damages, such as lost profits; 767 | * **iii)** does not attempt to limit or alter the recipients' rights in the 768 | Source Code under section 3.2; and 769 | * **iv)** requires any subsequent distribution of the Program by any party to 770 | be under a license that satisfies the requirements of this section 3. 771 | 772 | **3.2** When the Program is Distributed as Source Code: 773 | 774 | * **a)** it must be made available under this Agreement, or if the Program 775 | **(i)** is combined with other material in a separate file or files made 776 | available under a Secondary License, and **(ii)** the initial Contributor 777 | attached to the Source Code the notice described in Exhibit A of this 778 | Agreement, then the Program may be made available under the terms of such 779 | Secondary Licenses, and 780 | * **b)** a copy of this Agreement must be included with each copy of the 781 | Program. 782 | 783 | **3.3** Contributors may not remove or alter any copyright, patent, trademark, 784 | attribution notices, disclaimers of warranty, or limitations of liability 785 | (“notices”) contained within the Program from any copy of the Program which 786 | they Distribute, provided that Contributors may add their own appropriate 787 | notices. 788 | 789 | ### 4. Commercial Distribution 790 | 791 | Commercial distributors of software may accept certain responsibilities with 792 | respect to end users, business partners and the like. While this license is 793 | intended to facilitate the commercial use of the Program, the Contributor who 794 | includes the Program in a commercial product offering should do so in a manner 795 | which does not create potential liability for other Contributors. Therefore, if 796 | a Contributor includes the Program in a commercial product offering, such 797 | Contributor (“Commercial Contributor”) hereby agrees to defend and indemnify 798 | every other Contributor (“Indemnified Contributor”) against any losses, damages 799 | and costs (collectively “Losses”) arising from claims, lawsuits and other legal 800 | actions brought by a third party against the Indemnified Contributor to the 801 | extent caused by the acts or omissions of such Commercial Contributor in 802 | connection with its distribution of the Program in a commercial product 803 | offering. The obligations in this section do not apply to any claims or Losses 804 | relating to any actual or alleged intellectual property infringement. In order 805 | to qualify, an Indemnified Contributor must: **a)** promptly notify the 806 | Commercial Contributor in writing of such claim, and **b)** allow the 807 | Commercial Contributor to control, and cooperate with the Commercial 808 | Contributor in, the defense and any related settlement negotiations. The 809 | Indemnified Contributor may participate in any such claim at its own expense. 810 | 811 | For example, a Contributor might include the Program in a commercial product 812 | offering, Product X. That Contributor is then a Commercial Contributor. If that 813 | Commercial Contributor then makes performance claims, or offers warranties 814 | related to Product X, those performance claims and warranties are such 815 | Commercial Contributor's responsibility alone. Under this section, the 816 | Commercial Contributor would have to defend claims against the other 817 | Contributors related to those performance claims and warranties, and if a court 818 | requires any other Contributor to pay any damages as a result, the Commercial 819 | Contributor must pay those damages. 820 | 821 | ### 5. No Warranty 822 | 823 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED BY 824 | APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN “AS IS” BASIS, WITHOUT WARRANTIES 825 | OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 826 | LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 827 | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely 828 | responsible for determining the appropriateness of using and distributing the 829 | Program and assumes all risks associated with its exercise of rights under this 830 | Agreement, including but not limited to the risks and costs of program errors, 831 | compliance with applicable laws, damage to or loss of data, programs or 832 | equipment, and unavailability or interruption of operations. 833 | 834 | ### 6. Disclaimer of Liability 835 | 836 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED BY 837 | APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY 838 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 839 | DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY 840 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 841 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF 842 | THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF 843 | THE POSSIBILITY OF SUCH DAMAGES. 844 | 845 | ### 7. General 846 | 847 | If any provision of this Agreement is invalid or unenforceable under applicable 848 | law, it shall not affect the validity or enforceability of the remainder of the 849 | terms of this Agreement, and without further action by the parties hereto, such 850 | provision shall be reformed to the minimum extent necessary to make such 851 | provision valid and enforceable. 852 | 853 | If Recipient institutes patent litigation against any entity (including a 854 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 855 | (excluding combinations of the Program with other software or hardware) 856 | infringes such Recipient's patent(s), then such Recipient's rights granted 857 | under Section 2(b) shall terminate as of the date such litigation is filed. 858 | 859 | All Recipient's rights under this Agreement shall terminate if it fails to 860 | comply with any of the material terms or conditions of this Agreement and does 861 | not cure such failure in a reasonable period of time after becoming aware of 862 | such noncompliance. If all Recipient's rights under this Agreement terminate, 863 | Recipient agrees to cease use and distribution of the Program as soon as 864 | reasonably practicable. However, Recipient's obligations under this Agreement 865 | and any licenses granted by Recipient relating to the Program shall continue 866 | and survive. 867 | 868 | Everyone is permitted to copy and distribute copies of this Agreement, but in 869 | order to avoid inconsistency the Agreement is copyrighted and may only be 870 | modified in the following manner. The Agreement Steward reserves the right to 871 | publish new versions (including revisions) of this Agreement from time to time. 872 | No one other than the Agreement Steward has the right to modify this Agreement. 873 | The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation 874 | may assign the responsibility to serve as the Agreement Steward to a suitable 875 | separate entity. Each new version of the Agreement will be given a 876 | distinguishing version number. The Program (including Contributions) may always 877 | be Distributed subject to the version of the Agreement under which it was 878 | received. In addition, after a new version of the Agreement is published, 879 | Contributor may elect to Distribute the Program (including its Contributions) 880 | under the new version. 881 | 882 | Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives 883 | no rights or licenses to the intellectual property of any Contributor under 884 | this Agreement, whether expressly, by implication, estoppel or otherwise. All 885 | rights in the Program not expressly granted under this Agreement are reserved. 886 | Nothing in this Agreement is intended to be enforceable by any entity that is 887 | not a Contributor or Recipient. No third-party beneficiary rights are created 888 | under this Agreement. 889 | 890 | #### Exhibit A - Form of Secondary Licenses Notice 891 | 892 | > “This Source Code may also be made available under the following Secondary 893 | Licenses when the conditions for such availability set forth in the Eclipse 894 | Public License, v. 2.0 are satisfied: {name license(s), version(s), and 895 | exceptions or additional permissions here}.” 896 | 897 | Simply including a copy of this Agreement, including this Exhibit A is not 898 | sufficient to license the Source Code under Secondary Licenses. 899 | 900 | If it is not possible or desirable to put the notice in a particular file, then 901 | You may include the notice in a location (such as a LICENSE file in a relevant 902 | directory) where a recipient would be likely to look for such a notice. 903 | 904 | You may add additional accurate notices of copyright ownership. -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | apply plugin: 'java' 3 | apply plugin: 'maven-publish' 4 | apply plugin: 'signing' 5 | 6 | group = 'com.amazonaws' 7 | version = '0.1.0-SNAPSHOT' 8 | sourceCompatibility = '8' 9 | 10 | ext.isReleaseVersion = !version.endsWith('SNAPSHOT') 11 | 12 | repositories { 13 | mavenCentral() 14 | } 15 | 16 | java { 17 | withJavadocJar() 18 | } 19 | 20 | javadoc { 21 | def javaApiDocLink = [ 22 | (JavaVersion.VERSION_1_8): 'https://docs.oracle.com/javase/8/docs/api', 23 | (JavaVersion.VERSION_11): 'https://docs.oracle.com/en/java/javase/11/docs/api' 24 | ] 25 | 26 | source = sourceSets.main.allJava 27 | classpath = sourceSets.main.runtimeClasspath 28 | options.links = [javaApiDocLink.get(JavaVersion.current())] 29 | options.encoding = 'UTF-8' 30 | } 31 | 32 | test { 33 | useJUnitPlatform() 34 | } 35 | 36 | publishing { 37 | publications { 38 | release(MavenPublication) { 39 | repositories { 40 | maven { 41 | name = 'sonatype' 42 | url = isReleaseVersion ? 'https://aws.oss.sonatype.org/service/local/staging/deploy/maven2/' : 'https://aws.oss.sonatype.org/content/repositories/snapshots/' 43 | credentials { 44 | username findProperty('sonatypeUsername') 45 | password findProperty('sonatypePassword') 46 | } 47 | } 48 | } 49 | pom { 50 | name = project.name 51 | description = project.description 52 | licenses { 53 | license { 54 | name = 'The Apache License, Version 2.0' 55 | url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 56 | } 57 | } 58 | developers { 59 | developer { 60 | id = 'amazonwebservices' 61 | name = 'Amazon Web Services' 62 | url = 'https://aws.amazon.com' 63 | } 64 | } 65 | scm { 66 | connection = 'scm:git:https://github.com/awslabs/aws-xray-sdk-with-opentelemetry.git' 67 | developerConnection = 'scm:git:git@github.com:awslabs/aws-xray-sdk-with-opentelemetry.git' 68 | url = 'https://github.com/awslabs/aws-xray-sdk-with-opentelemetry' 69 | } 70 | } 71 | from(components.java) 72 | } 73 | } 74 | } 75 | 76 | tasks.withType(JavaCompile) { 77 | options.encoding = 'UTF-8' 78 | } 79 | 80 | signing { 81 | required { isReleaseVersion } 82 | 83 | //https://github.com/gradle/gradle/issues/11387 84 | if (required) { 85 | useInMemoryPgpKeys(findProperty('signingKey'), findProperty('signingPassword')) 86 | sign publishing.publications.release 87 | } 88 | } 89 | } 90 | 91 | defaultTasks 'build' 92 | 93 | wrapper { 94 | gradleVersion = '6.0' 95 | } 96 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awslabs/aws-xray-sdk-with-opentelemetry/89f941af2b32844652c190b79328f9f783fe60f8/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Nov 23 17:43:23 PST 2019 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /sdk/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'AWS X-Ray Java SDK with support for OpenTelemetry APIs' 2 | 3 | dependencies { 4 | implementation 'io.opentelemetry:opentelemetry-api:0.2.0' 5 | implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-core:2.4.0' 6 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1' 7 | testImplementation 'org.mockito:mockito-junit-jupiter:3.1.0' 8 | testImplementation 'org.mockito:mockito-core:3.1.0' 9 | testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1' 10 | } 11 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/EntitySpan.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing; 2 | 3 | import com.amazonaws.xray.AWSXRayRecorder; 4 | import com.amazonaws.xray.entities.DummySegment; 5 | import com.amazonaws.xray.entities.Entity; 6 | import com.amazonaws.xray.entities.Segment; 7 | import com.amazonaws.xray.entities.Subsegment; 8 | import com.amazonaws.xray.entities.TraceID; 9 | import com.amazonaws.xray.opentelemetry.tracing.metadata.EntityMetadata; 10 | import com.amazonaws.xray.opentelemetry.tracing.metadata.EntityMetadataEvent; 11 | import com.amazonaws.xray.opentelemetry.tracing.metadata.EntityMetadataFactory; 12 | import com.amazonaws.xray.opentelemetry.tracing.utils.ContextUtils; 13 | import com.amazonaws.xray.opentelemetry.tracing.utils.TimeUtils; 14 | import io.opentelemetry.trace.AttributeValue; 15 | import io.opentelemetry.trace.EndSpanOptions; 16 | import io.opentelemetry.trace.Event; 17 | import io.opentelemetry.trace.Span; 18 | import io.opentelemetry.trace.SpanContext; 19 | import io.opentelemetry.trace.Status; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | import org.apache.commons.logging.Log; 23 | import org.apache.commons.logging.LogFactory; 24 | 25 | /** 26 | * Adapter between the OpenTelemetry Span API and X-Ray Entities. 27 | * 28 | * @param the type of entity 29 | * @see io.opentelemetry.trace.Span 30 | */ 31 | public class EntitySpan implements Span { 32 | 33 | private static final Log logger = LogFactory.getLog(EntitySpan.class); 34 | 35 | private final T entity; 36 | private final EntityMetadata metadata; 37 | private SpanContext context; 38 | 39 | private EntitySpan(final T entity, final Span.Kind kind) { 40 | this.entity = entity; 41 | this.metadata = EntityMetadataFactory.getOrCreate(entity, kind); 42 | } 43 | 44 | /** 45 | * Begin a span backed by a segment without updating the active Entity in the X-Ray recorder. 46 | * 47 | * @param recorder create the span against this recorder 48 | * @param name the span's name 49 | * @param startTimestamp start time in nanoseconds 50 | * @param kind the OpenTelemetry span kind 51 | * @return the span 52 | */ 53 | public static EntitySpan beginSegment(final AWSXRayRecorder recorder, 54 | final String name, 55 | final long startTimestamp, 56 | final Span.Kind kind) { 57 | 58 | Entity currentEntity = recorder.getTraceEntity(); 59 | Segment newSegment = recorder.beginSegment(name); 60 | if (currentEntity == null) { 61 | recorder.clearTraceEntity(); 62 | } else { 63 | recorder.setTraceEntity(currentEntity); 64 | } 65 | 66 | newSegment.setStartTime(TimeUtils.nanoTimeToXrayTimestamp(startTimestamp)); 67 | return fromEntity(newSegment, kind); 68 | } 69 | 70 | /** 71 | * Begin a span backed by a subsegment without updating the active Entity in the X-Ray recorder. 72 | * 73 | * @param recorder create the span against this recorder 74 | * @param name the span's name 75 | * @param parent the parent span 76 | * @param startTimestamp start time in nanoseconds 77 | * @param kind the OpenTelemetry span kind 78 | * @return the span 79 | */ 80 | public static EntitySpan beginSubsegment(final AWSXRayRecorder recorder, 81 | final String name, 82 | final EntitySpan parent, 83 | final long startTimestamp, 84 | final Span.Kind kind) { 85 | Entity currentEntity = recorder.getTraceEntity(); 86 | recorder.setTraceEntity(parent.getXrayEntity()); 87 | 88 | Subsegment newSubsegment = recorder.beginSubsegment(name); 89 | newSubsegment.setStartTime(TimeUtils.nanoTimeToXrayTimestamp(startTimestamp)); 90 | 91 | if (currentEntity == null) { 92 | recorder.clearTraceEntity(); 93 | } else { 94 | recorder.setTraceEntity(currentEntity); 95 | } 96 | 97 | return fromEntity(newSubsegment, kind); 98 | } 99 | 100 | /** 101 | * Begin a span backed by a dummy segment. 102 | * 103 | * @param recorder create the span against this recorders 104 | * @param startTimestamp start time in nanoseconds 105 | * @param kind the OpenTelemetry span kind 106 | * @return the span 107 | */ 108 | public static EntitySpan beginDummySegment(final AWSXRayRecorder recorder, 109 | final long startTimestamp, 110 | final Span.Kind kind) { 111 | DummySegment dummySegment = new DummySegment(recorder, new TraceID()); 112 | dummySegment.setStartTime(TimeUtils.nanoTimeToXrayTimestamp(startTimestamp)); 113 | return fromEntity(dummySegment, kind); 114 | } 115 | 116 | /** 117 | * Create a span from the provided entity with the default INTERNAL kind. 118 | * 119 | * @param entity the entity which backs the span 120 | * @return the span 121 | */ 122 | public static EntitySpan fromEntity(final Entity entity) { 123 | return fromEntity(entity, Kind.INTERNAL); 124 | } 125 | 126 | /** 127 | * Create a span from the provided entity with the specified kind. 128 | * 129 | * @param entity the entity which backs the span 130 | * @param kind the kind of span 131 | * @return the span 132 | */ 133 | public static EntitySpan fromEntity(final Entity entity, final Span.Kind kind) { 134 | return new EntitySpan<>(entity, kind); 135 | } 136 | 137 | @Override 138 | public void setAttribute(final String key, final String value) { 139 | setAttributeMetadata(key, value); 140 | } 141 | 142 | @Override 143 | public void setAttribute(final String key, final long value) { 144 | setAttributeMetadata(key, value); 145 | } 146 | 147 | @Override 148 | public void setAttribute(final String key, final double value) { 149 | setAttributeMetadata(key, value); 150 | } 151 | 152 | @Override 153 | public void setAttribute(final String key, final boolean value) { 154 | setAttributeMetadata(key, value); 155 | } 156 | 157 | @Override 158 | public void setAttribute(final String key, final AttributeValue value) { 159 | if (AttributeValue.Type.BOOLEAN.equals(value.getType())) { 160 | setAttributeMetadata(key, value.getBooleanValue()); 161 | } 162 | 163 | if (AttributeValue.Type.DOUBLE.equals(value.getType())) { 164 | setAttributeMetadata(key, value.getDoubleValue()); 165 | } 166 | 167 | if (AttributeValue.Type.STRING.equals(value.getType())) { 168 | setAttributeMetadata(key, value.getStringValue()); 169 | } 170 | 171 | if (AttributeValue.Type.LONG.equals(value.getType())) { 172 | setAttributeMetadata(key, value.getLongValue()); 173 | } 174 | } 175 | 176 | private void setAttributeMetadata(final String key, final Object value) { 177 | switch (key) { 178 | case "http.method": 179 | if (value instanceof String) { 180 | putHttpAttribute("request","method", value); 181 | } 182 | break; 183 | case "http.status_code": 184 | if (value instanceof Long) { 185 | putHttpAttribute("response","status", value); 186 | } 187 | break; 188 | case "http.url": 189 | if (value instanceof String) { 190 | putHttpAttribute("request","url", value); 191 | } 192 | break; 193 | default: 194 | break; 195 | } 196 | 197 | metadata.putAttribute(key, value); 198 | } 199 | 200 | private void putHttpAttribute(final String section, final String key, final Object value) { 201 | Map http = entity.getHttp(); 202 | 203 | @SuppressWarnings(value = "unchecked") 204 | Map sectionMap; 205 | 206 | if (http.containsKey(section) && http.get(section) instanceof Map) { 207 | sectionMap = (Map) http.get(section); 208 | } else { 209 | sectionMap = new HashMap<>(); 210 | entity.putHttp(section, sectionMap); 211 | } 212 | 213 | sectionMap.put(key, value); 214 | } 215 | 216 | @Override 217 | public void addEvent(final String name) { 218 | if (isRecording()) { 219 | metadata.addEvent(EntityMetadataEvent.create(name)); 220 | } 221 | } 222 | 223 | @Override 224 | public void addEvent(final String name, final long timestamp) { 225 | if (isRecording()) { 226 | metadata.addEvent(EntityMetadataEvent.create(name, timestamp)); 227 | } 228 | } 229 | 230 | @Override 231 | public void addEvent(final String name, final Map attributes) { 232 | if (isRecording()) { 233 | metadata.addEvent(EntityMetadataEvent.create(name, attributes)); 234 | } 235 | } 236 | 237 | @Override 238 | public void addEvent(final String name, final Map attributes, 239 | final long timestamp) { 240 | if (isRecording()) { 241 | metadata.addEvent(EntityMetadataEvent.create(name, attributes, timestamp)); 242 | } 243 | } 244 | 245 | @Override 246 | public void addEvent(final Event event) { 247 | if (isRecording()) { 248 | metadata.addEvent(EntityMetadataEvent.create(event)); 249 | } 250 | } 251 | 252 | @Override 253 | public void addEvent(final Event event, final long timestamp) { 254 | if (isRecording()) { 255 | metadata.addEvent(EntityMetadataEvent.create(event, timestamp)); 256 | } 257 | } 258 | 259 | @Override 260 | public void setStatus(final Status status) { 261 | metadata.setStatus(status); 262 | } 263 | 264 | @Override 265 | public void updateName(final String name) { 266 | //Unsupported 267 | } 268 | 269 | @Override 270 | public void end() { 271 | if (isRecording()) { 272 | if (entity.getEndTime() == 0) { 273 | entity.setEndTime(TimeUtils.currentXrayNanoTimestamp()); 274 | } 275 | 276 | AWSXRayRecorder recorder = entity.getCreator(); 277 | Entity previous = recorder.getTraceEntity(); 278 | recorder.setTraceEntity(entity); 279 | 280 | if (entity instanceof Segment) { 281 | recorder.endSegment(); 282 | } else if (entity instanceof Subsegment) { 283 | recorder.endSubsegment(); 284 | } 285 | if (!entity.equals(previous)) { 286 | recorder.setTraceEntity(previous); 287 | } 288 | } 289 | } 290 | 291 | @Override 292 | public void end(final EndSpanOptions endOptions) { 293 | if (endOptions != null) { 294 | long endTime = endOptions.getEndTimestamp(); 295 | //EndTime values are in nanoseconds 296 | entity.setEndTime(TimeUtils.nanoTimeToXrayTimestamp(endTime)); 297 | } 298 | end(); 299 | } 300 | 301 | @Override 302 | public SpanContext getContext() { 303 | if (context == null) { 304 | context = ContextUtils.entityToSpanContext(entity); 305 | } 306 | return context; 307 | } 308 | 309 | @Override 310 | public boolean isRecording() { 311 | return entity.isInProgress(); 312 | } 313 | 314 | public Entity getXrayEntity() { 315 | return entity; 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/EntitySpanBuilder.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing; 2 | 3 | import com.amazonaws.xray.AWSXRayRecorder; 4 | import com.amazonaws.xray.opentelemetry.tracing.utils.TimeUtils; 5 | import io.opentelemetry.trace.AttributeValue; 6 | import io.opentelemetry.trace.Link; 7 | import io.opentelemetry.trace.Span; 8 | import io.opentelemetry.trace.SpanContext; 9 | import java.time.Instant; 10 | import java.util.Map; 11 | 12 | /** 13 | * A builder class which creates spans against a given X-Ray recorder. 14 | * 15 | * @see io.opentelemetry.trace.Span.Builder 16 | */ 17 | public class EntitySpanBuilder implements Span.Builder { 18 | 19 | 20 | 21 | private final AWSXRayRecorder recorder; 22 | private final String name; 23 | 24 | private SpanContext parentContext; 25 | private Span parentSpan; 26 | private Span.Kind kind = Span.Kind.INTERNAL; 27 | private long startTimestamp; 28 | 29 | private EntitySpanBuilder(final String name, final AWSXRayRecorder recorder, 30 | final Span currentSpan) { 31 | this.name = name; 32 | this.recorder = recorder; 33 | this.parentSpan = currentSpan; 34 | } 35 | 36 | /** 37 | * Create a factory using the given recorder. 38 | * 39 | * @param name the name of the span to create 40 | * @param recorder the recorder to use 41 | * @param currentSpan the current span or null 42 | * @return the builder 43 | */ 44 | public static EntitySpanBuilder create(final String name, final AWSXRayRecorder recorder, 45 | final Span currentSpan) { 46 | return new EntitySpanBuilder(name, recorder, currentSpan); 47 | } 48 | 49 | @Override 50 | public Span.Builder setParent(final Span span) { 51 | this.parentSpan = span; 52 | this.parentContext = null; 53 | return this; 54 | } 55 | 56 | @Override 57 | public Span.Builder setParent(final SpanContext spanContext) { 58 | this.parentContext = spanContext; 59 | this.parentSpan = null; 60 | return this; 61 | } 62 | 63 | @Override 64 | public Span.Builder setNoParent() { 65 | parentContext = null; 66 | parentSpan = null; 67 | return this; 68 | } 69 | 70 | /* 71 | * Segment linking is not supported by X-Ray 72 | */ 73 | @Override 74 | public Span.Builder addLink(final SpanContext spanContext) { 75 | return this; 76 | } 77 | 78 | @Override 79 | public Span.Builder addLink(final SpanContext spanContext, 80 | final Map map) { 81 | return this; 82 | } 83 | 84 | @Override 85 | public Span.Builder addLink(final Link link) { 86 | return this; 87 | } 88 | 89 | @Override 90 | public Span.Builder setSpanKind(final Span.Kind kind) { 91 | this.kind = kind; 92 | return this; 93 | } 94 | 95 | @Override 96 | public Span.Builder setStartTimestamp(final long startTimestamp) { 97 | this.startTimestamp = startTimestamp; 98 | return this; 99 | } 100 | 101 | @Override 102 | public Span startSpan() { 103 | if (startTimestamp == 0) { 104 | startTimestamp = TimeUtils.getCurrentNanoTime(); 105 | } 106 | 107 | if (parentContext != null || parentSpan == null) { 108 | return EntitySpan.beginSegment(recorder, name, startTimestamp, kind); 109 | } else { 110 | return EntitySpan 111 | .beginSubsegment(recorder, name, (EntitySpan) parentSpan, startTimestamp, kind); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/RecorderBackedTracer.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing; 2 | 3 | import com.amazonaws.xray.AWSXRayRecorder; 4 | import com.amazonaws.xray.entities.Entity; 5 | import com.amazonaws.xray.opentelemetry.tracing.propagation.HttpTraceContext; 6 | import io.opentelemetry.context.Scope; 7 | import io.opentelemetry.context.propagation.BinaryFormat; 8 | import io.opentelemetry.context.propagation.HttpTextFormat; 9 | import io.opentelemetry.trace.DefaultSpan; 10 | import io.opentelemetry.trace.Span; 11 | import io.opentelemetry.trace.SpanContext; 12 | import io.opentelemetry.trace.Tracer; 13 | 14 | /** 15 | * A tracer backed by an AWS X-Ray recorder. 16 | * 17 | * @see io.opentelemetry.trace.Tracer 18 | */ 19 | public class RecorderBackedTracer implements Tracer { 20 | 21 | private static final HttpTraceContext HTTP_TRACE_CONTEXT = new HttpTraceContext(); 22 | private AWSXRayRecorder recorder; 23 | private Span currentSpan = null; 24 | private Entity currentEntity = null; 25 | 26 | private RecorderBackedTracer(AWSXRayRecorder recorder) { 27 | this.recorder = recorder; 28 | } 29 | 30 | /** 31 | * Create a tracer using a given recorder. 32 | * 33 | * @param recorder the recorder 34 | * @return a tracer 35 | */ 36 | public static RecorderBackedTracer fromRecorder(AWSXRayRecorder recorder) { 37 | return new RecorderBackedTracer(recorder); 38 | } 39 | 40 | /** 41 | * {@inheritDoc} This implementation will automatically update the active span based on changes to 42 | * the X-Ray recorder but otherwise conforms to OpenTelemetry semantics when creating spans. 43 | */ 44 | @Override 45 | public Span getCurrentSpan() { 46 | if (currentSpan == null && recorder.getTraceEntity() == null) { 47 | return DefaultSpan.getInvalid(); 48 | } else { 49 | //Reflect the recorder's current entity changing in response to X-Ray calls 50 | Entity recorderCurrentEntity = recorder.getTraceEntity(); 51 | if (recorderCurrentEntity != null && !recorderCurrentEntity.equals(currentEntity)) { 52 | currentEntity = recorderCurrentEntity; 53 | currentSpan = EntitySpan.fromEntity(currentEntity); 54 | } 55 | } 56 | return currentSpan; 57 | } 58 | 59 | @Override 60 | public Scope withSpan(final Span span) { 61 | if (span instanceof EntitySpan) { 62 | final EntitySpan adapter = (EntitySpan) span; 63 | currentSpan = span; 64 | recorder.setTraceEntity(adapter.getXrayEntity()); 65 | } 66 | 67 | //Just a rough implementation. There's some talk of separating scope management from 68 | //existing gRPC influenced deps. Need to better integrate this and X-Ray Recorder's 69 | //scope management. 70 | return new Scope() { 71 | @Override 72 | public void close() { 73 | } 74 | }; 75 | } 76 | 77 | @Override 78 | public Span.Builder spanBuilder(final String name) { 79 | return EntitySpanBuilder.create(name, recorder, getCurrentSpan()); 80 | } 81 | 82 | @Override 83 | public BinaryFormat getBinaryFormat() { 84 | return null; 85 | } 86 | 87 | @Override 88 | public HttpTextFormat getHttpTextFormat() { 89 | return HTTP_TRACE_CONTEXT; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/RecorderBackedTracerFactory.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing; 2 | 3 | import com.amazonaws.xray.AWSXRay; 4 | import com.amazonaws.xray.AWSXRayRecorder; 5 | import io.opentelemetry.trace.Tracer; 6 | import io.opentelemetry.trace.TracerFactory; 7 | 8 | /** 9 | * A factory for creating RecorderBackedTracers. 10 | * 11 | * @see io.opentelemetry.trace.Tracer 12 | */ 13 | public class RecorderBackedTracerFactory implements TracerFactory { 14 | 15 | private final AWSXRayRecorder recorder; 16 | private RecorderBackedTracer tracer = null; 17 | 18 | private RecorderBackedTracerFactory(AWSXRayRecorder recorder) { 19 | this.recorder = recorder; 20 | } 21 | 22 | /** 23 | * Create a new tracer factory. 24 | * 25 | * @return the factory 26 | */ 27 | public static final RecorderBackedTracerFactory create() { 28 | return new RecorderBackedTracerFactory(AWSXRay.getGlobalRecorder()); 29 | } 30 | 31 | @Override 32 | public Tracer get(final String instrumentationName) { 33 | return get(instrumentationName, null); 34 | } 35 | 36 | @Override 37 | public Tracer get(final String instrumentationName, final String instrumentationVersion) { 38 | if (tracer == null) { 39 | synchronized (this) { 40 | if (tracer == null) { 41 | tracer = RecorderBackedTracer.fromRecorder(recorder); 42 | } 43 | } 44 | } 45 | 46 | return tracer; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/TracingProvider.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing; 2 | 3 | import io.opentelemetry.trace.TracerFactory; 4 | import io.opentelemetry.trace.spi.TracerFactoryProvider; 5 | 6 | /** 7 | * SPI implementation for making this SDK available via OpenTelemetry. 8 | * 9 | * @see io.opentelemetry.OpenTelemetry 10 | */ 11 | public class TracingProvider implements TracerFactoryProvider { 12 | 13 | @Override 14 | public TracerFactory create() { 15 | return RecorderBackedTracerFactory.create(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/metadata/EntityMetadata.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.metadata; 2 | 3 | import io.opentelemetry.trace.Span.Kind; 4 | import io.opentelemetry.trace.Status; 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | public class EntityMetadata { 12 | 13 | private final List events; 14 | private final Map attributes; 15 | private final Kind kind; 16 | private Status status; 17 | 18 | public static EntityMetadata create(final Kind kind) { 19 | return new EntityMetadata(kind); 20 | } 21 | 22 | private EntityMetadata(final Kind kind) { 23 | this.kind = kind; 24 | events = new ArrayList<>(); 25 | attributes = new ConcurrentHashMap<>(); 26 | status = Status.OK; 27 | } 28 | 29 | public void setStatus(final Status status) { 30 | this.status = status; 31 | } 32 | 33 | public void putAttribute(final String name, final Object value) { 34 | attributes.put(name, value); 35 | } 36 | 37 | public void addEvent(final EntityMetadataEvent event) { 38 | events.add(event); 39 | Collections.sort(events); 40 | } 41 | 42 | public Status getStatus() { 43 | return status; 44 | } 45 | 46 | public Map getAttributes() { 47 | return attributes; 48 | } 49 | 50 | public Kind getKind() { 51 | return kind; 52 | } 53 | 54 | public List getEvents() { 55 | return events; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/metadata/EntityMetadataEvent.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.metadata; 2 | 3 | import com.amazonaws.xray.opentelemetry.tracing.serializers.EntityMetadataEventSerializer; 4 | import com.amazonaws.xray.opentelemetry.tracing.utils.TimeUtils; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import io.opentelemetry.trace.AttributeValue; 7 | import io.opentelemetry.trace.Event; 8 | import java.util.Collections; 9 | import java.util.Map; 10 | 11 | @JsonSerialize(using = EntityMetadataEventSerializer.class) 12 | public class EntityMetadataEvent implements Event, Comparable { 13 | private String name; 14 | private Map attributes; 15 | private long timestamp; 16 | 17 | public static EntityMetadataEvent create(final String name) { 18 | return new EntityMetadataEvent(name, 19 | Collections.unmodifiableMap(Collections.emptyMap()), TimeUtils.getCurrentNanoTime()); 20 | } 21 | 22 | public static EntityMetadataEvent create(final String name, 23 | final Map attributes) { 24 | return new EntityMetadataEvent(name, attributes, TimeUtils.getCurrentNanoTime()); 25 | } 26 | 27 | public static EntityMetadataEvent create(final String name, final long timestamp) { 28 | return new EntityMetadataEvent(name, 29 | Collections.unmodifiableMap(Collections.emptyMap()), timestamp); 30 | } 31 | 32 | public static EntityMetadataEvent create(final String name, 33 | final Map attributes, final long timestamp) { 34 | return new EntityMetadataEvent(name, attributes, timestamp); 35 | } 36 | 37 | public static EntityMetadataEvent create(final Event event) { 38 | return new EntityMetadataEvent(event.getName(), event.getAttributes(), 39 | TimeUtils.getCurrentNanoTime()); 40 | } 41 | 42 | public static EntityMetadataEvent create(final Event event, final long timestamp) { 43 | return new EntityMetadataEvent(event.getName(), event.getAttributes(), timestamp); 44 | } 45 | 46 | private EntityMetadataEvent(final String name, final Map attributes, 47 | final long timestamp) { 48 | this.attributes = attributes; 49 | this.name = name; 50 | this.timestamp = timestamp; 51 | } 52 | 53 | @Override 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | @Override 59 | public Map getAttributes() { 60 | return attributes; 61 | } 62 | 63 | @Override 64 | public int compareTo(EntityMetadataEvent o) { 65 | return Long.compare(timestamp, o.timestamp); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/metadata/EntityMetadataFactory.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.metadata; 2 | 3 | import com.amazonaws.xray.entities.Entity; 4 | import io.opentelemetry.trace.Span; 5 | import java.util.Map; 6 | 7 | public class EntityMetadataFactory { 8 | 9 | private static final String OT_METADATA_NAMESPACE = "sdk"; 10 | private static final String OT_METADATA_KEY = "open_telemetry"; 11 | 12 | /** 13 | * Return metadata from an Entity initializing it if it isn't already. 14 | * @param entity the entity 15 | * @param kind the kind to use if initializing new metadata 16 | * @return the metadata 17 | */ 18 | public static EntityMetadata getOrCreate(final Entity entity, final Span.Kind kind) { 19 | 20 | Map otNamespace = entity.getMetadata().get(OT_METADATA_NAMESPACE); 21 | Object otMetadataObject = null; 22 | if (otNamespace != null) { 23 | otMetadataObject = otNamespace.get(OT_METADATA_KEY); 24 | } 25 | 26 | if (otMetadataObject instanceof EntityMetadata) { 27 | return (EntityMetadata) otMetadataObject; 28 | } else { 29 | EntityMetadata metadata = EntityMetadata.create(kind); 30 | entity.putMetadata(OT_METADATA_NAMESPACE, OT_METADATA_KEY, metadata); 31 | return metadata; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/propagation/HttpTraceContext.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.propagation; 2 | 3 | import com.amazonaws.xray.entities.TraceHeader; 4 | import com.amazonaws.xray.opentelemetry.tracing.utils.ContextUtils; 5 | import io.opentelemetry.context.propagation.HttpTextFormat; 6 | import io.opentelemetry.trace.SpanContext; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | /** 11 | * Propagate trace ID information via X-Ray Headers. 12 | * 13 | * @see io.opentelemetry.context.propagation.HttpTextFormat 14 | */ 15 | public class HttpTraceContext implements HttpTextFormat { 16 | 17 | public static final String XRAY_HEADER_NAME = TraceHeader.HEADER_KEY; 18 | public static final List FIELDS = Collections.singletonList(XRAY_HEADER_NAME); 19 | public static final io.opentelemetry.trace.propagation.HttpTraceContext OT_TRACE_CONTEXT 20 | = new io.opentelemetry.trace.propagation.HttpTraceContext(); 21 | 22 | @Override 23 | public List fields() { 24 | return FIELDS; 25 | } 26 | 27 | @Override 28 | //TODO - Also emit w3c headers 29 | public void inject(final SpanContext value, final C carrier, final Setter setter) { 30 | setter.put(carrier, XRAY_HEADER_NAME, ContextUtils.spanContextToHeader(value).toString()); 31 | } 32 | 33 | @Override 34 | //TODO - Accept w3c headers 35 | public SpanContext extract(final C carrier, final Getter getter) { 36 | String xrayHeader = getter.get(carrier, XRAY_HEADER_NAME); 37 | if (xrayHeader != null) { 38 | return ContextUtils.headerToSpanContext(TraceHeader.fromString(xrayHeader)); 39 | } else { 40 | throw new RuntimeException("Could not extract X-Ray Trace Header."); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/serializers/EntityMetadataEventSerializer.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.serializers; 2 | 3 | import com.amazonaws.xray.opentelemetry.tracing.metadata.EntityMetadataEvent; 4 | import com.fasterxml.jackson.core.JsonGenerator; 5 | import com.fasterxml.jackson.core.JsonProcessingException; 6 | import com.fasterxml.jackson.databind.SerializerProvider; 7 | import com.fasterxml.jackson.databind.ser.std.StdSerializer; 8 | import io.opentelemetry.trace.AttributeValue.Type; 9 | import java.io.IOException; 10 | 11 | 12 | public class EntityMetadataEventSerializer extends StdSerializer { 13 | 14 | 15 | public static final String NAME_FIELD = "name"; 16 | public static final String ATTRIBUTES_FIELD = "attributes"; 17 | public static final String TYPE_FIELD = "type"; 18 | public static final String VALUE_FIELD = "value"; 19 | 20 | public EntityMetadataEventSerializer() { 21 | this(null); 22 | } 23 | 24 | public EntityMetadataEventSerializer(final Class t) { 25 | super(t); 26 | } 27 | 28 | /** 29 | * Serialize an EntityMetadataEvent into JSON with correct handling of AttributeValues. 30 | * @param value the value to serialize 31 | * @param gen the JSON generator 32 | * @param provider the JSON provider 33 | * @throws IOException when an IO error occurs 34 | * @throws JsonProcessingException when a JSON processing error occurs 35 | */ 36 | public void serialize(final EntityMetadataEvent value, 37 | final JsonGenerator gen, 38 | final SerializerProvider provider) 39 | throws IOException, JsonProcessingException { 40 | 41 | gen.writeStartObject(); 42 | gen.writeObjectField(NAME_FIELD, value.getName()); 43 | gen.writeObjectFieldStart(ATTRIBUTES_FIELD); 44 | value.getAttributes().forEach((s, attributeValue) -> { 45 | try { 46 | gen.writeObjectFieldStart(s); 47 | gen.writeStringField(TYPE_FIELD, attributeValue.getType().toString()); 48 | 49 | /* 50 | * Jackson attempts to treat AttributeValue as a POJO 51 | * Calling the wrong-type of getValue() throws exceptions 52 | */ 53 | if (attributeValue.getType() == Type.BOOLEAN) { 54 | gen.writeBooleanField(VALUE_FIELD, attributeValue.getBooleanValue()); 55 | } else if (attributeValue.getType() == Type.LONG) { 56 | gen.writeNumberField(VALUE_FIELD, attributeValue.getLongValue()); 57 | } else if (attributeValue.getType() == Type.DOUBLE) { 58 | gen.writeNumberField(VALUE_FIELD, attributeValue.getDoubleValue()); 59 | } else if (attributeValue.getType() == Type.STRING) { 60 | gen.writeStringField(VALUE_FIELD, attributeValue.getStringValue()); 61 | } 62 | 63 | gen.writeEndObject(); 64 | } catch (IOException e) { 65 | throw new RuntimeException(e); 66 | } 67 | }); 68 | gen.writeEndObject(); 69 | gen.writeEndObject(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/utils/ContextUtils.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.utils; 2 | 3 | import com.amazonaws.xray.entities.Entity; 4 | import com.amazonaws.xray.entities.Segment; 5 | import com.amazonaws.xray.entities.TraceHeader; 6 | import com.amazonaws.xray.entities.TraceID; 7 | import io.opentelemetry.trace.SpanContext; 8 | import io.opentelemetry.trace.SpanId; 9 | import io.opentelemetry.trace.TraceFlags; 10 | import io.opentelemetry.trace.TraceId; 11 | import io.opentelemetry.trace.Tracestate; 12 | 13 | public class ContextUtils { 14 | 15 | private static final String XRAY_VERSION_PREFIX = "1-"; 16 | private static final String XRAY_SEPARATOR = "-"; 17 | 18 | 19 | /** 20 | * Convert an Entity into a SpanContext, preserving the Entity's Trace and Segment IDs. 21 | * @param entity the entity 22 | * @return a SpanContext 23 | */ 24 | public static SpanContext entityToSpanContext(final Entity entity) { 25 | TraceId traceId = TraceId 26 | .fromLowerBase16(xrayTraceIdToOT(entity.getParentSegment().getTraceId().toString()), 0); 27 | SpanId spanId = SpanId.fromLowerBase16(entity.getId(), 0); 28 | TraceFlags flags = TraceFlags.builder() 29 | .setIsSampled(entity.getParentSegment().isSampled()) 30 | .build(); 31 | Tracestate state = Tracestate.getDefault(); 32 | 33 | //Segments with a parent ID are usually remote 34 | if (entity instanceof Segment && entity.getParentId() != null) { 35 | return SpanContext.createFromRemoteParent(traceId, spanId, flags, state); 36 | } else { 37 | return SpanContext.create(traceId, spanId, flags, state); 38 | } 39 | } 40 | 41 | /** 42 | * Convert an X-Amzn-Trace-Id HTTP header into a SpanContext, preserving the provided IDs. 43 | * @param header the TraceHeader 44 | * @return a SpanContext 45 | */ 46 | public static SpanContext headerToSpanContext(final TraceHeader header) { 47 | TraceId traceId = TraceId 48 | .fromLowerBase16(xrayTraceIdToOT(header.getRootTraceId().toString()), 0); 49 | SpanId spanId = SpanId.fromLowerBase16(header.getParentId().toLowerCase(), 0); 50 | TraceFlags flags = TraceFlags.builder() 51 | .setIsSampled(header.getSampled().equals(TraceHeader.SampleDecision.SAMPLED) 52 | || header.getSampled().equals(TraceHeader.SampleDecision.REQUESTED)) 53 | .build(); 54 | Tracestate state = Tracestate.getDefault(); 55 | return SpanContext.createFromRemoteParent(traceId, spanId, flags, state); 56 | } 57 | 58 | /** 59 | * Convert a SpanContext into an X-Amzn-Trace-Id HTTP header. 60 | * @param context the SpanContext 61 | * @return a TraceHeader 62 | */ 63 | public static TraceHeader spanContextToHeader(final SpanContext context) { 64 | String otTraceId = context.getTraceId().toLowerBase16(); 65 | String xrayTraceId = 66 | XRAY_VERSION_PREFIX + otTraceId.substring(0, 8) + XRAY_SEPARATOR + otTraceId.substring(8); 67 | TraceID xrayId = TraceID.fromString(xrayTraceId); 68 | TraceHeader header = new TraceHeader(); 69 | header.setSampled(context.getTraceFlags().isSampled() 70 | ? TraceHeader.SampleDecision.SAMPLED : TraceHeader.SampleDecision.NOT_SAMPLED); 71 | header.setRootTraceId(xrayId); 72 | header.setParentId(context.getSpanId().toLowerBase16()); 73 | 74 | return header; 75 | } 76 | 77 | private static String xrayTraceIdToOT(String xrayId) { 78 | String otId = xrayId.substring(2).replaceAll("-", ""); 79 | return otId; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /sdk/src/main/java/com/amazonaws/xray/opentelemetry/tracing/utils/TimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.utils; 2 | 3 | import java.time.Instant; 4 | 5 | public class TimeUtils { 6 | 7 | private static final Long MS_TO_NS = 1000000L; 8 | private static final Double NS_TO_S = 1e+9D; 9 | 10 | /** 11 | * Return the current epoch time as a nanosecond Long. 12 | * @return the current time in epoch nanoseconds 13 | */ 14 | public static Long getCurrentNanoTime() { 15 | Instant now = Instant.now(); 16 | return (now.toEpochMilli() * MS_TO_NS) + now.getNano(); 17 | } 18 | 19 | /** 20 | * Convert a long containing epoch nanoseconds into a double containing seconds. 21 | * @param nanoTime the nanosecond epoch time 22 | * @return a double precision epoch second timestamp 23 | */ 24 | public static Double nanoTimeToXrayTimestamp(Long nanoTime) { 25 | return nanoTime / NS_TO_S; 26 | } 27 | 28 | /** 29 | * Return the current time with nanosecond resolution as a double containing epoch seconds. 30 | * @return the double precision epoch second timestamp with nanosecond resolution 31 | */ 32 | public static Double currentXrayNanoTimestamp() { 33 | return nanoTimeToXrayTimestamp(getCurrentNanoTime()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /sdk/src/main/resources/META-INF/services/io.opentelemetry.trace.spi.TracerFactoryProvider: -------------------------------------------------------------------------------- 1 | com.amazonaws.xray.opentelemetry.tracing.TracingProvider 2 | -------------------------------------------------------------------------------- /sdk/src/test/java/com/amazonaws/xray/opentelemetry/tracing/EntitySpanTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.mockito.ArgumentMatchers.any; 5 | import static org.mockito.ArgumentMatchers.eq; 6 | import static org.mockito.Mockito.anyString; 7 | import static org.mockito.Mockito.inOrder; 8 | import static org.mockito.Mockito.mock; 9 | import static org.mockito.Mockito.times; 10 | import static org.mockito.Mockito.verify; 11 | import static org.mockito.Mockito.when; 12 | 13 | import com.amazonaws.xray.AWSXRayRecorder; 14 | import com.amazonaws.xray.entities.Segment; 15 | import com.amazonaws.xray.entities.Subsegment; 16 | import io.opentelemetry.trace.Span; 17 | import java.util.Map; 18 | import org.junit.jupiter.api.Test; 19 | import org.junit.jupiter.api.extension.ExtendWith; 20 | import org.mockito.InOrder; 21 | import org.mockito.Mock; 22 | import org.mockito.junit.jupiter.MockitoExtension; 23 | 24 | @ExtendWith(MockitoExtension.class) 25 | public class EntitySpanTest { 26 | 27 | @Mock 28 | AWSXRayRecorder recorder; 29 | 30 | @Mock 31 | Segment segment; 32 | 33 | @Mock 34 | Subsegment subsegment; 35 | 36 | @Mock 37 | Segment previousSegment; 38 | 39 | @Test 40 | public void when_aSegmentIsCreatedAndEnded_then_theCurrentEntityIsPreserved() { 41 | when(recorder.beginSegment(anyString())).thenReturn(segment); 42 | when(recorder.getTraceEntity()).thenReturn(previousSegment); 43 | when(segment.getCreator()).thenReturn(recorder); 44 | when(segment.isInProgress()).thenReturn(true); 45 | 46 | Span testSpan = EntitySpan.beginSegment(recorder, "Test Span", 0, Span.Kind.INTERNAL); 47 | testSpan.end(); 48 | 49 | //Verify Order of Operations 50 | InOrder inOrder = inOrder(recorder); 51 | //Create new span 52 | inOrder.verify(recorder).getTraceEntity(); 53 | inOrder.verify(recorder).beginSegment(anyString()); 54 | inOrder.verify(recorder).setTraceEntity(previousSegment); 55 | 56 | //End span 57 | inOrder.verify(recorder).getTraceEntity(); 58 | inOrder.verify(recorder).setTraceEntity(segment); 59 | inOrder.verify(recorder).endSegment(); 60 | inOrder.verify(recorder).setTraceEntity(previousSegment); 61 | inOrder.verifyNoMoreInteractions(); 62 | } 63 | 64 | @Test 65 | public void when_aSegmentExists_then_aSubsegemtnIsCreated() { 66 | EntitySpan parentSpan = mock(EntitySpan.class); 67 | when(parentSpan.getXrayEntity()).thenReturn(segment); 68 | when(subsegment.getCreator()).thenReturn(recorder); 69 | when(recorder.getTraceEntity()).thenReturn(previousSegment); 70 | when(recorder.beginSubsegment(anyString())).thenReturn(subsegment); 71 | when(subsegment.isInProgress()).thenReturn(true); 72 | 73 | Span subsegmentSpan = EntitySpan 74 | .beginSubsegment(recorder, "Test Child", parentSpan, 0, Span.Kind.INTERNAL); 75 | subsegmentSpan.end(); 76 | 77 | //Verify Order of Operations 78 | InOrder inOrder = inOrder(recorder); 79 | //Create new subsegment 80 | inOrder.verify(recorder).getTraceEntity(); 81 | inOrder.verify(recorder).setTraceEntity(segment); 82 | inOrder.verify(recorder).beginSubsegment(anyString()); 83 | inOrder.verify(recorder).setTraceEntity(previousSegment); 84 | 85 | //End span 86 | inOrder.verify(recorder).getTraceEntity(); 87 | inOrder.verify(recorder).setTraceEntity(subsegment); 88 | inOrder.verify(recorder).endSubsegment(); 89 | inOrder.verify(recorder).setTraceEntity(previousSegment); 90 | inOrder.verifyNoMoreInteractions(); 91 | } 92 | 93 | @Test 94 | public void when_aSegmentHasHttpParams_then_segmentHasHttpBlock() { 95 | when(recorder.beginSegment(anyString())).thenReturn(segment); 96 | Span testSpan = EntitySpan.beginSegment(recorder, "Test Span", 0, Span.Kind.INTERNAL); 97 | testSpan.setAttribute("http.method", "GET"); 98 | testSpan.setAttribute("http.status_code", 200L); 99 | testSpan.setAttribute("http.url", "http://test.com"); 100 | testSpan.end(); 101 | 102 | verify(segment, times(2)).putHttp(eq("request"), any(Map.class)); 103 | verify(segment).putHttp(eq("response"), any(Map.class)); 104 | } 105 | 106 | @Test 107 | public void when_isRecordingCalled_then_isInProgressCalled() { 108 | when(recorder.beginSegment(anyString())).thenReturn(segment); 109 | when(segment.isInProgress()).thenReturn(false); 110 | Span testSpan = EntitySpan.beginSegment(recorder, "Test Span", 0, Span.Kind.INTERNAL); 111 | assertEquals(false, testSpan.isRecording()); 112 | } 113 | 114 | 115 | } 116 | -------------------------------------------------------------------------------- /sdk/src/test/java/com/amazonaws/xray/opentelemetry/tracing/metadata/EntityMetadataEventTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.metadata; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import com.fasterxml.jackson.core.JsonProcessingException; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | import io.opentelemetry.trace.AttributeValue; 8 | import java.util.Collections; 9 | import java.util.Map; 10 | import org.junit.jupiter.api.BeforeEach; 11 | import org.junit.jupiter.api.Test; 12 | 13 | public class EntityMetadataEventTest { 14 | 15 | EntityMetadataEvent e1; 16 | EntityMetadataEvent e2; 17 | 18 | @BeforeEach 19 | public void setup() { 20 | Map attrs = 21 | Collections.singletonMap("TEST", AttributeValue.booleanAttributeValue(true)); 22 | e1 = EntityMetadataEvent.create("Test 1", attrs, 0L); 23 | e2 = EntityMetadataEvent.create("Test 2", 1L); 24 | } 25 | 26 | @Test 27 | public void when_EventsAreCompared_then_TheyAreOrderdByTimestamp() { 28 | assertEquals(-1, e1.compareTo(e2)); 29 | assertEquals(0, e1.compareTo(e1)); 30 | assertEquals(1, e2.compareTo(e1)); 31 | } 32 | 33 | @Test 34 | public void when_EventsAreSerialized_then_jacksonDoesNotThrowExceptions() 35 | throws JsonProcessingException { 36 | ObjectMapper mapper = new ObjectMapper(); 37 | mapper.writeValueAsString(e1); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /sdk/src/test/java/com/amazonaws/xray/opentelemetry/tracing/utils/ContextUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.amazonaws.xray.opentelemetry.tracing.utils; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.mockito.Mockito.when; 5 | 6 | import com.amazonaws.xray.entities.Segment; 7 | import com.amazonaws.xray.entities.TraceHeader; 8 | import com.amazonaws.xray.entities.TraceID; 9 | import io.opentelemetry.trace.SpanContext; 10 | import io.opentelemetry.trace.SpanId; 11 | import io.opentelemetry.trace.TraceFlags; 12 | import io.opentelemetry.trace.TraceId; 13 | import io.opentelemetry.trace.Tracestate; 14 | import org.junit.jupiter.api.BeforeEach; 15 | import org.junit.jupiter.api.Test; 16 | import org.junit.jupiter.api.extension.ExtendWith; 17 | import org.mockito.Mock; 18 | import org.mockito.junit.jupiter.MockitoExtension; 19 | 20 | @ExtendWith(MockitoExtension.class) 21 | public class ContextUtilsTest { 22 | 23 | 24 | private static final String X_RAY_TRACE_HEADER 25 | = "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"; 26 | private static final String X_RAY_TRACE_ID = "1-5759e988-bd862e3fe1be46a994272793"; 27 | private static final String OT_TRACE_ID = "5759e988bd862e3fe1be46a994272793"; 28 | private static final String SEGMENT_ID = "53995c3f42cd8ad8"; 29 | 30 | private TraceId otTraceId; 31 | private TraceID xrayTraceId; 32 | private SpanId spanId; 33 | private TraceFlags flags; 34 | private Tracestate state = Tracestate.getDefault(); 35 | private TraceHeader header; 36 | private SpanContext context; 37 | 38 | @Mock 39 | private Segment segment; 40 | 41 | 42 | @BeforeEach 43 | public void setup() { 44 | xrayTraceId = TraceID.fromString(X_RAY_TRACE_ID); 45 | otTraceId = TraceId.fromLowerBase16(OT_TRACE_ID, 0); 46 | spanId = SpanId.fromLowerBase16(SEGMENT_ID, 0); 47 | flags = TraceFlags.builder().setIsSampled(true).build(); 48 | context = SpanContext.createFromRemoteParent(otTraceId, spanId, flags, state); 49 | header = TraceHeader.fromString(X_RAY_TRACE_HEADER); 50 | } 51 | 52 | 53 | @Test 54 | public void when_aConTextIsGiven_then_aHeaderIsReturned() { 55 | assertEquals(context, ContextUtils.headerToSpanContext(header)); 56 | } 57 | 58 | @Test 59 | public void when_aHeaderIsGiven_then_aContextIsReturned() { 60 | assertEquals(X_RAY_TRACE_HEADER, ContextUtils.spanContextToHeader(context).toString()); 61 | } 62 | 63 | @Test 64 | public void when_anEntityIsGiven_then_ContextIsReturned() { 65 | when(segment.getParentSegment()).thenReturn(segment); 66 | when(segment.getTraceId()).thenReturn(xrayTraceId); 67 | when(segment.getId()).thenReturn(SEGMENT_ID); 68 | when(segment.isSampled()).thenReturn(true); 69 | when(segment.getParentId()).thenReturn(SEGMENT_ID); 70 | assertEquals(context, ContextUtils.entityToSpanContext(segment)); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "aws-xray-opentelemetry" 2 | 3 | include ":aws-xray-sdk-opentelemetry" 4 | project(':aws-xray-sdk-opentelemetry').projectDir = "$rootDir/sdk" as File 5 | 6 | --------------------------------------------------------------------------------