diff --git a/.github/workflows/links-check.yml b/.github/workflows/links-check.yml new file mode 100644 index 0000000000..5c9fd00b76 --- /dev/null +++ b/.github/workflows/links-check.yml @@ -0,0 +1,21 @@ +name: Link Checker + +on: + repository_dispatch: + workflow_dispatch: + schedule: + - cron: "0 0 * * *" + +jobs: + linkChecker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Link Checker + uses: lycheeverse/lychee-action@v1.8.0 + with: + fail: true + args: --exclude-mail --exclude .+localhost.+ README.md + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 0000000000..375b661f50 --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1,3 @@ +user=aklivity +project=zilla +enhancement-labels=enhancement,story diff --git a/CHANGELOG.md b/CHANGELOG.md index 44b2003ff4..ffaae0a618 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,59 @@ ## [Unreleased](https://github.com/aklivity/zilla/tree/HEAD) -[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.91...HEAD) +[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.92...HEAD) + +**Implemented enhancements:** + +- Support `pgsql` binding [\#1057](https://github.com/aklivity/zilla/issues/1057) +- Handle large HTTP headers [\#1046](https://github.com/aklivity/zilla/issues/1046) +- Gracefully handle `zilla.yml` instead of `zilla.yaml` [\#580](https://github.com/aklivity/zilla/issues/580) + +**Fixed bugs:** + +- Zilla OpenAPI not supporting filesystem catalog [\#1225](https://github.com/aklivity/zilla/issues/1225) +- Zilla produces corrupt messages due to incorrect CRC when fragmented [\#1221](https://github.com/aklivity/zilla/issues/1221) +- Issue referencing `guard` in `asyncapi` binding [\#1215](https://github.com/aklivity/zilla/issues/1215) +- Using catalog::apicurio triggers unexpected behaviour [\#1202](https://github.com/aklivity/zilla/issues/1202) +- `400 Bad Request` response from Zilla when Using Java HttpClient [\#1192](https://github.com/aklivity/zilla/issues/1192) +- Investigate connection pool reconnect when Kafka not yet available [\#1153](https://github.com/aklivity/zilla/issues/1153) + +**Merged pull requests:** + +- Refactor vault handler [\#1236](https://github.com/aklivity/zilla/pull/1236) ([jfallows](https://github.com/jfallows)) +- Mqtt flow control fix [\#1233](https://github.com/aklivity/zilla/pull/1233) ([bmaidics](https://github.com/bmaidics)) +- Fix incorrect flush acknowledgement in KafkaCacheClientProduceFactory [\#1232](https://github.com/aklivity/zilla/pull/1232) ([bmaidics](https://github.com/bmaidics)) +- http binding update to support header overrides at route level [\#1231](https://github.com/aklivity/zilla/pull/1231) ([ankitk-me](https://github.com/ankitk-me)) +- Update asyncapi binding module-info to open parser package [\#1227](https://github.com/aklivity/zilla/pull/1227) ([jfallows](https://github.com/jfallows)) +- Link checker [\#1216](https://github.com/aklivity/zilla/pull/1216) ([vordimous](https://github.com/vordimous)) +- Fix incorrect CRC combine in Kafka produce client [\#1214](https://github.com/aklivity/zilla/pull/1214) ([bmaidics](https://github.com/bmaidics)) +- Reduce compile warnings [\#1213](https://github.com/aklivity/zilla/pull/1213) ([jfallows](https://github.com/jfallows)) +- Eclipse IDE import maven projects [\#1212](https://github.com/aklivity/zilla/pull/1212) ([jfallows](https://github.com/jfallows)) +- Disable JVM class sharing to avoid error message during build [\#1210](https://github.com/aklivity/zilla/pull/1210) ([jfallows](https://github.com/jfallows)) +- Initial risingwave binding projects [\#1209](https://github.com/aklivity/zilla/pull/1209) ([jfallows](https://github.com/jfallows)) +- Ensure id encoding is consistent for encode and decode [\#1204](https://github.com/aklivity/zilla/pull/1204) ([jfallows](https://github.com/jfallows)) +- Update mqtt session stream to report correct origin id for zilla dump command [\#1203](https://github.com/aklivity/zilla/pull/1203) ([jfallows](https://github.com/jfallows)) +- Support pgsql binding [\#1200](https://github.com/aklivity/zilla/pull/1200) ([akrambek](https://github.com/akrambek)) +- Initial pgsql binding projects [\#1198](https://github.com/aklivity/zilla/pull/1198) ([jfallows](https://github.com/jfallows)) +- Fix: Using `asyncapi client` binding trigger NPE & crashes Zilla [\#1197](https://github.com/aklivity/zilla/pull/1197) ([ankitk-me](https://github.com/ankitk-me)) +- Compute kafka produce checksum without staging headers [\#1196](https://github.com/aklivity/zilla/pull/1196) ([jfallows](https://github.com/jfallows)) +- Allow content-length header with h2c upgrade [\#1194](https://github.com/aklivity/zilla/pull/1194) ([jfallows](https://github.com/jfallows)) +- Kafka cache client: mark entry dirty at flush before notifying the server to process [\#1193](https://github.com/aklivity/zilla/pull/1193) ([bmaidics](https://github.com/bmaidics)) +- Ensure streams are cleaned up on authentication failure… [\#1191](https://github.com/aklivity/zilla/pull/1191) ([jfallows](https://github.com/jfallows)) + +## [0.9.92](https://github.com/aklivity/zilla/tree/0.9.92) (2024-08-13) + +[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.91...0.9.92) **Implemented enhancements:** - Support `extract-key` kafka message transform [\#1176](https://github.com/aklivity/zilla/issues/1176) +**Merged pull requests:** + +- Align subject names when using inline catalog [\#1190](https://github.com/aklivity/zilla/pull/1190) ([jfallows](https://github.com/jfallows)) +- Support extract-key kafka message transform [\#1183](https://github.com/aklivity/zilla/pull/1183) ([akrambek](https://github.com/akrambek)) + ## [0.9.91](https://github.com/aklivity/zilla/tree/0.9.91) (2024-08-10) [Full Changelog](https://github.com/aklivity/zilla/compare/0.9.90...0.9.91) diff --git a/README.md b/README.md index 06949a3e3f..655159ca4a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Use **Zilla** as a: | [Async workflows for sync microservices →](https://github.com/aklivity/zilla-examples/tree/main/http.kafka.async) | Make request-response microservice communication asynchronous by routing it over a pair of Kafka topics. | | [Create an event-mesh →](https://www.aklivity.io/post/end-to-end-streaming-between-grpc-services-via-kafka) | Integrate mesh and event-driven microservices by routing connectivity through Kafka. Make Kafka look like a gRPC/REST server or gRPC client. | | [Secure a Server Sent Event (SSE) API →](https://github.com/aklivity/zilla-examples/tree/main/sse.proxy.jwt) | Secure an SSE API by adding JWT-based Continous Authorization. | -| [Validate MQTT via AsyncAPI →](https://github.com/aklivity/zilla-examples/tree/main/mqtt.proxy.asyncapi) | Enforce an AsyncAPI schema for messages going into an MQTT broker. | +| [Validate MQTT via AsyncAPI →](https://github.com/aklivity/zilla-examples/tree/main/asyncapi.mqtt.kafka.proxy) | Enforce an AsyncAPI schema for messages going into an MQTT broker. | | **Much more!** | Check out all the [Zilla Demos](https://github.com/aklivity/zilla-demos) and [Zilla Examples](https://github.com/aklivity/zilla-examples). | ## Get started in 60 seconds diff --git a/build/flyweight-maven-plugin/pom.xml b/build/flyweight-maven-plugin/pom.xml index 37c1bcad88..b3f52643cf 100644 --- a/build/flyweight-maven-plugin/pom.xml +++ b/build/flyweight-maven-plugin/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla build - 0.9.92 + 0.9.93 ../pom.xml diff --git a/build/flyweight-maven-plugin/src/main/java/io/aklivity/zilla/build/maven/plugins/flyweight/internal/AbstractMojo.java b/build/flyweight-maven-plugin/src/main/java/io/aklivity/zilla/build/maven/plugins/flyweight/internal/AbstractMojo.java index f7e3607766..980b19d404 100644 --- a/build/flyweight-maven-plugin/src/main/java/io/aklivity/zilla/build/maven/plugins/flyweight/internal/AbstractMojo.java +++ b/build/flyweight-maven-plugin/src/main/java/io/aklivity/zilla/build/maven/plugins/flyweight/internal/AbstractMojo.java @@ -20,6 +20,8 @@ import java.net.URI; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.LinkedList; import java.util.List; @@ -65,11 +67,15 @@ ClassLoader createLoader() throws IOException try { - for (Object resourcePathEntry : project.getTestClasspathElements()) + for (String classPathElement : project.getTestClasspathElements()) { - File resourcePathFile = new File(resourcePathEntry.toString()); - URI resourcePathURI = resourcePathFile.getAbsoluteFile().toURI(); - resourcePath.add(URI.create(String.format("jar:%s!/META-INF/zilla/", resourcePathURI)).toURL()); + Path classPathEntry = Path.of(classPathElement).toAbsolutePath(); + URI classPathEntryURI = classPathEntry.toUri(); + URI resourcePathEntryURI = Files.isDirectory(classPathEntry) + ? classPathEntry.resolve("META-INF/zilla").toUri() + : URI.create(String.format("jar:%s!/META-INF/zilla/", classPathEntryURI)); + URL resourcePathEntry = resourcePathEntryURI.toURL(); + resourcePath.add(resourcePathEntry); } } catch (DependencyResolutionRequiredException e) diff --git a/build/pom.xml b/build/pom.xml index 2fcb47c3ef..2f3b48bc3c 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla zilla - 0.9.92 + 0.9.93 ../pom.xml diff --git a/cloud/docker-image/pom.xml b/cloud/docker-image/pom.xml index b2d916c4d7..d57f470607 100644 --- a/cloud/docker-image/pom.xml +++ b/cloud/docker-image/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla cloud - 0.9.92 + 0.9.93 ../pom.xml @@ -51,37 +51,37 @@ ${project.groupId} - binding-openapi + binding-echo ${project.version} runtime ${project.groupId} - binding-openapi-asyncapi + binding-fan ${project.version} runtime ${project.groupId} - binding-echo + binding-filesystem ${project.version} runtime ${project.groupId} - binding-fan + binding-http ${project.version} runtime ${project.groupId} - binding-filesystem + binding-http-filesystem ${project.version} runtime ${project.groupId} - binding-http + binding-http-kafka ${project.version} runtime @@ -91,6 +91,12 @@ ${project.version} runtime + + ${project.groupId} + binding-grpc-kafka + ${project.version} + runtime + ${project.groupId} binding-kafka @@ -99,7 +105,7 @@ ${project.groupId} - binding-proxy + binding-kafka-grpc ${project.version} runtime @@ -111,61 +117,67 @@ ${project.groupId} - binding-sse + binding-mqtt-kafka ${project.version} runtime ${project.groupId} - binding-tcp + binding-openapi ${project.version} runtime ${project.groupId} - binding-tls + binding-openapi-asyncapi ${project.version} runtime ${project.groupId} - binding-ws + binding-pgsql ${project.version} runtime ${project.groupId} - binding-http-filesystem + binding-proxy ${project.version} runtime ${project.groupId} - binding-http-kafka + binding-risingwave ${project.version} runtime ${project.groupId} - binding-grpc-kafka + binding-sse ${project.version} runtime ${project.groupId} - binding-mqtt-kafka + binding-sse-kafka ${project.version} runtime ${project.groupId} - binding-sse-kafka + binding-tcp ${project.version} runtime ${project.groupId} - binding-kafka-grpc + binding-tls + ${project.version} + runtime + + + ${project.groupId} + binding-ws ${project.version} runtime @@ -376,7 +388,7 @@ io.fabric8 docker-maven-plugin - 0.43.2 + 0.45.0 ${*} diff --git a/cloud/docker-image/src/main/docker/zpm.json.template b/cloud/docker-image/src/main/docker/zpm.json.template index 7ae3d0f995..d3a9925787 100644 --- a/cloud/docker-image/src/main/docker/zpm.json.template +++ b/cloud/docker-image/src/main/docker/zpm.json.template @@ -29,7 +29,9 @@ "io.aklivity.zilla:binding-mqtt-kafka", "io.aklivity.zilla:binding-openapi", "io.aklivity.zilla:binding-openapi-asyncapi", + "io.aklivity.zilla:binding-pgsql", "io.aklivity.zilla:binding-proxy", + "io.aklivity.zilla:binding-risingwave", "io.aklivity.zilla:binding-sse", "io.aklivity.zilla:binding-sse-kafka", "io.aklivity.zilla:binding-tcp", diff --git a/cloud/helm-chart/pom.xml b/cloud/helm-chart/pom.xml index 67cc6bdc30..81f31da6c1 100644 --- a/cloud/helm-chart/pom.xml +++ b/cloud/helm-chart/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla cloud - 0.9.92 + 0.9.93 ../pom.xml diff --git a/cloud/pom.xml b/cloud/pom.xml index a60f2f3b38..d851548d86 100644 --- a/cloud/pom.xml +++ b/cloud/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla zilla - 0.9.92 + 0.9.93 ../pom.xml diff --git a/conf/pom.xml b/conf/pom.xml index 65fcb9616d..0b83423bd6 100644 --- a/conf/pom.xml +++ b/conf/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla zilla - 0.9.92 + 0.9.93 ../pom.xml diff --git a/conf/src/main/resources/io/aklivity/zilla/conf/checkstyle/configuration.xml b/conf/src/main/resources/io/aklivity/zilla/conf/checkstyle/configuration.xml index d710133e57..1224d5fd77 100644 --- a/conf/src/main/resources/io/aklivity/zilla/conf/checkstyle/configuration.xml +++ b/conf/src/main/resources/io/aklivity/zilla/conf/checkstyle/configuration.xml @@ -18,6 +18,10 @@ + + + + diff --git a/conf/src/main/resources/io/aklivity/zilla/conf/checkstyle/suppressions.xml b/conf/src/main/resources/io/aklivity/zilla/conf/checkstyle/suppressions.xml index 0dd8c7aab1..2e54379c17 100644 --- a/conf/src/main/resources/io/aklivity/zilla/conf/checkstyle/suppressions.xml +++ b/conf/src/main/resources/io/aklivity/zilla/conf/checkstyle/suppressions.xml @@ -21,6 +21,4 @@ - - diff --git a/incubator/binding-amqp.spec/pom.xml b/incubator/binding-amqp.spec/pom.xml index 39c74a14d6..e1b78131aa 100644 --- a/incubator/binding-amqp.spec/pom.xml +++ b/incubator/binding-amqp.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla incubator - 0.9.92 + 0.9.93 ../pom.xml diff --git a/incubator/binding-amqp/pom.xml b/incubator/binding-amqp/pom.xml index ea64884fef..02881fd767 100644 --- a/incubator/binding-amqp/pom.xml +++ b/incubator/binding-amqp/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla incubator - 0.9.92 + 0.9.93 ../pom.xml diff --git a/incubator/binding-amqp/src/main/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/AmqpServerFactory.java b/incubator/binding-amqp/src/main/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/AmqpServerFactory.java index c26de20cad..3797788cb6 100644 --- a/incubator/binding-amqp/src/main/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/AmqpServerFactory.java +++ b/incubator/binding-amqp/src/main/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/AmqpServerFactory.java @@ -254,8 +254,6 @@ public final class AmqpServerFactory implements AmqpStreamFactory private final AmqpMapFW annotationsRO = new AmqpMapFW<>(new AmqpValueFW(), new AmqpValueFW()); private final OctetsFW deliveryTagRO = new OctetsFW(); private final AmqpMessagePropertiesFW amqpPropertiesRO = new AmqpMessagePropertiesFW(); - private final AmqpMapFW applicationPropertyRO = - new AmqpMapFW<>(new AmqpValueFW(), new AmqpValueFW()); private final AmqpApplicationPropertiesFW applicationPropertiesRO = new AmqpApplicationPropertiesFW<>(new AmqpStringFW(), new AmqpSimpleTypeFW()); private final AmqpMapFW footerRO = new AmqpMapFW<>(new AmqpValueFW(), new AmqpValueFW()); @@ -275,7 +273,6 @@ public final class AmqpServerFactory implements AmqpStreamFactory private final AmqpCloseFW.Builder amqpCloseRW = new AmqpCloseFW.Builder(); private final AmqpErrorListFW.Builder amqpErrorListRW = new AmqpErrorListFW.Builder(); private final AmqpStringFW.Builder amqpStringRW = new AmqpStringFW.Builder(); - private final AmqpSimpleTypeFW.Builder amqpValueRW = new AmqpSimpleTypeFW.Builder(); private final AmqpSymbolFW.Builder amqpSymbolRW = new AmqpSymbolFW.Builder(); private final AmqpSourceListFW.Builder amqpSourceListRW = new AmqpSourceListFW.Builder(); private final AmqpTargetListFW.Builder amqpTargetListRW = new AmqpTargetListFW.Builder(); @@ -4503,6 +4500,8 @@ private int encodeSectionData( messageFragmentRW.put(buffer, progress, Integer.BYTES); progress += Integer.BYTES; break; + default: + break; } this.sectionEncoder = this::encodeSectionDataBytes; } @@ -4553,6 +4552,8 @@ private int encodeSectionSequence( messageFragmentRW.put(buffer, progress, Integer.BYTES); progress += Integer.BYTES; break; + default: + break; } this.sectionEncoder = this::encodeSectionSequenceBytes; } diff --git a/incubator/binding-pgsql.spec/COPYRIGHT b/incubator/binding-pgsql.spec/COPYRIGHT new file mode 100644 index 0000000000..0cb10b6f62 --- /dev/null +++ b/incubator/binding-pgsql.spec/COPYRIGHT @@ -0,0 +1,12 @@ +Copyright ${copyrightYears} Aklivity Inc + +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/incubator/binding-pgsql.spec/LICENSE b/incubator/binding-pgsql.spec/LICENSE new file mode 100644 index 0000000000..f3cf11c3ad --- /dev/null +++ b/incubator/binding-pgsql.spec/LICENSE @@ -0,0 +1,114 @@ + Aklivity Community License Agreement + Version 1.0 + +This Aklivity Community License Agreement Version 1.0 (the “Agreement”) sets +forth the terms on which Aklivity, Inc. (“Aklivity”) makes available certain +software made available by Aklivity under this Agreement (the “Software”). BY +INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, +YOU AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO +SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE SOFTWARE. IF YOU ARE RECEIVING +THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU +HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS +AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you, an individual, or +the entity on whose behalf you are receiving the Software. + + 1. LICENSE GRANT AND CONDITIONS. + + 1.1 License. Subject to the terms and conditions of this Agreement, + Aklivity hereby grants to Licensee a non-exclusive, royalty-free, + worldwide, non-transferable, non-sublicenseable license during the term + of this Agreement to: (a) use the Software; (b) prepare modifications and + derivative works of the Software; (c) distribute the Software (including + without limitation in source code or object code form); and (d) reproduce + copies of the Software (the “License”). Licensee is not granted the + right to, and Licensee shall not, exercise the License for an Excluded + Purpose. For purposes of this Agreement, “Excluded Purpose” means making + available any software-as-a-service, platform-as-a-service, + infrastructure-as-a-service or other similar online service that competes + with Aklivity products or services that provide the Software. + + 1.2 Conditions. In consideration of the License, Licensee’s distribution + of the Software is subject to the following conditions: + + (a) Licensee must cause any Software modified by Licensee to carry + prominent notices stating that Licensee modified the Software. + + (b) On each Software copy, Licensee shall reproduce and not remove or + alter all Aklivity or third party copyright or other proprietary + notices contained in the Software, and Licensee must provide the + notice below with each copy. + + “This software is made available by Aklivity, Inc., under the + terms of the Aklivity Community License Agreement, Version 1.0 + located at http://www.Aklivity.io/Aklivity-community-license. BY + INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF + THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.” + + 1.3 Licensee Modifications. Licensee may add its own copyright notices + to modifications made by Licensee and may provide additional or different + license terms and conditions for use, reproduction, or distribution of + Licensee’s modifications. While redistributing the Software or + modifications thereof, Licensee may choose to offer, for a fee or free of + charge, support, warranty, indemnity, or other obligations. Licensee, and + not Aklivity, will be responsible for any such obligations. + + 1.4 No Sublicensing. The License does not include the right to + sublicense the Software, however, each recipient to which Licensee + provides the Software may exercise the Licenses so long as such recipient + agrees to the terms and conditions of this Agreement. + + 2. TERM AND TERMINATION. This Agreement will continue unless and until + earlier terminated as set forth herein. If Licensee breaches any of its + conditions or obligations under this Agreement, this Agreement will + terminate automatically and the License will terminate automatically and + permanently. + + 3. INTELLECTUAL PROPERTY. As between the parties, Aklivity will retain all + right, title, and interest in the Software, and all intellectual property + rights therein. Aklivity hereby reserves all rights not expressly granted + to Licensee in this Agreement. Aklivity hereby reserves all rights in its + trademarks and service marks, and no licenses therein are granted in this + Agreement. + + 4. DISCLAIMER. Aklivity HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND + CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY + DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR + PURPOSE, WITH RESPECT TO THE SOFTWARE. + + 5. LIMITATION OF LIABILITY. Aklivity WILL NOT BE LIABLE FOR ANY DAMAGES OF + ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL, + SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL + APPLY TO THE EXTENT PERMITTED BY APPLICABLE LAW. + + 6.GENERAL. + + 6.1 Governing Law. This Agreement will be governed by and interpreted in + accordance with the laws of the state of California, without reference to + its conflict of laws principles. If Licensee is located within the + United States, all disputes arising out of this Agreement are subject to + the exclusive jurisdiction of courts located in Santa Clara County, + California. USA. If Licensee is located outside of the United States, + any dispute, controversy or claim arising out of or relating to this + Agreement will be referred to and finally determined by arbitration in + accordance with the JAMS International Arbitration Rules. The tribunal + will consist of one arbitrator. The place of arbitration will be Palo + Alto, California. The language to be used in the arbitral proceedings + will be English. Judgment upon the award rendered by the arbitrator may + be entered in any court having jurisdiction thereof. + + 6.2 Assignment. Licensee is not authorized to assign its rights under + this Agreement to any third party. Aklivity may freely assign its rights + under this Agreement to any third party. + + 6.3 Other. This Agreement is the entire agreement between the parties + regarding the subject matter hereof. No amendment or modification of + this Agreement will be valid or binding upon the parties unless made in + writing and signed by the duly authorized representatives of both + parties. In the event that any provision, including without limitation + any condition, of this Agreement is held to be unenforceable, this + Agreement and all licenses and rights granted hereunder will immediately + terminate. Waiver by Aklivity of a breach of any provision of this + Agreement or the failure by Aklivity to exercise any right hereunder + will not be construed as a waiver of any subsequent breach of that right + or as a waiver of any other right. \ No newline at end of file diff --git a/incubator/binding-pgsql.spec/NOTICE b/incubator/binding-pgsql.spec/NOTICE new file mode 100644 index 0000000000..cf99769e41 --- /dev/null +++ b/incubator/binding-pgsql.spec/NOTICE @@ -0,0 +1,18 @@ +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +This project includes: + agrona under The Apache License, Version 2.0 + ICU4J under Unicode/ICU License + Jakarta JSON Processing API under Eclipse Public License 2.0 or GNU General Public License, version 2 with the GNU Classpath Exception + org.leadpony.justify under The Apache Software License, Version 2.0 + zilla::specs::engine.spec under The Apache Software License, Version 2.0 + diff --git a/incubator/binding-pgsql.spec/NOTICE.template b/incubator/binding-pgsql.spec/NOTICE.template new file mode 100644 index 0000000000..209ca12f74 --- /dev/null +++ b/incubator/binding-pgsql.spec/NOTICE.template @@ -0,0 +1,13 @@ +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +This project includes: +#GENERATED_NOTICES# diff --git a/incubator/binding-pgsql.spec/mvnw b/incubator/binding-pgsql.spec/mvnw new file mode 100755 index 0000000000..d2f0ea3808 --- /dev/null +++ b/incubator/binding-pgsql.spec/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/incubator/binding-pgsql.spec/mvnw.cmd b/incubator/binding-pgsql.spec/mvnw.cmd new file mode 100644 index 0000000000..b26ab24f03 --- /dev/null +++ b/incubator/binding-pgsql.spec/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/incubator/binding-pgsql.spec/pom.xml b/incubator/binding-pgsql.spec/pom.xml new file mode 100644 index 0000000000..36198495c7 --- /dev/null +++ b/incubator/binding-pgsql.spec/pom.xml @@ -0,0 +1,159 @@ + + + + 4.0.0 + + io.aklivity.zilla + incubator + 0.9.93 + ../pom.xml + + + binding-pgsql.spec + zilla::incubator::binding-pgsql.spec + + + + Aklivity Community License Agreement + https://www.aklivity.io/aklivity-community-license/ + repo + + + + + 1.00 + 0 + + + + + io.aklivity.k3po + lang + provided + + + ${project.groupId} + engine.spec + ${project.version} + + + junit + junit + test + + + io.aklivity.k3po + control-junit + test + + + org.hamcrest + hamcrest-library + test + + + + + + + src/main/resources + + + src/main/scripts + + + + + + org.jasig.maven + maven-notice-plugin + + + ${project.groupId} + flyweight-maven-plugin + ${project.version} + + core pgsql + io.aklivity.zilla.specs.binding.pgsql.internal.types + + + + + validate + generate + + + + + + com.mycila + license-maven-plugin + + + maven-checkstyle-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.moditect + moditect-maven-plugin + + + io.aklivity.k3po + k3po-maven-plugin + + + ${project.groupId} + engine + ${project.version} + test-jar + + + ${project.groupId} + engine + ${project.version} + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.jacoco + jacoco-maven-plugin + + + io/aklivity/zilla/specs/binding/pgsql/internal/types/**/*.class + + + + BUNDLE + + + INSTRUCTION + COVEREDRATIO + ${jacoco.coverage.ratio} + + + CLASS + MISSEDCOUNT + ${jacoco.missed.count} + + + + + + + + + diff --git a/incubator/binding-pgsql.spec/src/main/java/io/aklivity/zilla/specs/binding/pgsql/PgsqlFunctions.java b/incubator/binding-pgsql.spec/src/main/java/io/aklivity/zilla/specs/binding/pgsql/PgsqlFunctions.java new file mode 100644 index 0000000000..ca46aa48c1 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/java/io/aklivity/zilla/specs/binding/pgsql/PgsqlFunctions.java @@ -0,0 +1,398 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.specs.binding.pgsql; + +import org.agrona.MutableDirectBuffer; +import org.agrona.concurrent.UnsafeBuffer; + +import io.aklivity.k3po.runtime.lang.el.Function; +import io.aklivity.k3po.runtime.lang.el.spi.FunctionMapperSpi; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlBeginExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlColumnInfoFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlCompletedFlushExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlDataExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlFlushExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlFormat; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlMessageType; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlQueryDataExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlReadyFlushExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlRowDataExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlStatus; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlTypeFlushExFW; + +public final class PgsqlFunctions +{ + @Function + public static PgsqlBeginExBuilder beginEx() + { + return new PgsqlBeginExBuilder(); + } + + @Function + public static PgsqlDataExBuilder dataEx() + { + return new PgsqlDataExBuilder(); + } + + @Function + public static PgsqlFlushExBuilder flushEx() + { + return new PgsqlFlushExBuilder(); + } + + public static final class PgsqlBeginExBuilder + { + private final MutableDirectBuffer writeBuffer = new UnsafeBuffer(new byte[1024 * 8]); + + private final PgsqlBeginExFW.Builder beginExRW = new PgsqlBeginExFW.Builder(); + + private PgsqlBeginExBuilder() + { + beginExRW.wrap(writeBuffer, 0, writeBuffer.capacity()); + } + + public PgsqlBeginExBuilder typeId( + int typeId) + { + beginExRW.typeId(typeId); + return this; + } + + public PgsqlBeginExBuilder parameter( + String name, + String value) + { + beginExRW.parametersItem(p -> p + .name(String.format("%s\u0000", name)) + .value(String.format("%s\u0000", value))); + + return this; + } + + public byte[] build() + { + final PgsqlBeginExFW beginEx = beginExRW.build(); + final byte[] array = new byte[beginEx.sizeof()]; + beginEx.buffer().getBytes(beginEx.offset(), array); + return array; + } + } + + public static final class PgsqlDataExBuilder + { + private final MutableDirectBuffer writeBuffer = new UnsafeBuffer(new byte[1024 * 8]); + + private final PgsqlDataExFW dataExRO = new PgsqlDataExFW(); + + private final PgsqlDataExFW.Builder dataExRW = new PgsqlDataExFW.Builder(); + + private PgsqlDataExBuilder() + { + dataExRW.wrap(writeBuffer, 0, writeBuffer.capacity()); + } + + public PgsqlDataExBuilder typeId( + int typeId) + { + dataExRW.typeId(typeId); + return this; + } + + public PgsqlQueryDataExBuilder query() + { + dataExRW.kind(PgsqlMessageType.QUERY.value()); + + return new PgsqlQueryDataExBuilder(); + } + + public PgsqlRowDataExBuilder row() + { + dataExRW.kind(PgsqlMessageType.ROW.value()); + + return new PgsqlRowDataExBuilder(); + } + + public byte[] build() + { + final PgsqlDataExFW dataEx = dataExRO; + final byte[] array = new byte[dataEx.sizeof()]; + dataEx.buffer().getBytes(dataEx.offset(), array); + return array; + } + + public final class PgsqlQueryDataExBuilder + { + private final PgsqlQueryDataExFW.Builder pgsqlQueryDataExRW = new PgsqlQueryDataExFW.Builder(); + + private PgsqlQueryDataExBuilder() + { + pgsqlQueryDataExRW.wrap(writeBuffer, PgsqlDataExFW.FIELD_OFFSET_QUERY, writeBuffer.capacity()); + } + + public PgsqlQueryDataExBuilder deferred( + int deferred) + { + pgsqlQueryDataExRW.deferred(deferred); + return this; + } + + public PgsqlDataExBuilder build() + { + final PgsqlQueryDataExFW pgsqlQueryDataEx = pgsqlQueryDataExRW.build(); + dataExRO.wrap(writeBuffer, 0, pgsqlQueryDataEx.limit()); + return PgsqlDataExBuilder.this; + } + } + + public final class PgsqlRowDataExBuilder + { + private final PgsqlRowDataExFW.Builder pgsqlRowDataExRW = new PgsqlRowDataExFW.Builder(); + + private PgsqlRowDataExBuilder() + { + pgsqlRowDataExRW.wrap(writeBuffer, PgsqlDataExFW.FIELD_OFFSET_QUERY, writeBuffer.capacity()); + } + + public PgsqlRowDataExBuilder deferred( + int deferred) + { + pgsqlRowDataExRW.deferred(deferred); + return this; + } + + public PgsqlDataExBuilder build() + { + final PgsqlRowDataExFW pgsqlRowDataEx = pgsqlRowDataExRW.build(); + dataExRO.wrap(writeBuffer, 0, pgsqlRowDataEx.limit()); + return PgsqlDataExBuilder.this; + } + } + } + + public static final class PgsqlFlushExBuilder + { + private final MutableDirectBuffer writeBuffer = new UnsafeBuffer(new byte[1024 * 8]); + + private final PgsqlFlushExFW flushExRO = new PgsqlFlushExFW(); + + private final PgsqlFlushExFW.Builder flushExRW = new PgsqlFlushExFW.Builder(); + + private PgsqlFlushExBuilder() + { + flushExRW.wrap(writeBuffer, 0, writeBuffer.capacity()); + } + + public PgsqlFlushExBuilder typeId( + int typeId) + { + flushExRW.typeId(typeId); + return this; + } + + public PgsqlTypeFlushExBuilder type() + { + flushExRW.kind(PgsqlMessageType.TYPE.value()); + + return new PgsqlTypeFlushExBuilder(); + } + + public PgsqlCompletedFlushExBuilder completion() + { + flushExRW.kind(PgsqlMessageType.COMPLETION.value()); + + return new PgsqlCompletedFlushExBuilder(); + } + + public PgsqlReadyFlushExBuilder ready() + { + flushExRW.kind(PgsqlMessageType.READY.value()); + + return new PgsqlReadyFlushExBuilder(); + } + + public byte[] build() + { + final PgsqlFlushExFW dataEx = flushExRO; + final byte[] array = new byte[dataEx.sizeof()]; + dataEx.buffer().getBytes(dataEx.offset(), array); + return array; + } + + public final class PgsqlTypeFlushExBuilder + { + private final PgsqlTypeFlushExFW.Builder pgsqlTypeFlushExRW = new PgsqlTypeFlushExFW.Builder(); + + private PgsqlTypeFlushExBuilder() + { + pgsqlTypeFlushExRW.wrap(writeBuffer, PgsqlFlushExFW.FIELD_OFFSET_TYPE, writeBuffer.capacity()); + } + + public PgsqlColumnInfoBuilder column() + { + return new PgsqlColumnInfoBuilder(); + } + + public final class PgsqlColumnInfoBuilder + { + private final MutableDirectBuffer columnInfoBuffer = new UnsafeBuffer(new byte[1024 * 8]); + private final PgsqlColumnInfoFW.Builder columnInfoRW = new PgsqlColumnInfoFW.Builder(); + + PgsqlColumnInfoBuilder() + { + columnInfoRW.wrap(columnInfoBuffer, 0, columnInfoBuffer.capacity()); + } + + public PgsqlColumnInfoBuilder name( + String name) + { + columnInfoRW.name(String.format("%s\u0000", name)); + return this; + } + + public PgsqlColumnInfoBuilder tableOid( + int tableOid) + { + columnInfoRW.tableOid(tableOid); + return this; + } + + public PgsqlColumnInfoBuilder index( + short index) + { + columnInfoRW.index(index); + return this; + } + + public PgsqlColumnInfoBuilder typeOid( + int typeOid) + { + columnInfoRW.typeOid(typeOid); + return this; + } + + public PgsqlColumnInfoBuilder length( + short length) + { + columnInfoRW.length(length); + return this; + } + + public PgsqlColumnInfoBuilder modifier( + int modifier) + { + columnInfoRW.modifier(modifier); + return this; + } + + public PgsqlColumnInfoBuilder format( + String format) + { + columnInfoRW.format(f -> f.set(PgsqlFormat.valueOf(format))); + return this; + } + + public PgsqlTypeFlushExBuilder build() + { + PgsqlColumnInfoFW columnInfo = columnInfoRW.build(); + pgsqlTypeFlushExRW.columnsItem(c -> c + .name(columnInfo.name()) + .tableOid(columnInfo.tableOid()) + .index(columnInfo.index()) + .typeOid(columnInfo.typeOid()) + .length(columnInfo.length()) + .modifier(columnInfo.modifier()) + .format(columnInfo.format())); + + return PgsqlTypeFlushExBuilder.this; + } + } + + public PgsqlFlushExBuilder build() + { + final PgsqlTypeFlushExFW pgsqlTypeFlushEx = pgsqlTypeFlushExRW.build(); + flushExRO.wrap(writeBuffer, 0, pgsqlTypeFlushEx.limit()); + return PgsqlFlushExBuilder.this; + } + } + + public final class PgsqlCompletedFlushExBuilder + { + private final PgsqlCompletedFlushExFW.Builder pgsqlCompletedFlushExRW = new PgsqlCompletedFlushExFW.Builder(); + + private PgsqlCompletedFlushExBuilder() + { + pgsqlCompletedFlushExRW.wrap(writeBuffer, PgsqlFlushExFW.FIELD_OFFSET_TYPE, writeBuffer.capacity()); + } + + public PgsqlCompletedFlushExBuilder tag( + String tag) + { + pgsqlCompletedFlushExRW.tag(String.format("%s\u0000", tag)); + return this; + } + + public PgsqlFlushExBuilder build() + { + final PgsqlCompletedFlushExFW pgsqlCompletedFlushEx = pgsqlCompletedFlushExRW.build(); + flushExRO.wrap(writeBuffer, 0, pgsqlCompletedFlushEx.limit()); + return PgsqlFlushExBuilder.this; + } + } + + public final class PgsqlReadyFlushExBuilder + { + private final PgsqlReadyFlushExFW.Builder pgsqlReadyFlushExRW = new PgsqlReadyFlushExFW.Builder(); + + private PgsqlReadyFlushExBuilder() + { + pgsqlReadyFlushExRW.wrap(writeBuffer, PgsqlFlushExFW.FIELD_OFFSET_TYPE, writeBuffer.capacity()); + } + + public PgsqlReadyFlushExBuilder status( + String status) + { + pgsqlReadyFlushExRW.status(s -> s.set(PgsqlStatus.valueOf(status))); + return this; + } + + public PgsqlFlushExBuilder build() + { + final PgsqlReadyFlushExFW pgsqlReadyFlushEx = pgsqlReadyFlushExRW.build(); + flushExRO.wrap(writeBuffer, 0, pgsqlReadyFlushEx.limit()); + return PgsqlFlushExBuilder.this; + } + } + } + + private PgsqlFunctions() + { + // utility + } + + public static class Mapper extends FunctionMapperSpi.Reflective + { + + public Mapper() + { + super(PgsqlFunctions.class); + } + + @Override + public String getPrefixName() + { + return "pgsql"; + } + } +} diff --git a/incubator/binding-pgsql.spec/src/main/moditect/module-info.java b/incubator/binding-pgsql.spec/src/main/moditect/module-info.java new file mode 100644 index 0000000000..521d25ef4b --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/moditect/module-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +open module io.aklivity.zilla.specs.binding.pgsql +{ + requires transitive io.aklivity.zilla.specs.engine; +} diff --git a/incubator/binding-pgsql.spec/src/main/resources/META-INF/services/io.aklivity.k3po.runtime.lang.el.spi.FunctionMapperSpi b/incubator/binding-pgsql.spec/src/main/resources/META-INF/services/io.aklivity.k3po.runtime.lang.el.spi.FunctionMapperSpi new file mode 100644 index 0000000000..0a11bf0815 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/resources/META-INF/services/io.aklivity.k3po.runtime.lang.el.spi.FunctionMapperSpi @@ -0,0 +1 @@ +io.aklivity.zilla.specs.binding.pgsql.PgsqlFunctions$Mapper diff --git a/incubator/binding-pgsql.spec/src/main/resources/META-INF/zilla/pgsql.idl b/incubator/binding-pgsql.spec/src/main/resources/META-INF/zilla/pgsql.idl new file mode 100644 index 0000000000..8e9de96273 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/resources/META-INF/zilla/pgsql.idl @@ -0,0 +1,101 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +scope pgsql +{ + scope stream + { + struct PgsqlParameter + { + string16 name; + string16 value; + } + + struct PgsqlBeginEx extends core::stream::Extension + { + PgsqlParameter[] parameters; + } + + enum PgsqlMessageType (uint8) + { + QUERY (81), + ROW (68), + TYPE (84), + COMPLETION (67), + READY (90) + } + + union PgsqlDataEx switch (uint8) extends core::stream::Extension + { + case 68: pgsql::stream::PgsqlRowDataEx row; + case 81: pgsql::stream::PgsqlQueryDataEx query; + } + + struct PgsqlQueryDataEx + { + int32 deferred = 0; + } + + struct PgsqlRowDataEx + { + int32 deferred = 0; + } + + union PgsqlFlushEx switch (uint8) extends core::stream::Extension + { + case 84: pgsql::stream::PgsqlTypeFlushEx type; + case 67: pgsql::stream::PgsqlCompletedFlushEx completion; + case 90: pgsql::stream::PgsqlReadyFlushEx ready; + } + + enum PgsqlFormat (uint16) + { + TEXT(0), + BINARY(1) + } + + struct PgsqlColumnInfo + { + string16 name; + int32 tableOid; + int16 index; + int32 typeOid; + int16 length; + int32 modifier; + PgsqlFormat format; + } + + struct PgsqlTypeFlushEx + { + PgsqlColumnInfo[] columns; + } + + struct PgsqlCompletedFlushEx + { + string16 tag; + } + + enum PgsqlStatus (uint8) + { + IDLE(73), + TRANSACTION(84), + ERROR(69) + } + + struct PgsqlReadyFlushEx + { + PgsqlStatus status; + } + } +} diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/config/client.yaml b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/config/client.yaml new file mode 100644 index 0000000000..971eccfc84 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/config/client.yaml @@ -0,0 +1,22 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +--- +name: test +bindings: + app0: + type: pgsql + kind: client + exit: net0 diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/config/server.yaml b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/config/server.yaml new file mode 100644 index 0000000000..e792a837e4 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/config/server.yaml @@ -0,0 +1,22 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +--- +name: test +bindings: + net0: + type: pgsql + kind: server + exit: app0 diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/schema/pgsql.schema.patch.json b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/schema/pgsql.schema.patch.json new file mode 100644 index 0000000000..de34cc7625 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/schema/pgsql.schema.patch.json @@ -0,0 +1,50 @@ +[ + { + "op": "add", + "path": "/$defs/binding/properties/type/enum/-", + "value": "pgsql" + }, + { + "op": "add", + "path": "/$defs/binding/allOf/-", + "value": + { + "if": + { + "properties": + { + "type": + { + "const": "pgsql" + } + } + }, + "then": + { + "properties": + { + "type": + { + "const": "pgsql" + }, + "kind": + { + "enum": [ "client", "server" ] + }, + "vault": false, + "options": false, + "routes": false + }, + "anyOf": + [ + { + "required": + [ + "exit" + ] + } + ] + } + } + } +] diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.read.abort/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.read.abort/client.rpt new file mode 100644 index 0000000000..274501cfe1 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.read.abort/client.rpt @@ -0,0 +1,31 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "duplex" + +write zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +read abort +write aborted diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.read.abort/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.read.abort/server.rpt new file mode 100644 index 0000000000..d750157216 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.read.abort/server.rpt @@ -0,0 +1,35 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "duplex" + +accepted + +read zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +write aborted +read abort diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.write.abort/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.write.abort/client.rpt new file mode 100644 index 0000000000..edec5d4ef6 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.write.abort/client.rpt @@ -0,0 +1,31 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "duplex" + +write zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +write abort +read aborted diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.write.abort/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.write.abort/server.rpt new file mode 100644 index 0000000000..3b4c24ea01 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/client.sent.write.abort/server.rpt @@ -0,0 +1,35 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "duplex" + +accepted + +read zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +read aborted +write abort diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.fragmented/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.fragmented/client.rpt new file mode 100644 index 0000000000..3b4b648f7f --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.fragmented/client.rpt @@ -0,0 +1,58 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "duplex" + +write zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +write option zilla:flags "init" +write zilla:data.ext ${pgsql:dataEx() + .typeId(zilla:id("pgsql")) + .query() + .deferred(41) + .build() + .build()} +write "CREATE TABLE IF NOT EXISTS balances (name VARCHAR, type VARCHAR, description VARCHAR, timestamp VARCHAR," + +write option zilla:flags "fin" +write " PRIMARY KEY (name));" + [0x00] + +read advised zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .completion() + .tag("CREATE_TABLE") + .build() + .build()} + +read advised zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .ready() + .status("IDLE") + .build() + .build()} + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.fragmented/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.fragmented/server.rpt new file mode 100644 index 0000000000..575551430d --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.fragmented/server.rpt @@ -0,0 +1,62 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "duplex" + +accepted + +read zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +read option zilla:flags "init" +read zilla:data.ext ${pgsql:dataEx() + .typeId(zilla:id("pgsql")) + .query() + .deferred(41) + .build() + .build()} +read "CREATE TABLE IF NOT EXISTS balances (name VARCHAR, type VARCHAR, description VARCHAR, timestamp VARCHAR," + +read option zilla:flags "fin" +read " PRIMARY KEY (name));" + [0x00] + +write advise zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .completion() + .tag("CREATE_TABLE") + .build() + .build()} + +write advise zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .ready() + .status("IDLE") + .build() + .build()} + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.with.primary.key/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.with.primary.key/client.rpt new file mode 100644 index 0000000000..939265a72b --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.with.primary.key/client.rpt @@ -0,0 +1,55 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "duplex" + +write zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +write zilla:data.ext ${pgsql:dataEx() + .typeId(zilla:id("pgsql")) + .query() + .build() + .build()} +write "CREATE TABLE IF NOT EXISTS balances (name VARCHAR, type VARCHAR, description VARCHAR, PRIMARY KEY (name));" + [0x00] + +write flush + +read advised zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .completion() + .tag("CREATE_TABLE") + .build() + .build()} + +read advised zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .ready() + .status("IDLE") + .build() + .build()} + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.with.primary.key/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.with.primary.key/server.rpt new file mode 100644 index 0000000000..778b3043e7 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/create.table.with.primary.key/server.rpt @@ -0,0 +1,57 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "duplex" + +accepted + +read zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +read zilla:data.ext ${pgsql:dataEx() + .typeId(zilla:id("pgsql")) + .query() + .build() + .build()} +read "CREATE TABLE IF NOT EXISTS balances (name VARCHAR, type VARCHAR, description VARCHAR, PRIMARY KEY (name));" + [0x00] + +write advise zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .completion() + .tag("CREATE_TABLE") + .build() + .build()} + +write advise zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .ready() + .status("IDLE") + .build() + .build()} + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/select.table/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/select.table/client.rpt new file mode 100644 index 0000000000..abf8208ff1 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/select.table/client.rpt @@ -0,0 +1,100 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "duplex" + +write zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +write zilla:data.ext ${pgsql:dataEx() + .typeId(zilla:id("pgsql")) + .query() + .build() + .build()} +write "SELECT * FROM balances;" + [0x00] + +read advised zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .type() + .column() + .name("balance") + .tableOid(0) + .index(0) + .typeOid(701) + .length(8) + .modifier(-1) + .format("TEXT") + .build() + .column() + .name("timestamp") + .tableOid(0) + .index(0) + .typeOid(20) + .length(8) + .modifier(-1) + .format("TEXT") + .build() + .column() + .name("user_id") + .tableOid(0) + .index(0) + .typeOid(17) + .length(-1) + .modifier(-1) + .format("TEXT") + .build() + .build() + .build()} + +read zilla:data.ext ${pgsql:dataEx() + .typeId(zilla:id("pgsql")) + .row() + .build() + .build()} +read [0x00 0x03] # Field Count + [0x00 0x00 0x00 0x04] # Length + [0x31 0x39 0x36 0x34] # Data + [0x00 0x00 0x00 0x0a] # Length + [0x31 0x37 0x32 0x33 0x35 0x39 0x33 0x31 0x31 0x33] # Data + [0x00 0x00 0x00 0x04] # Length + [0x5c 0x78 0x33 0x31] # Data + + +read advised zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .completion() + .tag("SELECT 1") + .build() + .build()} + +read advised zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .ready() + .status("IDLE") + .build() + .build()} + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/select.table/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/select.table/server.rpt new file mode 100644 index 0000000000..c0575c3658 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/select.table/server.rpt @@ -0,0 +1,103 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "duplex" + +accepted + +read zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +read zilla:data.ext ${pgsql:dataEx() + .typeId(zilla:id("pgsql")) + .query() + .build() + .build()} +read "SELECT * FROM balances;" +read [0x00] + +write advise zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .type() + .column() + .name("balance") + .tableOid(0) + .index(0) + .typeOid(701) + .length(8) + .modifier(-1) + .format("TEXT") + .build() + .column() + .name("timestamp") + .tableOid(0) + .index(0) + .typeOid(20) + .length(8) + .modifier(-1) + .format("TEXT") + .build() + .column() + .name("user_id") + .tableOid(0) + .index(0) + .typeOid(17) + .length(-1) + .modifier(-1) + .format("TEXT") + .build() + .build() + .build()} + +write zilla:data.ext ${pgsql:dataEx() + .typeId(zilla:id("pgsql")) + .row() + .build() + .build()} +write [0x00 0x03] # Field Count + [0x00 0x00 0x00 0x04] # Length + [0x31 0x39 0x36 0x34] # Data + [0x00 0x00 0x00 0x0a] # Length + [0x31 0x37 0x32 0x33 0x35 0x39 0x33 0x31 0x31 0x33] # Data + [0x00 0x00 0x00 0x04] # Length + [0x5c 0x78 0x33 0x31] # Data + +write advise zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .completion() + .tag("SELECT 1") + .build() + .build()} + +write advise zilla:flush ${pgsql:flushEx() + .typeId(zilla:id("pgsql")) + .ready() + .status("IDLE") + .build() + .build()} + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/ssl.request/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/ssl.request/client.rpt new file mode 100644 index 0000000000..14d03b01ad --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/ssl.request/client.rpt @@ -0,0 +1,31 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "duplex" + +write zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/ssl.request/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/ssl.request/server.rpt new file mode 100644 index 0000000000..a614aa4e01 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/ssl.request/server.rpt @@ -0,0 +1,35 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "duplex" + +accepted + +read zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/termination.request/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/termination.request/client.rpt new file mode 100644 index 0000000000..0e041a3c51 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/termination.request/client.rpt @@ -0,0 +1,31 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "duplex" + +write zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/termination.request/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/termination.request/server.rpt new file mode 100644 index 0000000000..263b8175f5 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/application/termination.request/server.rpt @@ -0,0 +1,35 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "duplex" + +accepted + +read zilla:begin.ext ${pgsql:beginEx() + .typeId(zilla:id("pgsql")) + .parameter("user", "root") + .parameter("database", "dev") + .parameter("application_name", "psql") + .parameter("client_encoding", "UTF8") + .build()} + +connected + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.read.abort/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.read.abort/client.rpt new file mode 100644 index 0000000000..b7cf8dde76 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.read.abort/client.rpt @@ -0,0 +1,72 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkConnectWindow 8192 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +read [0x52] # type R + 8 # length + 0 # authentication type + +read [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +read [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +read [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +read [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +read [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +read [0x5a] # type Z + 5 # length + [0x49] # status + +read abort +write aborted diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.read.abort/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.read.abort/server.rpt new file mode 100644 index 0000000000..2fa4e897c4 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.read.abort/server.rpt @@ -0,0 +1,74 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +write [0x52] # type R + 8 # length + 0 # authentication type + +write [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +write [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +write [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +write [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +write [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +write [0x5a] # type Z + 5 # length + [0x49] # status + +write aborted +read abort diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.write.abort/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.write.abort/client.rpt new file mode 100644 index 0000000000..21cc55c7bf --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.write.abort/client.rpt @@ -0,0 +1,72 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkConnectWindow 8192 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +read [0x52] # type R + 8 # length + 0 # authentication type + +read [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +read [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +read [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +read [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +read [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +read [0x5a] # type Z + 5 # length + [0x49] # status + +write abort +read aborted diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.write.abort/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.write.abort/server.rpt new file mode 100644 index 0000000000..0593b3e115 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/client.sent.write.abort/server.rpt @@ -0,0 +1,74 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +write [0x52] # type R + 8 # length + 0 # authentication type + +write [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +write [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +write [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +write [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +write [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +write [0x5a] # type Z + 5 # length + [0x49] # status + +read aborted +write abort diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.fragmented/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.fragmented/client.rpt new file mode 100644 index 0000000000..2c0f9bca1d --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.fragmented/client.rpt @@ -0,0 +1,91 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkConnectWindow 8192 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +read [0x52] # type R + 8 # length + 0 # authentication type + +read [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +read [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +read [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +read [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +read [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +read [0x5a] # type Z + 5 # length + [0x49] # status + +write [0x51] # type Q + 130 # length + "CREATE TABLE IF NOT EXISTS balances (name VARCHAR, type VARCHAR, description VARCHAR," + +write " timestamp VARCHAR, PRIMARY KEY (name));" + [0x00] # End of string + +read [0x43] # type C + 17 # length + "CREATE_TABLE" # tag + [0x00] # End of string + +read [0x5a] # type Z + 5 # length + [0x49] # status + +read [0x58] # type X + 4 # length + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.fragmented/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.fragmented/server.rpt new file mode 100644 index 0000000000..82f7d00e60 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.fragmented/server.rpt @@ -0,0 +1,93 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +write [0x52] # type R + 8 # length + 0 # authentication type + +write [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +write [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +write [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +write [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +write [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +write [0x5a] # type Z + 5 # length + [0x49] # status + +read [0x51] # type Q + 130 # length + "CREATE TABLE IF NOT EXISTS balances (name VARCHAR, type VARCHAR, description VARCHAR," + +read " timestamp VARCHAR, PRIMARY KEY (name));" + [0x00] # End of string + +write [0x43] # type C + 17 # length + "CREATE_TABLE" # tag + [0x00] # End of string + +write [0x5a] # type Z + 5 # length + [0x49] # status + +write [0x58] # type X + 4 # length + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.with.primary.key/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.with.primary.key/client.rpt new file mode 100644 index 0000000000..7a46c8a830 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.with.primary.key/client.rpt @@ -0,0 +1,89 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkConnectWindow 8192 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +read [0x52] # type R + 8 # length + 0 # authentication type + +read [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +read [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +read [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +read [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +read [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +read [0x5a] # type Z + 5 # length + [0x49] # status + +write [0x51] # type Q + 111 # length + "CREATE TABLE IF NOT EXISTS balances (name VARCHAR, type VARCHAR, description VARCHAR, PRIMARY KEY (name));" + [0x00] # End of string + +read [0x43] # type C + 17 # length + "CREATE_TABLE" # tag + [0x00] # End of string + +read [0x5a] # type Z + 5 # length + [0x49] # status + +read [0x58] # type X + 4 # length + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.with.primary.key/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.with.primary.key/server.rpt new file mode 100644 index 0000000000..9d73f7dfdf --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/create.table.with.primary.key/server.rpt @@ -0,0 +1,91 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +write [0x52] # type R + 8 # length + 0 # authentication type + +write [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +write [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +write [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +write [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +write [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +write [0x5a] # type Z + 5 # length + [0x49] # status + +read [0x51] # type Q + 111 # length + "CREATE TABLE IF NOT EXISTS balances (name VARCHAR, type VARCHAR, description VARCHAR, PRIMARY KEY (name));" + [0x00] # End of string + +write [0x43] # type C + 17 # length + "CREATE_TABLE" # tag + [0x00] # End of string + +write [0x5a] # type Z + 5 # length + [0x49] # status + +write [0x58] # type X + 4 # length + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/select.table/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/select.table/client.rpt new file mode 100644 index 0000000000..270d5f2556 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/select.table/client.rpt @@ -0,0 +1,128 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkConnectWindow 8192 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +read [0x52] # type R + 8 # length + 0 # authentication type + +read [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +read [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +read [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +read [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +read [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +read [0x5a] # type Z + 5 # length + [0x49] # status + +write [0x51] # type Q + 28 # length + "SELECT * FROM balances;" + [0x00] + +read [0x54] # type T + 86 # length + 3s # Field Count + "balance" # Column name + [0x00] # End of string + 0 # Table OID + 0s # Index + 701 # Type OID + 8s # Length + -1 # Modifier + 0s # Format + "timestamp" # Column name + [0x00] # End of string + 0 # Table OID + 0s # Index + 20 # Type OID + 8s # Length + -1 # Modifier + 0s # Format + "user_id" # Column name + [0x00] # End of string + 0 # Table OID + 0s # Index + 17 # Type OID + -1s # Length + -1 # Modifier + 0s # Format + +read [0x44] # type D + 36 # length + 3s # Field Count + 4 # Length + [0x31 0x39 0x36 0x34] # Data + 10 # Length + [0x31 0x37 0x32 0x33 0x35 0x39 0x33 0x31 0x31 0x33] # Data + 4 # Length + [0x5c 0x78 0x33 0x31] # Data + + +read [0x43] # type C + 13 # length + "SELECT 1" # tag + [0x00] # End of string + +read [0x5a] # type Z + 5 # length + [0x49] # status + +read [0x58] # type X + 4 # length + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/select.table/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/select.table/server.rpt new file mode 100644 index 0000000000..bdd4c46b05 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/select.table/server.rpt @@ -0,0 +1,130 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +write [0x52] # type R + 8 # length + 0 # authentication type + +write [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +write [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +write [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +write [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +write [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +write [0x5a] # type Z + 5 # length + [0x49] # status + +read [0x51] # type Q + 28 # length + "SELECT * FROM balances;" + [0x00] + +write [0x54] # type T + 86 # length + 3s # Field Count + "balance" # Column name + [0x00] # End of string + 0 # Table OID + 0s # Index + 701 # Type OID + 8s # Length + -1 # Modifier + 0s # Format + "timestamp" # Column name + [0x00] # End of string + 0 # Table OID + 0s # Index + 20 # Type OID + 8s # Length + -1 # Modifier + 0s # Format + "user_id" # Column name + [0x00] # End of string + 0 # Table OID + 0s # Index + 17 # Type OID + -1s # Length + -1 # Modifier + 0s # Format + +write [0x44] # type D + 36 # length + 3s # Field Count + 4 # Length + [0x31 0x39 0x36 0x34] # Data + 10 # Length + [0x31 0x37 0x32 0x33 0x35 0x39 0x33 0x31 0x31 0x33] # Data + 4 # Length + [0x5c 0x78 0x33 0x31] # Data + + +write [0x43] # type C + 13 # length + "SELECT 1" # tag + [0x00] # End of string + +write [0x5a] # type Z + 5 # length + [0x49] # status + +write [0x58] # type X + 4 # length + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/ssl.request/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/ssl.request/client.rpt new file mode 100644 index 0000000000..d52779fc06 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/ssl.request/client.rpt @@ -0,0 +1,80 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkConnectWindow 8192 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 8 # length + [0x04 0xd2 0x16 0x2f] # request code + +read [0x4e] + +write 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +read [0x52] # type R + 8 # length + 0 # authentication type + +read [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +read [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +read [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +read [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +read [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +read [0x5a] # type Z + 5 # length + [0x49] # status + +read [0x58] # type X + 4 # length + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/ssl.request/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/ssl.request/server.rpt new file mode 100644 index 0000000000..e0b126ef8e --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/ssl.request/server.rpt @@ -0,0 +1,82 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 8 # length + [0x04 0xd2 0x16 0x2f] # request code + +write [0x4e] + +read 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +write [0x52] # type R + 8 # length + 0 # authentication type + +write [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +write [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +write [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +write [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +write [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +write [0x5a] # type Z + 5 # length + [0x49] # status + +write [0x58] # type X + 4 # length + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/termination.request/client.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/termination.request/client.rpt new file mode 100644 index 0000000000..ba792966fe --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/termination.request/client.rpt @@ -0,0 +1,75 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkConnectWindow 8192 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +read [0x52] # type R + 8 # length + 0 # authentication type + +read [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +read [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +read [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +read [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +read [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +read [0x5a] # type Z + 5 # length + [0x49] # status + +write [0x58] # type X + 4 # length + +write close +read closed diff --git a/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/termination.request/server.rpt b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/termination.request/server.rpt new file mode 100644 index 0000000000..68391ef8ea --- /dev/null +++ b/incubator/binding-pgsql.spec/src/main/scripts/io/aklivity/zilla/specs/binding/pgsql/streams/network/termination.request/server.rpt @@ -0,0 +1,77 @@ +# +# Copyright 2021-2023 Aklivity Inc +# +# Licensed under the Aklivity Community License (the "License"); you may not use +# this file except in compliance with the License. You may obtain a copy of the +# License at +# +# https://www.aklivity.io/aklivity-community-license/ +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 75 # length + 3s # major version + 0s # minor version + "user" [0x00] # name + "root" [0x00] # value + "database" [0x00] # name + "dev" [0x00] # value + "application_name" [0x00] # name + "psql" [0x00] # value + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + [0x00] # end of parameters + +write [0x52] # type R + 8 # length + 0 # authentication type + +write [0x4b] # type K + 12 # length + 0 # pid + 0 # key + +write [0x53] # type S + 25 # length + "client_encoding" [0x00] # name + "UTF8" [0x00] # value + +write [0x53] # type S + 35 # length + "standard_conforming_strings" [0x00] # name + [0x6f 0x6e 0x00] # value + +write [0x53] # type S + 25 # length + "server_version" [0x00] # name + "1.0.0" [0x00] # value + +write [0x53] # type S + 27 # length + "application_name" [0x00] # name + "zilla" [0x00] # value + +write [0x5a] # type Z + 5 # length + [0x49] # status + +read [0x58] # type X + 4 # length + +read closed +write close diff --git a/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/ApplicationIT.java b/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/ApplicationIT.java new file mode 100644 index 0000000000..7f88a05062 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/ApplicationIT.java @@ -0,0 +1,102 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.specs.binding.pgsql.streams; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.rules.RuleChain.outerRule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.DisableOnDebug; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +import io.aklivity.k3po.runtime.junit.annotation.Specification; +import io.aklivity.k3po.runtime.junit.rules.K3poRule; + +public class ApplicationIT +{ + private final K3poRule k3po = new K3poRule() + .addScriptRoot("app", "io/aklivity/zilla/specs/binding/pgsql/streams/application"); + + private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS)); + + @Rule + public final TestRule chain = outerRule(k3po).around(timeout); + + @Test + @Specification({ + "${app}/create.table.with.primary.key/client", + "${app}/create.table.with.primary.key/server" + }) + public void shouldCreateTableWithPrimaryKey() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${app}/select.table/client", + "${app}/select.table/server" }) + public void shouldSelectTable() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${app}/client.sent.write.abort/client", + "${app}/client.sent.write.abort/server" }) + public void shouldHandleClientSentWriteAbort() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${app}/client.sent.read.abort/client", + "${app}/client.sent.read.abort/server" }) + public void shouldHandleClientSentReadAbort() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${app}/create.table.fragmented/client", + "${app}/create.table.fragmented/server" }) + public void shouldHandleFragmentedCreateTable() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${app}/ssl.request/client", + "${app}/ssl.request/server" }) + public void shouldHandleSslRequest() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${app}/termination.request/client", + "${app}/termination.request/server" }) + public void shouldHandleTerminationRequest() throws Exception + { + k3po.finish(); + } +} diff --git a/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/NetworkIT.java b/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/NetworkIT.java new file mode 100644 index 0000000000..89eed98a61 --- /dev/null +++ b/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/NetworkIT.java @@ -0,0 +1,102 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.specs.binding.pgsql.streams; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.rules.RuleChain.outerRule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.DisableOnDebug; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +import io.aklivity.k3po.runtime.junit.annotation.Specification; +import io.aklivity.k3po.runtime.junit.rules.K3poRule; + +public class NetworkIT +{ + private final K3poRule k3po = new K3poRule() + .addScriptRoot("net", "io/aklivity/zilla/specs/binding/pgsql/streams/network"); + + private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS)); + + @Rule + public final TestRule chain = outerRule(k3po).around(timeout); + + @Test + @Specification({ + "${net}/create.table.with.primary.key/client", + "${net}/create.table.with.primary.key/server" + }) + public void shouldCreateTableWithPrimaryKey() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${net}/select.table/client", + "${net}/select.table/server" }) + public void shouldSelectTable() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${net}/ssl.request/client", + "${net}/ssl.request/server" }) + public void shouldHandleSslRequest() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${net}/client.sent.write.abort/client", + "${net}/client.sent.write.abort/server" }) + public void shouldHandleClientSentWriteAbort() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${net}/client.sent.read.abort/client", + "${net}/client.sent.read.abort/server" }) + public void shouldHandleClientSentReadAbort() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${net}/create.table.fragmented/client", + "${net}/create.table.fragmented/server" }) + public void shouldHandleFragmentedCreateTable() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${net}/termination.request/client", + "${net}/termination.request/server" }) + public void shouldHandleTerminationRequest() throws Exception + { + k3po.finish(); + } +} diff --git a/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/internal/PgsqlFunctionsTest.java b/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/internal/PgsqlFunctionsTest.java new file mode 100644 index 0000000000..0367fe9dbc --- /dev/null +++ b/incubator/binding-pgsql.spec/src/test/java/io/aklivity/zilla/specs/binding/pgsql/streams/internal/PgsqlFunctionsTest.java @@ -0,0 +1,174 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.specs.binding.pgsql.streams.internal; + +import static io.aklivity.zilla.specs.binding.pgsql.PgsqlFunctions.beginEx; +import static io.aklivity.zilla.specs.binding.pgsql.PgsqlFunctions.dataEx; +import static io.aklivity.zilla.specs.binding.pgsql.PgsqlFunctions.flushEx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; + +import java.lang.reflect.Method; + +import javax.el.ELContext; +import javax.el.FunctionMapper; + +import org.agrona.DirectBuffer; +import org.agrona.concurrent.UnsafeBuffer; +import org.junit.Test; + +import io.aklivity.k3po.runtime.lang.internal.el.ExpressionContext; +import io.aklivity.zilla.specs.binding.pgsql.PgsqlFunctions; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlBeginExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlDataExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlFlushExFW; +import io.aklivity.zilla.specs.binding.pgsql.internal.types.stream.PgsqlStatus; + + +public class PgsqlFunctionsTest +{ + @Test + public void shouldResolveFunction() throws Exception + { + final ELContext ctx = new ExpressionContext(); + final FunctionMapper mapper = ctx.getFunctionMapper(); + final Method function = mapper.resolveFunction("pgsql", "beginEx"); + + assertNotNull(function); + assertSame(PgsqlFunctions.class, function.getDeclaringClass()); + } + + @Test + public void shouldGenerateBeginExtension() + { + byte[] build = beginEx() + .typeId(0x01) + .parameter("name", "pgsql") + .build(); + + DirectBuffer buffer = new UnsafeBuffer(build); + PgsqlBeginExFW beginEx = new PgsqlBeginExFW().wrap(buffer, 0, buffer.capacity()); + + assertEquals(1, beginEx.parameters().fieldCount()); + beginEx.parameters().forEach(h -> + { + assertEquals("name\u0000", h.name().asString()); + assertEquals("pgsql\u0000", h.value().asString()); + }); + } + + @Test + public void shouldEncodePgsqlDataQueryExtension() + { + final byte[] build = dataEx() + .typeId(0x01) + .query() + .deferred(1) + .build() + .build(); + + DirectBuffer buffer = new UnsafeBuffer(build); + PgsqlDataExFW dataEx = new PgsqlDataExFW().wrap(buffer, 0, buffer.capacity()); + assertEquals(0x01, dataEx.typeId()); + + assertEquals(1, dataEx.query().deferred()); + } + + @Test + public void shouldEncodePgsqlDataRowExtension() + { + final byte[] build = dataEx() + .typeId(0x01) + .row() + .deferred(1) + .build() + .build(); + + DirectBuffer buffer = new UnsafeBuffer(build); + PgsqlDataExFW dataEx = new PgsqlDataExFW().wrap(buffer, 0, buffer.capacity()); + assertEquals(0x01, dataEx.typeId()); + + assertEquals(1, dataEx.row().deferred()); + } + + @Test + public void shouldEncodePgsqlFlushTypeExtension() + { + final byte[] build = flushEx() + .typeId(0x01) + .type() + .column() + .name("balance") + .tableOid(0) + .index((short) 0) + .typeOid(701) + .length((short)8) + .modifier(-1) + .format("TEXT") + .build() + .build() + .build(); + + DirectBuffer buffer = new UnsafeBuffer(build); + PgsqlFlushExFW flushEx = new PgsqlFlushExFW().wrap(buffer, 0, buffer.capacity()); + assertEquals(0x01, flushEx.typeId()); + + assertEquals(1, flushEx.type().columns().fieldCount()); + flushEx.type().columns().forEach(c -> + { + assertEquals("balance\u0000", c.name().asString()); + assertEquals(0, c.tableOid()); + assertEquals(0, c.index()); + assertEquals(701, c.typeOid()); + assertEquals(-1, c.modifier()); + }); + } + + @Test + public void shouldEncodePgsqlFlushCompletionExtension() + { + final byte[] build = flushEx() + .typeId(0x01) + .completion() + .tag("CREATE_TABLE") + .build() + .build(); + + DirectBuffer buffer = new UnsafeBuffer(build); + PgsqlFlushExFW flushEx = new PgsqlFlushExFW().wrap(buffer, 0, buffer.capacity()); + + assertEquals(0x01, flushEx.typeId()); + assertEquals("CREATE_TABLE\u0000", flushEx.completion().tag().asString()); + } + + @Test + public void shouldEncodePgsqlFlushReadyExtension() + { + final byte[] build = flushEx() + .typeId(0x01) + .ready() + .status("IDLE") + .build() + .build(); + + DirectBuffer buffer = new UnsafeBuffer(build); + PgsqlFlushExFW flushEx = new PgsqlFlushExFW().wrap(buffer, 0, buffer.capacity()); + + assertEquals(0x01, flushEx.typeId()); + assertEquals(PgsqlStatus.IDLE, flushEx.ready().status().get()); + } + +} diff --git a/incubator/binding-pgsql/COPYRIGHT b/incubator/binding-pgsql/COPYRIGHT new file mode 100644 index 0000000000..0cb10b6f62 --- /dev/null +++ b/incubator/binding-pgsql/COPYRIGHT @@ -0,0 +1,12 @@ +Copyright ${copyrightYears} Aklivity Inc + +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/incubator/binding-pgsql/LICENSE b/incubator/binding-pgsql/LICENSE new file mode 100644 index 0000000000..f6abb6327b --- /dev/null +++ b/incubator/binding-pgsql/LICENSE @@ -0,0 +1,114 @@ + Aklivity Community License Agreement + Version 1.0 + +This Aklivity Community License Agreement Version 1.0 (the “Agreement”) sets +forth the terms on which Aklivity, Inc. (“Aklivity”) makes available certain +software made available by Aklivity under this Agreement (the “Software”). BY +INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, +YOU AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO +SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE SOFTWARE. IF YOU ARE RECEIVING +THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU +HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS +AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you, an individual, or +the entity on whose behalf you are receiving the Software. + + 1. LICENSE GRANT AND CONDITIONS. + + 1.1 License. Subject to the terms and conditions of this Agreement, + Aklivity hereby grants to Licensee a non-exclusive, royalty-free, + worldwide, non-transferable, non-sublicenseable license during the term + of this Agreement to: (a) use the Software; (b) prepare modifications and + derivative works of the Software; (c) distribute the Software (including + without limitation in source code or object code form); and (d) reproduce + copies of the Software (the “License”). Licensee is not granted the + right to, and Licensee shall not, exercise the License for an Excluded + Purpose. For purposes of this Agreement, “Excluded Purpose” means making + available any software-as-a-service, platform-as-a-service, + infrastructure-as-a-service or other similar online service that competes + with Aklivity products or services that provide the Software. + + 1.2 Conditions. In consideration of the License, Licensee’s distribution + of the Software is subject to the following conditions: + + (a) Licensee must cause any Software modified by Licensee to carry + prominent notices stating that Licensee modified the Software. + + (b) On each Software copy, Licensee shall reproduce and not remove or + alter all Aklivity or third party copyright or other proprietary + notices contained in the Software, and Licensee must provide the + notice below with each copy. + + “This software is made available by Aklivity, Inc., under the + terms of the Aklivity Community License Agreement, Version 1.0 + located at http://www.Aklivity.io/Aklivity-community-license. BY + INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF + THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.” + + 1.3 Licensee Modifications. Licensee may add its own copyright notices + to modifications made by Licensee and may provide additional or different + license terms and conditions for use, reproduction, or distribution of + Licensee’s modifications. While redistributing the Software or + modifications thereof, Licensee may choose to offer, for a fee or free of + charge, support, warranty, indemnity, or other obligations. Licensee, and + not Aklivity, will be responsible for any such obligations. + + 1.4 No Sublicensing. The License does not include the right to + sublicense the Software, however, each recipient to which Licensee + provides the Software may exercise the Licenses so long as such recipient + agrees to the terms and conditions of this Agreement. + + 2. TERM AND TERMINATION. This Agreement will continue unless and until + earlier terminated as set forth herein. If Licensee breaches any of its + conditions or obligations under this Agreement, this Agreement will + terminate automatically and the License will terminate automatically and + permanently. + + 3. INTELLECTUAL PROPERTY. As between the parties, Aklivity will retain all + right, title, and interest in the Software, and all intellectual property + rights therein. Aklivity hereby reserves all rights not expressly granted + to Licensee in this Agreement. Aklivity hereby reserves all rights in its + trademarks and service marks, and no licenses therein are granted in this + Agreement. + + 4. DISCLAIMER. Aklivity HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND + CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY + DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR + PURPOSE, WITH RESPECT TO THE SOFTWARE. + + 5. LIMITATION OF LIABILITY. Aklivity WILL NOT BE LIABLE FOR ANY DAMAGES OF + ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL, + SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL + APPLY TO THE EXTENT PERMITTED BY APPLICABLE LAW. + + 6.GENERAL. + + 6.1 Governing Law. This Agreement will be governed by and interpreted in + accordance with the laws of the state of California, without reference to + its conflict of laws principles. If Licensee is located within the + United States, all disputes arising out of this Agreement are subject to + the exclusive jurisdiction of courts located in Santa Clara County, + California. USA. If Licensee is located outside of the United States, + any dispute, controversy or claim arising out of or relating to this + Agreement will be referred to and finally determined by arbitration in + accordance with the JAMS International Arbitration Rules. The tribunal + will consist of one arbitrator. The place of arbitration will be Palo + Alto, California. The language to be used in the arbitral proceedings + will be English. Judgment upon the award rendered by the arbitrator may + be entered in any court having jurisdiction thereof. + + 6.2 Assignment. Licensee is not authorized to assign its rights under + this Agreement to any third party. Aklivity may freely assign its rights + under this Agreement to any third party. + + 6.3 Other. This Agreement is the entire agreement between the parties + regarding the subject matter hereof. No amendment or modification of + this Agreement will be valid or binding upon the parties unless made in + writing and signed by the duly authorized representatives of both + parties. In the event that any provision, including without limitation + any condition, of this Agreement is held to be unenforceable, this + Agreement and all licenses and rights granted hereunder will immediately + terminate. Waiver by Aklivity of a breach of any provision of this + Agreement or the failure by Aklivity to exercise any right hereunder + will not be construed as a waiver of any subsequent breach of that right + or as a waiver of any other right. \ No newline at end of file diff --git a/incubator/binding-pgsql/NOTICE b/incubator/binding-pgsql/NOTICE new file mode 100644 index 0000000000..9024d8926d --- /dev/null +++ b/incubator/binding-pgsql/NOTICE @@ -0,0 +1,13 @@ +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +This project includes: + diff --git a/incubator/binding-pgsql/NOTICE.template b/incubator/binding-pgsql/NOTICE.template new file mode 100644 index 0000000000..209ca12f74 --- /dev/null +++ b/incubator/binding-pgsql/NOTICE.template @@ -0,0 +1,13 @@ +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +This project includes: +#GENERATED_NOTICES# diff --git a/incubator/binding-pgsql/mvnw b/incubator/binding-pgsql/mvnw new file mode 100755 index 0000000000..d2f0ea3808 --- /dev/null +++ b/incubator/binding-pgsql/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/incubator/binding-pgsql/mvnw.cmd b/incubator/binding-pgsql/mvnw.cmd new file mode 100644 index 0000000000..b26ab24f03 --- /dev/null +++ b/incubator/binding-pgsql/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/incubator/binding-pgsql/pom.xml b/incubator/binding-pgsql/pom.xml new file mode 100644 index 0000000000..ab39dd7b2f --- /dev/null +++ b/incubator/binding-pgsql/pom.xml @@ -0,0 +1,233 @@ + + + + 4.0.0 + + io.aklivity.zilla + incubator + 0.9.93 + ../pom.xml + + + binding-pgsql + zilla::incubator::binding-pgsql + + + + Aklivity Community License Agreement + https://www.aklivity.io/aklivity-community-license/ + repo + + + + + 0.89 + 0 + + + + + ${project.groupId} + binding-pgsql.spec + ${project.version} + provided + + + ${project.groupId} + engine + ${project.version} + provided + + + ${project.groupId} + engine + test-jar + ${project.version} + test + + + junit + junit + test + + + org.hamcrest + hamcrest-library + test + + + org.mockito + mockito-core + test + + + io.aklivity.k3po + control-junit + test + + + io.aklivity.k3po + lang + test + + + org.openjdk.jmh + jmh-core + test + + + org.openjdk.jmh + jmh-generator-annprocess + test + + + + + + + org.jasig.maven + maven-notice-plugin + + + ${project.groupId} + flyweight-maven-plugin + ${project.version} + + core pgsql protocol + io.aklivity.zilla.runtime.binding.pgsql.internal.types + + + + + generate + + + + + + com.mycila + license-maven-plugin + + + maven-checkstyle-plugin + + + maven-dependency-plugin + + + process-resources + + unpack + + + + + ${project.groupId} + binding-pgsql.spec + + + ^\Qio/aklivity/zilla/specs/binding/pgsql/\E + io/aklivity/zilla/runtime/binding/pgsql/internal/ + + + + + io/aklivity/zilla/specs/binding/pgsql/schema/pgsql.schema.patch.json + ${project.build.directory}/classes + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.moditect + moditect-maven-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + io.aklivity.k3po + k3po-maven-plugin + + + ${project.groupId} + engine + ${project.version} + test-jar + + + ${project.groupId} + engine + ${project.version} + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.jacoco + jacoco-maven-plugin + + + io/aklivity/zilla/runtime/binding/pgsql/internal/types/**/*.class + + + + BUNDLE + + + INSTRUCTION + COVEREDRATIO + ${jacoco.coverage.ratio} + + + CLASS + MISSEDCOUNT + ${jacoco.missed.count} + + + + + + + + io.gatling + maven-shade-plugin + + + + org.agrona:agrona + io.aklivity.zilla:engine + org.openjdk.jmh:jmh-core + net.sf.jopt-simple:jopt-simple + org.apache.commons:commons-math3 + commons-cli:commons-cli + com.github.biboudis:jmh-profilers + + + + + + + diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBinding.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBinding.java new file mode 100644 index 0000000000..7dcc630942 --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBinding.java @@ -0,0 +1,52 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal; + +import java.net.URL; + +import io.aklivity.zilla.runtime.engine.EngineContext; +import io.aklivity.zilla.runtime.engine.binding.Binding; + +public final class PgsqlBinding implements Binding +{ + public static final String NAME = "pgsql"; + + private final PgsqlConfiguration config; + + PgsqlBinding( + PgsqlConfiguration config) + { + this.config = config; + } + + @Override + public String name() + { + return PgsqlBinding.NAME; + } + + @Override + public URL type() + { + return getClass().getResource("schema/pgsql.schema.patch.json"); + } + + @Override + public PgsqlBindingContext supply( + EngineContext context) + { + return new PgsqlBindingContext(config, context); + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBindingContext.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBindingContext.java new file mode 100644 index 0000000000..6d05623bdb --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBindingContext.java @@ -0,0 +1,77 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal; + +import static io.aklivity.zilla.runtime.engine.config.KindConfig.CLIENT; +import static io.aklivity.zilla.runtime.engine.config.KindConfig.SERVER; + +import java.util.EnumMap; +import java.util.Map; + +import io.aklivity.zilla.runtime.binding.pgsql.internal.stream.PgsqlClientFactory; +import io.aklivity.zilla.runtime.binding.pgsql.internal.stream.PgsqlServerFactory; +import io.aklivity.zilla.runtime.binding.pgsql.internal.stream.PgsqlStreamFactory; +import io.aklivity.zilla.runtime.engine.EngineContext; +import io.aklivity.zilla.runtime.engine.binding.BindingContext; +import io.aklivity.zilla.runtime.engine.binding.BindingHandler; +import io.aklivity.zilla.runtime.engine.config.BindingConfig; +import io.aklivity.zilla.runtime.engine.config.KindConfig; + +final class PgsqlBindingContext implements BindingContext +{ + private final Map factories; + + PgsqlBindingContext( + PgsqlConfiguration config, + EngineContext context) + { + final EnumMap factories = new EnumMap<>(KindConfig.class); + factories.put(SERVER, new PgsqlServerFactory(config, context)); + factories.put(CLIENT, new PgsqlClientFactory(config, context)); + this.factories = factories; + } + + @Override + public BindingHandler attach( + BindingConfig binding) + { + PgsqlStreamFactory factory = factories.get(binding.kind); + + if (factory != null) + { + factory.attach(binding); + } + + return factory; + } + + @Override + public void detach( + BindingConfig binding) + { + PgsqlStreamFactory factory = factories.get(binding.kind); + + if (factory != null) + { + factory.detach(binding.id); + } + } + + @Override + public String toString() + { + return String.format("%s %s", getClass().getSimpleName(), factories); + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBindingFactorySpi.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBindingFactorySpi.java new file mode 100644 index 0000000000..6429dacdf8 --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlBindingFactorySpi.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal; + +import io.aklivity.zilla.runtime.common.feature.Incubating; +import io.aklivity.zilla.runtime.engine.Configuration; +import io.aklivity.zilla.runtime.engine.binding.BindingFactorySpi; + +@Incubating +public final class PgsqlBindingFactorySpi implements BindingFactorySpi +{ + @Override + public String type() + { + return PgsqlBinding.NAME; + } + + @Override + public PgsqlBinding create( + Configuration config) + { + return new PgsqlBinding(new PgsqlConfiguration(config)); + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlConfiguration.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlConfiguration.java new file mode 100644 index 0000000000..0d73bddf30 --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/PgsqlConfiguration.java @@ -0,0 +1,34 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal; + +import io.aklivity.zilla.runtime.engine.Configuration; + +public class PgsqlConfiguration extends Configuration +{ + private static final ConfigurationDef PGSQL_CONFIG; + + static + { + final ConfigurationDef config = new ConfigurationDef(String.format("zilla.binding.%s", PgsqlBinding.NAME)); + PGSQL_CONFIG = config; + } + + public PgsqlConfiguration( + Configuration config) + { + super(PGSQL_CONFIG, config); + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/config/PgsqlBindingConfig.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/config/PgsqlBindingConfig.java new file mode 100644 index 0000000000..20afd0fa42 --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/config/PgsqlBindingConfig.java @@ -0,0 +1,48 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal.config; + +import static java.util.stream.Collectors.toList; + +import java.util.List; + +import io.aklivity.zilla.runtime.engine.config.BindingConfig; +import io.aklivity.zilla.runtime.engine.config.KindConfig; + +public final class PgsqlBindingConfig +{ + public final long id; + public final String name; + public final KindConfig kind; + public final List routes; + + public PgsqlBindingConfig( + BindingConfig binding) + { + this.id = binding.id; + this.name = binding.name; + this.kind = binding.kind; + this.routes = binding.routes.stream().map(PgsqlRouteConfig::new).collect(toList()); + } + + public PgsqlRouteConfig resolve( + long authorization) + { + return routes.stream() + .filter(r -> r.authorized(authorization)) + .findFirst() + .orElse(null); + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/config/PgsqlRouteConfig.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/config/PgsqlRouteConfig.java new file mode 100644 index 0000000000..1be96cb669 --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/config/PgsqlRouteConfig.java @@ -0,0 +1,41 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal.config; + +import java.util.function.LongPredicate; + +import io.aklivity.zilla.runtime.engine.config.RouteConfig; + +public final class PgsqlRouteConfig +{ + public final long id; + public final int order; + + private final LongPredicate authorized; + + public PgsqlRouteConfig( + RouteConfig route) + { + this.id = route.id; + this.order = route.order; + this.authorized = route.authorized; + } + + boolean authorized( + long authorization) + { + return authorized.test(authorization); + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlClientFactory.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlClientFactory.java new file mode 100644 index 0000000000..b3626ef285 --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlClientFactory.java @@ -0,0 +1,1681 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal.stream; + +import static io.aklivity.zilla.runtime.engine.buffer.BufferPool.NO_SLOT; +import static java.nio.ByteOrder.BIG_ENDIAN; +import static java.util.Objects.requireNonNull; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.LongUnaryOperator; + +import org.agrona.DirectBuffer; +import org.agrona.MutableDirectBuffer; +import org.agrona.collections.Int2ObjectHashMap; +import org.agrona.collections.Long2ObjectHashMap; +import org.agrona.collections.LongLongConsumer; +import org.agrona.collections.MutableInteger; +import org.agrona.concurrent.UnsafeBuffer; + +import io.aklivity.zilla.runtime.binding.pgsql.internal.PgsqlBinding; +import io.aklivity.zilla.runtime.binding.pgsql.internal.PgsqlConfiguration; +import io.aklivity.zilla.runtime.binding.pgsql.internal.config.PgsqlBindingConfig; +import io.aklivity.zilla.runtime.binding.pgsql.internal.config.PgsqlRouteConfig; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.Array32FW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.OctetsFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlAuthenticationMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlBackendKeyMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlRowDescriptionFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlStartupMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.AbortFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.BeginFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.DataFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.EndFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.ExtensionFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.FlushFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlBeginExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlColumnInfoFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlDataExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlFlushExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlFormat; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlQueryDataExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlStatus; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.ResetFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.WindowFW; +import io.aklivity.zilla.runtime.engine.EngineContext; +import io.aklivity.zilla.runtime.engine.binding.BindingHandler; +import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer; +import io.aklivity.zilla.runtime.engine.buffer.BufferPool; +import io.aklivity.zilla.runtime.engine.config.BindingConfig; + + +public final class PgsqlClientFactory implements PgsqlStreamFactory +{ + private static final Byte MESSAGE_TYPE_TYPE = 'T'; + private static final Byte MESSAGE_TYPE_AUTH = 'R'; + private static final Byte MESSAGE_TYPE_BACKEND_KEY = 'K'; + private static final Byte MESSAGE_TYPE_PARAMETER_STATUS = 'S'; + private static final Byte MESSAGE_TYPE_QUERY = 'Q'; + private static final Byte MESSAGE_TYPE_DATA_ROW = 'D'; + private static final Byte MESSAGE_TYPE_COMPLETION = 'C'; + private static final Byte MESSAGE_TYPE_READY = 'Z'; + private static final Byte MESSAGE_TYPE_TERMINATION = 'X'; + + private static final int AUTHENTICATION_SUCCESS_CODE = 0; + private static final int END_OF_FIELD = 0x00; + + private static final int FLAGS_INIT = 0x02; + private static final int FLAGS_CONT = 0x00; + private static final int FLAGS_FIN = 0x01; + private static final int FLAGS_COMP = 0x03; + + private static final DirectBuffer EMPTY_BUFFER = new UnsafeBuffer(new byte[0]); + private static final OctetsFW EMPTY_OCTETS = new OctetsFW().wrap(EMPTY_BUFFER, 0, 0); + private static final Consumer EMPTY_EXTENSION = ex -> {}; + + private final MutableInteger payloadRemaining = new MutableInteger(0); + + private final BeginFW beginRO = new BeginFW(); + private final DataFW dataRO = new DataFW(); + private final EndFW endRO = new EndFW(); + private final AbortFW abortRO = new AbortFW(); + + private final BeginFW.Builder beginRW = new BeginFW.Builder(); + private final DataFW.Builder dataRW = new DataFW.Builder(); + private final EndFW.Builder endRW = new EndFW.Builder(); + private final AbortFW.Builder abortRW = new AbortFW.Builder(); + private final FlushFW.Builder flushRW = new FlushFW.Builder(); + + private final ResetFW resetRO = new ResetFW(); + private final WindowFW windowRO = new WindowFW(); + + private final ResetFW.Builder resetRW = new ResetFW.Builder(); + private final WindowFW.Builder windowRW = new WindowFW.Builder(); + + private final ExtensionFW extensionRO = new ExtensionFW(); + private final PgsqlBeginExFW pgsqlBeginExRO = new PgsqlBeginExFW(); + private final PgsqlDataExFW pgsqlDataExRO = new PgsqlDataExFW(); + + private final PgsqlDataExFW.Builder dataExRW = new PgsqlDataExFW.Builder(); + private final PgsqlFlushExFW.Builder flushExRW = new PgsqlFlushExFW.Builder(); + private final Array32FW.Builder columnsRW = + new Array32FW.Builder<>(new PgsqlColumnInfoFW.Builder(), new PgsqlColumnInfoFW()); + + private final PgsqlMessageFW messageRO = new PgsqlMessageFW(); + private final PgsqlAuthenticationMessageFW authMessageRO = new PgsqlAuthenticationMessageFW(); + private final PgsqlBackendKeyMessageFW backendKeyMessageRO = new PgsqlBackendKeyMessageFW(); + private final PgsqlRowDescriptionFW rowDescriptionRO = new PgsqlRowDescriptionFW(); + + private final PgsqlStartupMessageFW.Builder startupMessageRW = new PgsqlStartupMessageFW.Builder(); + private final PgsqlMessageFW.Builder messageRW = new PgsqlMessageFW.Builder(); + + private final BufferPool bufferPool; + private final MutableDirectBuffer writeBuffer; + private final MutableDirectBuffer messageBuffer; + private final LongUnaryOperator supplyInitialId; + private final LongUnaryOperator supplyReplyId; + private final BindingHandler streamFactory; + + private final int decodeMax; + + private final Long2ObjectHashMap bindings; + private final int pgsqlTypeId; + + private final PgsqlClientDecoder decodePgsqlMessage = this::decodePgsqlMessage; + private final PgsqlClientDecoder decodePgsqlAuth = this::decodePgsqlMessageAuth; + private final PgsqlClientDecoder decodePgsqlBackendKey = this::decodePgsqlMessageBackendKey; + private final PgsqlClientDecoder decodePgsqlParameterStatus = this::decodePgsqlMessageParameterStatus; + private final PgsqlClientDecoder decodePgsqlType = this::decodePgsqlMessageType; + private final PgsqlClientDecoder decodePgsqlRow = this::decodePgsqlMessageRow; + private final PgsqlClientDecoder decodePgsqlCompletion = this::decodePgsqlMessageCompletion; + private final PgsqlClientDecoder decodePgsqlReady = this::decodePgsqlMessageReady; + private final PgsqlClientDecoder decodePgsqlTermination = this::decodePgsqlMessageTerminator; + private final PgsqlClientDecoder decodePgsqlPayload = this::decodePgsqlMessagePayload; + private final PgsqlClientDecoder decodePgsqlIgnoreOne = this::decodePgsqlIgnoreOne; + private final PgsqlClientDecoder decodePgsqlIgnoreAll = this::decodePgsqlIgnoreAll; + + private final Int2ObjectHashMap decodersByType; + + { + Int2ObjectHashMap decodersByType = new Int2ObjectHashMap<>(); + decodersByType.put(MESSAGE_TYPE_AUTH, decodePgsqlAuth); + decodersByType.put(MESSAGE_TYPE_BACKEND_KEY, decodePgsqlBackendKey); + decodersByType.put(MESSAGE_TYPE_PARAMETER_STATUS, decodePgsqlParameterStatus); + decodersByType.put(MESSAGE_TYPE_TYPE, decodePgsqlType); + decodersByType.put(MESSAGE_TYPE_DATA_ROW, decodePgsqlRow); + decodersByType.put(MESSAGE_TYPE_COMPLETION, decodePgsqlCompletion); + decodersByType.put(MESSAGE_TYPE_READY, decodePgsqlReady); + decodersByType.put(MESSAGE_TYPE_TERMINATION, decodePgsqlTermination); + this.decodersByType = decodersByType; + } + + public PgsqlClientFactory( + PgsqlConfiguration config, + EngineContext context) + { + this.writeBuffer = requireNonNull(context.writeBuffer()); + this.messageBuffer = new UnsafeBuffer(new byte[writeBuffer.capacity()]); + this.supplyInitialId = context::supplyInitialId; + this.supplyReplyId = context::supplyReplyId; + this.streamFactory = context.streamFactory(); + this.bufferPool = context.bufferPool(); + this.decodeMax = bufferPool.slotCapacity(); + + this.bindings = new Long2ObjectHashMap<>(); + + this.pgsqlTypeId = context.supplyTypeId(PgsqlBinding.NAME); + } + + @Override + public void attach( + BindingConfig binding) + { + PgsqlBindingConfig pgsqlBinding = new PgsqlBindingConfig(binding); + bindings.put(binding.id, pgsqlBinding); + } + + @Override + public void detach( + long bindingId) + { + bindings.remove(bindingId); + } + + @Override + public MessageConsumer newStream( + int msgTypeId, + DirectBuffer buffer, + int index, + int length, + MessageConsumer network) + { + final BeginFW begin = beginRO.wrap(buffer, index, index + length); + final long originId = begin.originId(); + final long routedId = begin.routedId(); + final long initialId = begin.streamId(); + final long authorization = begin.authorization(); + final OctetsFW extension = begin.extension(); + final PgsqlBeginExFW pgsqlBeginEx = extension.get(pgsqlBeginExRO::tryWrap); + + final Map parameters = new LinkedHashMap<>(); + pgsqlBeginEx.parameters().forEach(p -> parameters.put(p.name().asString(), p.value().asString())); + + PgsqlBindingConfig binding = bindings.get(routedId); + + MessageConsumer newStream = null; + + if (binding != null) + { + PgsqlRouteConfig route = binding.resolve(authorization); + + if (route != null) + { + newStream = new PgsqlStream( + network, + originId, + routedId, + initialId, + route.id, + parameters)::onApplicationMessage; + } + } + + return newStream; + } + + private final class PgsqlClient + { + private final Map parameters; + private final PgsqlStream stream; + private LongLongConsumer encoder; + private PgsqlClientDecoder decoder; + + private MessageConsumer network; + private final long originId; + private final long routedId; + private long authorization; + + private final long initialId; + private final long replyId; + + private long initialSeq; + private long initialAck; + private int initialMax; + public long initialBudgetId; + private int initialPadding; + + private long replySeq; + private long replyAck; + private int replyMax; + private int replyPad; + private long replyBudgetId; + + private int decodeSlot = NO_SLOT; + private int decodeSlotOffset; + private int decodeSlotReserved; + + private int state; + + private PgsqlClient( + PgsqlStream stream, + long originId, + long routedId, + Map parameters) + { + this.originId = originId; + this.routedId = routedId; + this.initialId = supplyInitialId.applyAsLong(routedId); + this.replyId = supplyReplyId.applyAsLong(initialId); + this.replyMax = decodeMax; + this.parameters = parameters; + + this.stream = stream; + this.encoder = this::doEncodeNetworkStartupMessage; + this.decoder = decodePgsqlMessage; + } + + private void onNetworkMessage( + final int msgTypeId, + final DirectBuffer buffer, + final int index, + final int length) + { + switch (msgTypeId) + { + case BeginFW.TYPE_ID: + final BeginFW begin = beginRO.wrap(buffer, index, index + length); + onNetworkBegin(begin); + break; + case DataFW.TYPE_ID: + final DataFW data = dataRO.wrap(buffer, index, index + length); + onNetworkData(data); + break; + case EndFW.TYPE_ID: + final EndFW end = endRO.wrap(buffer, index, index + length); + onNetworkEnd(end); + break; + case AbortFW.TYPE_ID: + final AbortFW abort = abortRO.wrap(buffer, index, index + length); + onNetworkAbort(abort); + break; + case ResetFW.TYPE_ID: + final ResetFW reset = resetRO.wrap(buffer, index, index + length); + onNetworkReset(reset); + break; + case WindowFW.TYPE_ID: + final WindowFW window = windowRO.wrap(buffer, index, index + length); + onNetworkWindow(window); + break; + default: + // ignore + break; + } + } + + private void onNetworkBegin( + final BeginFW begin) + { + final long sequence = begin.sequence(); + final long acknowledge = begin.acknowledge(); + final int maximum = begin.maximum(); + final long traceId = begin.traceId(); + final long authorization = begin.authorization(); + + assert acknowledge == sequence; + assert sequence >= replySeq; + assert maximum == 0; + + replySeq = sequence; + replyAck = acknowledge; + + state = PgsqlState.openingReply(state); + + doNetworkWindow(traceId, authorization, replyBudgetId, decodeSlotReserved, replyPad); + + encoder.accept(traceId, authorization); + } + + private void onNetworkData( + final DataFW data) + { + final long sequence = data.sequence(); + final long acknowledge = data.acknowledge(); + final long traceId = data.traceId(); + final long budgetId = data.budgetId(); + int reserved = data.reserved(); + authorization = data.authorization(); + + assert acknowledge <= sequence; + assert sequence >= replySeq; + assert acknowledge <= replyAck; + + replySeq = sequence + reserved; + + assert replyAck <= replySeq; + + if (replySeq > replyAck + decodeMax) + { + cleanupNetwork(traceId, authorization); + } + else + { + final OctetsFW payload = data.payload(); + DirectBuffer buffer = payload.buffer(); + int offset = payload.offset(); + int limit = payload.limit(); + + if (decodeSlot != NO_SLOT) + { + final MutableDirectBuffer slotBuffer = bufferPool.buffer(decodeSlot); + slotBuffer.putBytes(decodeSlotOffset, buffer, offset, limit - offset); + decodeSlotOffset += limit - offset; + decodeSlotReserved += reserved; + + buffer = slotBuffer; + offset = 0; + limit = decodeSlotOffset; + reserved = decodeSlotReserved; + } + + decodeNetwork(traceId, authorization, budgetId, reserved, buffer, offset, limit); + } + } + + private void onNetworkEnd( + final EndFW end) + { + final long traceId = end.traceId(); + final long authorization = end.authorization(); + + state = PgsqlState.closeReply(state); + + cleanupDecodeSlotIfNecessary(); + + stream.doApplicationEnd(traceId, authorization); + } + + private void onNetworkAbort( + final AbortFW abort) + { + final long traceId = abort.traceId(); + final long authorization = abort.authorization(); + + state = PgsqlState.closeReply(state); + + stream.doApplicationAbort(traceId, authorization); + } + + private void onNetworkReset( + final ResetFW reset) + { + final long traceId = reset.traceId(); + final long authorization = reset.authorization(); + + state = PgsqlState.closeInitial(state); + + stream.doApplicationReset(traceId, authorization); + } + + private void onNetworkWindow( + final WindowFW window) + { + final long sequence = window.sequence(); + final long acknowledge = window.acknowledge(); + final long traceId = window.traceId(); + final long authorization = window.authorization(); + final long budgetId = window.budgetId(); + final int maximum = window.maximum(); + final int padding = window.padding(); + + assert acknowledge <= sequence; + assert sequence <= initialSeq; + assert acknowledge >= initialAck; + assert maximum >= initialMax; + + initialAck = acknowledge; + initialMax = maximum; + initialBudgetId = budgetId; + initialPadding = padding; + + assert initialAck <= initialSeq; + + state = PgsqlState.openInitial(state); + + encoder.accept(traceId, authorization); + } + + private void doNetworkBegin( + long traceId, + long authorization, + long affinity) + { + state = PgsqlState.openingInitial(state); + + final BeginFW begin = beginRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(initialId) + .sequence(initialSeq) + .acknowledge(initialAck) + .maximum(initialMax) + .traceId(traceId) + .authorization(authorization) + .affinity(affinity) + .extension(EMPTY_OCTETS) + .build(); + + network = streamFactory.newStream(begin.typeId(), begin.buffer(), begin.offset(), begin.sizeof(), + this::onNetworkMessage); + + network.accept(begin.typeId(), begin.buffer(), begin.offset(), begin.sizeof()); + } + + private void doNetworkWindow( + long traceId, + long authorization, + long budgetId, + int pendingAck, + int paddingMin) + { + long replyAckMax = Math.max(replySeq - pendingAck, replyAck); + if (!PgsqlState.replyOpening(stream.state) || + replyAckMax > replyAck || stream.replyMax > replyMax) + { + replyAck = replyAckMax; + replyMax = Math.max(stream.replyMax, replyMax); + replyPad = paddingMin; + assert replyAck <= replySeq; + + state = PgsqlState.openReply(state); + + doWindow(network, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, budgetId, replyPad); + } + } + + private void doNetworkData( + long traceId, + long authorization, + int flags, + long budgetId, + DirectBuffer buffer, + int offset, + int length) + { + final int reserved = length + initialPadding; + + doData(network, originId, routedId, initialId, initialSeq, initialAck, initialMax, traceId, authorization, + flags, budgetId, reserved, buffer, offset, length, EMPTY_EXTENSION); + + initialSeq += reserved; + } + + private void doNetworkResetAndAbort( + long traceId, + long authorization) + { + doNetworkReset(traceId, authorization); + doNetworkAbort(traceId, authorization); + } + + private void doNetworkEnd( + long traceId, + long authorization) + { + state = PgsqlState.closeInitial(state); + + doEnd(network, originId, routedId, initialId, initialSeq, initialAck, initialMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doNetworkAbort( + long traceId, + long authorization) + { + state = PgsqlState.closeReply(state); + + doAbort(network, originId, routedId, initialId, initialSeq, initialAck, initialMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doNetworkReset( + long traceId, + long authorization) + { + state = PgsqlState.closingInitial(state); + + doReset(network, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, EMPTY_OCTETS); + + cleanupDecodeSlotIfNecessary(); + } + + private int decodeNetwork( + long traceId, + long authorization, + long budgetId, + int reserved, + DirectBuffer buffer, + int offset, + int limit) + { + PgsqlClientDecoder previous = null; + int progress = offset; + while (progress <= limit && previous != decoder) + { + previous = decoder; + progress = decoder.decode(this, traceId, authorization, budgetId, buffer, progress, limit); + } + + if (progress < limit) + { + if (decodeSlot == NO_SLOT) + { + decodeSlot = bufferPool.acquire(replyId); + } + + if (decodeSlot == NO_SLOT) + { + cleanupNetwork(traceId, authorization); + } + else + { + final MutableDirectBuffer decodeBuffer = bufferPool.buffer(decodeSlot); + decodeBuffer.putBytes(0, buffer, progress, limit - progress); + decodeSlotOffset = limit - progress; + decodeSlotReserved = (int)((long) reserved * (limit - progress) / (limit - offset)); + } + } + else + { + cleanupDecodeSlotIfNecessary(); + } + + if (!PgsqlState.replyClosed(state)) + { + doNetworkWindow(traceId, authorization, budgetId, decodeSlotReserved, replyPad); + } + + return progress; + } + + private void onDecodeMessageType( + long traceId, + long authorization, + Array32FW columns) + { + Consumer typeEx = e -> e.set((b, o, l) -> flushExRW.wrap(b, o, l) + .typeId(pgsqlTypeId) + .type(t -> t.columns(columns)) + .build().sizeof()); + + stream.doApplicationFlush(traceId, authorization, decodeSlotReserved, typeEx); + } + + private void doEncodeNetworkWindow( + long traceId, + long authorization) + { + stream.doApplicationWindow(traceId, authorization, initialBudgetId, + (int)(initialSeq - initialAck), initialPadding); + } + + private void doEncodeNetworkStartupMessage( + long traceId, + long authorization) + { + if (PgsqlState.replyOpening(state)) + { + int startupOffset = 0; + + PgsqlStartupMessageFW startupMessage = + startupMessageRW.wrap(messageBuffer, startupOffset, messageBuffer.capacity()) + .length(0) + .majorVersion(3) + .minorVersion(0) + .build(); + startupOffset = startupMessage.limit(); + + for (Map.Entry parameter : parameters.entrySet()) + { + messageBuffer.putBytes(startupOffset, parameter.getKey().getBytes()); + startupOffset += parameter.getKey().length(); + messageBuffer.putBytes(startupOffset, parameter.getValue().getBytes()); + startupOffset += parameter.getValue().length(); + } + + messageBuffer.putByte(startupOffset, (byte) END_OF_FIELD); + startupOffset += Byte.BYTES; + + messageBuffer.putInt(0, startupOffset, BIG_ENDIAN); + + doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, startupOffset); + + encoder = this::doEncodeNetworkWindow; + } + } + + private void onDecodeMessageRow( + long traceId, + long authorization, + int flags, + int deferred, + DirectBuffer buffer, + int offset, + int limit) + { + Consumer rowEx = e -> e.set((b, o, l) -> dataExRW.wrap(b, o, l) + .typeId(pgsqlTypeId) + .row(q -> q.deferred(deferred)) + .build().sizeof()); + + stream.doApplicationData(traceId, authorization, flags, buffer, offset, limit, rowEx); + } + + private void onDecodeMessageCompletion( + long traceId, + long authorization, + DirectBuffer buffer, + int offset, + int length) + { + Consumer completionEx = e -> e.set((b, o, l) -> flushExRW.wrap(b, o, l) + .typeId(pgsqlTypeId) + .completion(c -> c.tag(buffer, offset, length)) + .build().sizeof()); + + stream.doApplicationFlush(traceId, authorization, decodeSlotReserved, completionEx); + } + + private void onDecodeMessageReady( + long traceId, + long authorization, + PgsqlStatus status) + { + encoder = this::doEncodeNetworkWindow; + encoder.accept(traceId, authorization); + + if (PgsqlState.replyOpening(stream.state)) + { + Consumer readyEx = e -> e.set((b, o, l) -> flushExRW.wrap(b, o, l) + .typeId(pgsqlTypeId) + .ready(r -> r.status(s -> s.set(status))) + .build().sizeof()); + + stream.doApplicationFlush(traceId, authorization, decodeSlotReserved, readyEx); + } + else + { + stream.doApplicationBegin(traceId, authorization); + } + + } + + private void onDecodeMessageTermination( + long traceId, + long authorization) + { + doNetworkEnd(traceId, authorization); + stream.doApplicationEnd(traceId, authorization); + } + + private void cleanupNetwork( + long traceId, + long authorization) + { + cleanup(traceId, authorization, this::doNetworkResetAndAbort); + } + + private void cleanup( + long traceId, + long authorization, + LongLongConsumer cleanupHandler) + { + cleanupHandler.accept(traceId, authorization); + stream.doApplicationAbortAndReset(traceId, authorization); + } + + private void cleanupDecodeSlotIfNecessary() + { + if (decodeSlot != NO_SLOT) + { + bufferPool.release(decodeSlot); + decodeSlot = NO_SLOT; + decodeSlotOffset = 0; + decodeSlotReserved = 0; + } + } + } + + private final class PgsqlStream + { + private final PgsqlClient client; + + private MessageConsumer application; + + private final long initialId; + private final long replyId; + private final long originId; + private final long routedId; + + private long initialSeq; + private long initialAck; + private int initialMax; + private int initialPad; + private long initialBudgetId; + + private long replySeq; + private long replyAck; + private int replyMax; + private int replyPadding; + private long replyBudgetId; + + private int state; + + private PgsqlStream( + MessageConsumer application, + long originId, + long routedId, + long initialId, + long resolvedId, + Map parameters) + { + this.application = application; + this.originId = originId; + this.routedId = routedId; + this.initialId = initialId; + this.replyId = supplyReplyId.applyAsLong(initialId); + + this.client = new PgsqlClient(this, originId, resolvedId, parameters); + } + + private void onApplicationMessage( + final int msgTypeId, + final DirectBuffer buffer, + final int index, + final int length) + { + switch (msgTypeId) + { + case BeginFW.TYPE_ID: + final BeginFW begin = beginRO.wrap(buffer, index, index + length); + onApplicationBegin(begin); + break; + case DataFW.TYPE_ID: + final DataFW data = dataRO.wrap(buffer, index, index + length); + onApplicationData(data); + break; + case EndFW.TYPE_ID: + final EndFW end = endRO.wrap(buffer, index, index + length); + onApplicationEnd(end); + break; + case AbortFW.TYPE_ID: + final AbortFW abort = abortRO.wrap(buffer, index, index + length); + onApplicationAbort(abort); + break; + case ResetFW.TYPE_ID: + final ResetFW reset = resetRO.wrap(buffer, index, index + length); + onApplicationReset(reset); + break; + case WindowFW.TYPE_ID: + final WindowFW window = windowRO.wrap(buffer, index, index + length); + onApplicationWindow(window); + break; + default: + // ignore + break; + } + } + + private void onApplicationBegin( + final BeginFW begin) + { + final long traceId = begin.traceId(); + final long authorization = begin.authorization(); + final long affinity = begin.affinity(); + + state = PgsqlState.openingInitial(state); + + client.doNetworkBegin(traceId, authorization, affinity); + } + + private void onApplicationData( + final DataFW data) + { + final long sequence = data.sequence(); + final long acknowledge = data.acknowledge(); + final long traceId = data.traceId(); + final long authorization = data.authorization(); + final long budgetId = data.budgetId(); + final int reserved = data.reserved(); + + assert acknowledge <= sequence; + assert sequence >= initialSeq; + assert acknowledge <= initialAck; + assert budgetId == client.initialBudgetId; + + initialSeq = sequence + reserved; + + assert initialAck <= initialSeq; + + if (initialSeq > initialAck + initialMax) + { + client.cleanupNetwork(traceId, authorization); + } + else + { + final OctetsFW extension = data.extension(); + final OctetsFW payload = data.payload(); + final ExtensionFW dataEx = extension.get(extensionRO::tryWrap); + + final PgsqlDataExFW pgsqlDataEx = dataEx != null && dataEx.typeId() == pgsqlTypeId ? + extension.get(pgsqlDataExRO::tryWrap) : null; + + if (pgsqlDataEx != null && + pgsqlDataEx.kind() == PgsqlDataExFW.KIND_QUERY) + { + PgsqlQueryDataExFW query = pgsqlDataEx.query(); + doEncodeQuery(traceId, authorization, query.deferred(), payload); + } + else + { + client.doNetworkData(traceId, authorization, FLAGS_COMP, 0L, payload.value(), 0, payload.sizeof()); + } + } + } + + private void onApplicationEnd( + final EndFW end) + { + final long traceId = end.traceId(); + final long authorization = end.authorization(); + + state = PgsqlState.closeInitial(state); + + if (!PgsqlState.closed(client.state)) + { + doEncodeTermination(traceId, authorization); + client.doNetworkEnd(traceId, authorization); + } + } + + private void onApplicationAbort( + final AbortFW abort) + { + final long traceId = abort.traceId(); + final long authorization = abort.authorization(); + + state = PgsqlState.closeInitial(state); + + client.doNetworkAbort(traceId, authorization); + } + + private void onApplicationReset( + final ResetFW reset) + { + final long traceId = reset.traceId(); + final long authorization = reset.authorization(); + + state = PgsqlState.closeReply(state); + + client.doNetworkReset(traceId, authorization); + } + + private void onApplicationWindow( + final WindowFW window) + { + final long sequence = window.sequence(); + final long acknowledge = window.acknowledge(); + final int maximum = window.maximum(); + final long traceId = window.traceId(); + final long authorization = window.authorization(); + final long budgetId = window.budgetId(); + final int padding = window.padding(); + + assert acknowledge <= sequence; + assert acknowledge >= replyAck; + assert maximum + acknowledge >= replyMax + replyAck; + + replyBudgetId = budgetId; + replyAck = acknowledge; + replyMax = maximum; + replyPadding = padding; + + assert replyAck <= replySeq; + + client.doNetworkWindow(traceId, authorization, budgetId, (int)(replySeq - replyAck), replyPadding); + } + + private void doApplicationBegin( + long traceId, + long authorization) + { + doBegin(application, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, 0L, EMPTY_OCTETS); + + state = PgsqlState.openingReply(state); + } + + private void doApplicationData( + long traceId, + long authorization, + int flags, + DirectBuffer buffer, + int offset, + int limit, + Consumer extension) + { + final int length = limit - offset; + final int reserved = length + initialPad; + + doData(application, originId, routedId, replyId, replySeq, replyAck, replyMax, traceId, authorization, + flags, replyBudgetId, reserved, buffer, offset, length, extension); + + replySeq += reserved; + assert replySeq <= replyAck + replyMax; + } + + private void doApplicationEnd( + long traceId, + long authorization) + { + state = PgsqlState.closeInitial(state); + + doEnd(application, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doApplicationAbort( + long traceId, + long authorization) + { + state = PgsqlState.closeReply(state); + + doAbort(application, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doApplicationReset( + long traceId, + long authorization) + { + state = PgsqlState.closeInitial(state); + + doReset(application, originId, routedId, initialId, initialSeq, initialAck, initialMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doApplicationAbortAndReset( + long traceId, + long authorization) + { + doApplicationAbort(traceId, authorization); + doApplicationReset(traceId, authorization); + } + + private void doApplicationWindow( + long traceId, + long authorization, + long budgetId, + int pendingAck, + int paddingMin) + { + long initialAckMax = Math.max(initialSeq - pendingAck, initialAck); + if (initialAckMax > initialAck || client.initialMax > initialMax) + { + initialAck = initialAckMax; + initialMax = client.initialMax; + assert initialAck <= initialSeq; + + int initialPad = paddingMin; + + state = PgsqlState.openInitial(state); + + doWindow(application, originId, routedId, initialId, initialSeq, initialAck, initialMax, + traceId, authorization, budgetId, initialPad); + } + } + + public void doApplicationFlush( + long traceId, + long authorization, + int reserved, + Consumer extension) + { + replySeq = client.replySeq; + + doFlush(application, originId, routedId, replyId, replySeq, replyAck, replyMax, traceId, + authorization, replyBudgetId, reserved, extension); + } + + private void doEncodeQuery( + long traceId, + long authorization, + int deferred, + OctetsFW query) + { + final DirectBuffer queryBuffer = query.value(); + final int rowSize = queryBuffer.capacity(); + + int queryOffset = 0; + + PgsqlMessageFW messageQuery = messageRW.wrap(messageBuffer, queryOffset, messageBuffer.capacity()) + .type(MESSAGE_TYPE_QUERY) + .length(rowSize + Integer.BYTES + deferred) + .build(); + queryOffset = messageQuery.limit(); + + messageBuffer.putBytes(queryOffset, queryBuffer, 0, rowSize); + queryOffset += rowSize; + + client.doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, queryOffset); + } + + private void doEncodeTermination( + long traceId, + long authorization) + { + PgsqlMessageFW messageTermination = messageRW.wrap(messageBuffer, 0, messageBuffer.capacity()) + .type(MESSAGE_TYPE_TERMINATION) + .length(Integer.BYTES) + .build(); + + client.doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, messageTermination.limit()); + } + } + + private void doBegin( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final long affinity, + final OctetsFW extension) + { + final BeginFW begin = beginRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .affinity(affinity) + .extension(extension) + .build(); + + receiver.accept(begin.typeId(), begin.buffer(), begin.offset(), begin.sizeof()); + } + + private void doData( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final int flags, + final long budgetId, + final int reserved, + DirectBuffer buffer, + int offset, + int length, + Consumer extension) + { + final DataFW data = dataRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .flags(flags) + .budgetId(budgetId) + .reserved(reserved) + .payload(buffer, offset, length) + .extension(extension) + .build(); + + receiver.accept(data.typeId(), data.buffer(), data.offset(), data.sizeof()); + } + + private void doFlush( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final long budgetId, + final int reserved, + Consumer extension) + { + final FlushFW flush = flushRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .budgetId(budgetId) + .reserved(reserved) + .extension(extension) + .build(); + + receiver.accept(flush.typeId(), flush.buffer(), flush.offset(), flush.sizeof()); + } + + private void doAbort( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final OctetsFW extension) + { + final AbortFW abort = abortRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .extension(extension) + .build(); + + receiver.accept(abort.typeId(), abort.buffer(), abort.offset(), abort.sizeof()); + } + + private void doEnd( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final OctetsFW extension) + { + final EndFW end = endRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .extension(extension) + .build(); + + receiver.accept(end.typeId(), end.buffer(), end.offset(), end.sizeof()); + } + + private void doReset( + final MessageConsumer sender, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final OctetsFW extension) + { + final ResetFW reset = resetRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .extension(extension) + .build(); + + sender.accept(reset.typeId(), reset.buffer(), reset.offset(), reset.sizeof()); + } + + private void doWindow( + final MessageConsumer sender, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + long authorization, + final long budgetId, + final int padding) + { + final WindowFW window = windowRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .budgetId(budgetId) + .padding(padding) + .build(); + + sender.accept(window.typeId(), window.buffer(), window.offset(), window.sizeof()); + } + + private int decodePgsqlMessage( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progress = offset; + + final PgsqlMessageFW pgsqlMessage = messageRO.tryWrap(buffer, offset, limit); + + if (pgsqlMessage != null) + { + final int type = pgsqlMessage.type(); + + final PgsqlClientDecoder decoder = decodersByType.getOrDefault(type, decodePgsqlIgnoreOne); + client.decoder = decoder; + } + + return progress; + } + + private int decodePgsqlMessageAuth( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progress = offset; + + final PgsqlAuthenticationMessageFW pgsqlAuth = authMessageRO.tryWrap(buffer, offset, limit); + + if (pgsqlAuth != null) + { + client.decoder = pgsqlAuth.authenticationType() == AUTHENTICATION_SUCCESS_CODE + ? decodePgsqlBackendKey + : decodePgsqlIgnoreAll; + progress = pgsqlAuth.limit(); + } + + return progress; + } + + private int decodePgsqlMessageBackendKey( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progress = offset; + + final PgsqlBackendKeyMessageFW pgsqlBackendKey = backendKeyMessageRO.tryWrap(buffer, offset, limit); + + if (pgsqlBackendKey != null) + { + client.decoder = decodePgsqlParameterStatus; + progress = pgsqlBackendKey.limit(); + } + + return progress; + } + + private int decodePgsqlMessageParameterStatus( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progress = offset; + + final PgsqlMessageFW pgsqlParameter = messageRO.tryWrap(buffer, offset, limit); + + if (pgsqlParameter != null) + { + client.decoder = decodePgsqlMessage; + progress += pgsqlParameter.length() + Byte.BYTES; + } + + return progress; + } + + + private int decodePgsqlMessageType( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progressOffset = offset; + + final PgsqlMessageFW pgsqlType = messageRO.tryWrap(buffer, offset, limit); + + if (pgsqlType != null) + { + progressOffset = pgsqlType.limit(); + + short fieldCount = buffer.getShort(progressOffset, BIG_ENDIAN); + progressOffset += Short.BYTES; + + columnsRW.wrap(messageBuffer, 0, messageBuffer.capacity()); + + columns: + for (int i = 0; i < fieldCount; i++) + { + final int nameOffset = progressOffset; + final int nameLength = getLengthOfString(buffer, progressOffset); + + if (nameLength == -1) + { + break columns; + } + + progressOffset += nameLength; + + PgsqlRowDescriptionFW description = rowDescriptionRO.tryWrap(buffer, progressOffset, limit); + + if (description == null) + { + break columns; + } + + columnsRW.item(c -> c + .name(buffer, nameOffset, nameLength) + .tableOid(description.tableOid()) + .index(description.index()) + .typeOid(description.typeOid()) + .length(description.length()) + .modifier(description.modifier()) + .format(f -> f.set(PgsqlFormat.valueOf(description.format())))); + + progressOffset = description.limit(); + } + + Array32FW columns = columnsRW.build(); + + if (columns.fieldCount() == fieldCount) + { + client.onDecodeMessageType(traceId, authorization, columns); + + client.decoder = decodePgsqlMessage; + } + } + + return progressOffset; + } + + private int decodePgsqlMessageRow( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progressOffset = offset; + + final PgsqlMessageFW pgsqlRow = messageRO.tryWrap(buffer, progressOffset, limit); + if (pgsqlRow != null) + { + progressOffset = pgsqlRow.limit(); + + final int rowSize = pgsqlRow.length() - Integer.BYTES; + payloadRemaining.set(rowSize); + + final int length = Math.min(payloadRemaining.value, limit - progressOffset); + + if (length > 0) + { + final int flags = rowSize == length ? FLAGS_COMP : FLAGS_INIT; + final int deferred = rowSize - length; + + client.onDecodeMessageRow(traceId, authorization, flags, deferred, + buffer, progressOffset, progressOffset + length); + progressOffset += length; + payloadRemaining.set(rowSize - length); + + assert payloadRemaining.get() >= 0; + + client.decoder = rowSize == length + ? decodePgsqlMessage + : decodePgsqlPayload; + } + } + + return progressOffset; + } + + private int decodePgsqlMessageCompletion( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progressOffset = offset; + + final PgsqlMessageFW pgsqlCompletion = messageRO.tryWrap(buffer, offset, limit); + + if (pgsqlCompletion != null) + { + progressOffset = pgsqlCompletion.limit(); + + final int completionSize = pgsqlCompletion.length() - Integer.BYTES; + payloadRemaining.set(completionSize); + final int length = Math.min(payloadRemaining.value, limit - progressOffset); + + client.onDecodeMessageCompletion(traceId, authorization, buffer, progressOffset, length); + progressOffset += length; + payloadRemaining.set(completionSize - length); + + client.decoder = completionSize == length + ? decodePgsqlMessage + : decodePgsqlPayload; + } + + + return progressOffset; + } + + private int decodePgsqlMessageReady( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progressOffset = offset; + + final PgsqlMessageFW pgsqlReady = messageRO.tryWrap(buffer, offset, limit); + + if (pgsqlReady != null && + limit - pgsqlReady.limit() >= Byte.BYTES) + { + progressOffset = pgsqlReady.limit(); + + client.onDecodeMessageReady(traceId, authorization, PgsqlStatus.valueOf(buffer.getByte(progressOffset))); + progressOffset += Byte.BYTES; + + client.decoder = decodePgsqlMessage; + } + + return progressOffset; + } + + private int decodePgsqlMessageTerminator( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progressOffset = offset; + + final PgsqlMessageFW pgsqlTerminate = messageRO.tryWrap(buffer, offset, limit); + + if (pgsqlTerminate != null) + { + client.onDecodeMessageTermination(traceId, authorization); + + client.decoder = decodePgsqlIgnoreAll; + progressOffset = limit; + } + + return progressOffset; + } + + private int decodePgsqlMessagePayload( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + final int payloadSize = payloadRemaining.get(); + final int length = Math.min(payloadSize, limit - offset); + + final int flags = payloadSize == length ? FLAGS_FIN : FLAGS_CONT; + + client.stream.doApplicationData(traceId, authorization, flags, buffer, offset, offset + limit, + EMPTY_EXTENSION); + payloadRemaining.set(payloadSize - length); + + assert payloadRemaining.get() >= 0; + + if (payloadSize == length) + { + client.decoder = decodePgsqlMessage; + } + + return length; + } + + private int decodePgsqlIgnoreOne( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + final PgsqlMessageFW messageType = messageRO.wrap(buffer, offset, limit); + final int progress = messageType.limit() + messageType.length(); + + client.decoder = decodePgsqlMessage; + return progress; + } + + private int decodePgsqlIgnoreAll( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + return limit; + } + + @FunctionalInterface + private interface PgsqlClientDecoder + { + int decode( + PgsqlClient client, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit); + } + + private int getLengthOfString( + DirectBuffer buffer, + int offset) + { + int length = -1; + loop: + for (int progress = offset; progress < buffer.capacity(); progress++) + { + if (buffer.getByte(progress) == END_OF_FIELD) + { + length = progress - offset + 1; + break loop; + } + } + return length; + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlServerFactory.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlServerFactory.java new file mode 100644 index 0000000000..9c843b17ea --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlServerFactory.java @@ -0,0 +1,1650 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal.stream; + +import static io.aklivity.zilla.runtime.engine.buffer.BufferPool.NO_SLOT; +import static java.nio.ByteOrder.BIG_ENDIAN; +import static java.util.Objects.requireNonNull; + +import java.util.function.Consumer; +import java.util.function.LongUnaryOperator; + +import org.agrona.DirectBuffer; +import org.agrona.MutableDirectBuffer; +import org.agrona.collections.Int2ObjectHashMap; +import org.agrona.collections.Long2ObjectHashMap; +import org.agrona.collections.LongLongConsumer; +import org.agrona.collections.MutableInteger; +import org.agrona.concurrent.UnsafeBuffer; + +import io.aklivity.zilla.runtime.binding.pgsql.internal.PgsqlBinding; +import io.aklivity.zilla.runtime.binding.pgsql.internal.PgsqlConfiguration; +import io.aklivity.zilla.runtime.binding.pgsql.internal.config.PgsqlBindingConfig; +import io.aklivity.zilla.runtime.binding.pgsql.internal.config.PgsqlRouteConfig; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.Array32FW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.OctetsFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlAuthenticationMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlBackendKeyMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlCancelRequestMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlSslRequestFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlSslResponseFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.codec.PgsqlStartupMessageFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.AbortFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.BeginFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.DataFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.EndFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.ExtensionFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.FlushFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlBeginExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlCompletedFlushExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlDataExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlFlushExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlParameterFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlReadyFlushExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlStatus; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.PgsqlTypeFlushExFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.ResetFW; +import io.aklivity.zilla.runtime.binding.pgsql.internal.types.stream.WindowFW; +import io.aklivity.zilla.runtime.engine.EngineContext; +import io.aklivity.zilla.runtime.engine.binding.BindingHandler; +import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer; +import io.aklivity.zilla.runtime.engine.buffer.BufferPool; +import io.aklivity.zilla.runtime.engine.config.BindingConfig; + +public final class PgsqlServerFactory implements PgsqlStreamFactory +{ + private static final Byte MESSAGE_TYPE_TYPE = 'T'; + private static final Byte MESSAGE_TYPE_QUERY = 'Q'; + private static final Byte MESSAGE_TYPE_DATA_ROW = 'D'; + private static final Byte MESSAGE_TYPE_COMPLETION = 'C'; + private static final Byte MESSAGE_TYPE_READY = 'Z'; + private static final Byte MESSAGE_TYPE_TERMINATE = 'X'; + private static final Byte MESSAGE_TYPE_PARAMETER_STATUS = 'S'; + + private static final int SSL_REQUEST_CODE = 80877103; + private static final int CANCEL_REQUEST_CODE = 80877102; + private static final int END_OF_FIELD = 0x00; + + private static final int FLAGS_INIT = 0x02; + private static final int FLAGS_CONT = 0x00; + private static final int FLAGS_FIN = 0x01; + private static final int FLAGS_COMP = 0x03; + + private static final DirectBuffer EMPTY_BUFFER = new UnsafeBuffer(new byte[0]); + private static final OctetsFW EMPTY_OCTETS = new OctetsFW().wrap(EMPTY_BUFFER, 0, 0); + private static final Consumer EMPTY_EXTENSION = ex -> {}; + + private final MutableInteger payloadRemaining = new MutableInteger(0); + private final MutableInteger progress = new MutableInteger(0); + + private final BeginFW beginRO = new BeginFW(); + private final DataFW dataRO = new DataFW(); + private final EndFW endRO = new EndFW(); + private final AbortFW abortRO = new AbortFW(); + private final FlushFW flushRO = new FlushFW(); + + private final BeginFW.Builder beginRW = new BeginFW.Builder(); + private final DataFW.Builder dataRW = new DataFW.Builder(); + private final EndFW.Builder endRW = new EndFW.Builder(); + private final AbortFW.Builder abortRW = new AbortFW.Builder(); + + private final ResetFW resetRO = new ResetFW(); + private final WindowFW windowRO = new WindowFW(); + + private final ResetFW.Builder resetRW = new ResetFW.Builder(); + private final WindowFW.Builder windowRW = new WindowFW.Builder(); + + private final ExtensionFW extensionRO = new ExtensionFW(); + private final PgsqlDataExFW pgsqlDataExRO = new PgsqlDataExFW(); + private final PgsqlFlushExFW pgsqlFlushExRO = new PgsqlFlushExFW(); + + private final PgsqlBeginExFW.Builder beginExRW = new PgsqlBeginExFW.Builder(); + private final PgsqlDataExFW.Builder dataExRW = new PgsqlDataExFW.Builder(); + + private final PgsqlMessageFW messageRO = new PgsqlMessageFW(); + private final PgsqlSslRequestFW sslRequestRO = new PgsqlSslRequestFW(); + private final PgsqlStartupMessageFW startupMessageRO = new PgsqlStartupMessageFW(); + private final PgsqlCancelRequestMessageFW cancelReqMessageRO = new PgsqlCancelRequestMessageFW(); + + private final PgsqlMessageFW.Builder messageRW = new PgsqlMessageFW.Builder(); + private final PgsqlSslResponseFW.Builder sslResponseRW = new PgsqlSslResponseFW.Builder(); + private final PgsqlAuthenticationMessageFW.Builder authMessageRW = new PgsqlAuthenticationMessageFW.Builder(); + private final PgsqlBackendKeyMessageFW.Builder backendKeyMessageRW = new PgsqlBackendKeyMessageFW.Builder(); + + private final Array32FW.Builder parametersRW = + new Array32FW.Builder<>(new PgsqlParameterFW.Builder(), new PgsqlParameterFW()); + + private final BufferPool bufferPool; + private final MutableDirectBuffer writeBuffer; + private final MutableDirectBuffer messageBuffer; + private final LongUnaryOperator supplyInitialId; + private final LongUnaryOperator supplyReplyId; + private final BindingHandler streamFactory; + + private final int decodeMax; + + private final Long2ObjectHashMap bindings; + private final int pgsqlTypeId; + + private final PgsqlServerDecoder decodePgsqlInitial = this::decodePgsqlInitial; + private final PgsqlServerDecoder decodePgsqlSslRequest = this::decodePgsqlSslRequest; + private final PgsqlServerDecoder decodePgsqlStartupMessage = this::decodePgsqlStartupMessage; + private final PgsqlServerDecoder decodePgsqlCancelRequest = this::decodePgsqlCancelRequest; + private final PgsqlServerDecoder decodePgsqlMessageType = this::decodePgsqlMessageType; + private final PgsqlServerDecoder decodePgsqlQuery = this::decodePgsqlMessageQuery; + private final PgsqlServerDecoder decodePgsqlPayload = this::decodePgsqlMessagePayload; + private final PgsqlServerDecoder decodePgsqlTermination = this::decodePgsqlMessageTerminator; + private final PgsqlServerDecoder decodePgsqlIgnoreOne = this::decodePgsqlIgnoreOne; + private final PgsqlServerDecoder decodePgsqlIgnoreAll = this::decodePgsqlIgnoreAll; + + private final Int2ObjectHashMap decodersByType; + { + Int2ObjectHashMap decodersByType = new Int2ObjectHashMap<>(); + decodersByType.put(MESSAGE_TYPE_QUERY, decodePgsqlQuery); + decodersByType.put(MESSAGE_TYPE_TERMINATE, decodePgsqlTermination); + this.decodersByType = decodersByType; + } + + public PgsqlServerFactory( + PgsqlConfiguration config, + EngineContext context) + { + this.writeBuffer = requireNonNull(context.writeBuffer()); + this.messageBuffer = new UnsafeBuffer(new byte[writeBuffer.capacity()]); + this.supplyInitialId = context::supplyInitialId; + this.supplyReplyId = context::supplyReplyId; + this.streamFactory = context.streamFactory(); + this.bufferPool = context.bufferPool(); + this.decodeMax = bufferPool.slotCapacity(); + + this.bindings = new Long2ObjectHashMap<>(); + + this.pgsqlTypeId = context.supplyTypeId(PgsqlBinding.NAME); + } + + @Override + public void attach( + BindingConfig binding) + { + PgsqlBindingConfig pgsqlBinding = new PgsqlBindingConfig(binding); + bindings.put(binding.id, pgsqlBinding); + } + + @Override + public void detach( + long bindingId) + { + bindings.remove(bindingId); + } + + @Override + public MessageConsumer newStream( + int msgTypeId, + DirectBuffer buffer, + int index, + int length, + MessageConsumer network) + { + final BeginFW begin = beginRO.wrap(buffer, index, index + length); + final long originId = begin.originId(); + final long routedId = begin.routedId(); + final long initialId = begin.streamId(); + final long affinity = begin.affinity(); + final long authorization = begin.authorization(); + + PgsqlBindingConfig binding = bindings.get(routedId); + + MessageConsumer newStream = null; + + if (binding != null) + { + PgsqlRouteConfig route = binding.resolve(authorization); + + if (route != null) + { + newStream = new PgsqlServer( + network, + originId, + routedId, + initialId, + affinity, + route.id)::onNetworkMessage; + } + } + + return newStream; + } + + private final class PgsqlServer + { + private final PgsqlStream stream; + private PgsqlServerDecoder decoder; + + private final MessageConsumer network; + private final long originId; + private final long routedId; + private long authorization; + + private final long initialId; + private final long replyId; + private final long affinity; + + private long initialSeq; + private long initialAck; + private int initialMax; + private int initialPadding; + + private long replySeq; + private long replyAck; + private int replyMax; + private int replyPad; + private long replyBudgetId; + + private int decodeSlot = NO_SLOT; + private int decodeSlotOffset; + private int decodeSlotReserved; + + private int state; + + private PgsqlServer( + MessageConsumer network, + long originId, + long routedId, + long initialId, + long affinity, + long resolvedId) + { + this.network = network; + this.originId = originId; + this.routedId = routedId; + this.initialId = initialId; + this.replyId = supplyReplyId.applyAsLong(initialId); + this.affinity = affinity; + this.initialMax = decodeMax; + + this.stream = new PgsqlStream(this, routedId, resolvedId); + this.decoder = decodePgsqlInitial; + } + + private void onNetworkMessage( + final int msgTypeId, + final DirectBuffer buffer, + final int index, + final int length) + { + switch (msgTypeId) + { + case BeginFW.TYPE_ID: + final BeginFW begin = beginRO.wrap(buffer, index, index + length); + onNetworkBegin(begin); + break; + case DataFW.TYPE_ID: + final DataFW data = dataRO.wrap(buffer, index, index + length); + onNetworkData(data); + break; + case EndFW.TYPE_ID: + final EndFW end = endRO.wrap(buffer, index, index + length); + onNetworkEnd(end); + break; + case AbortFW.TYPE_ID: + final AbortFW abort = abortRO.wrap(buffer, index, index + length); + onNetworkAbort(abort); + break; + case ResetFW.TYPE_ID: + final ResetFW reset = resetRO.wrap(buffer, index, index + length); + onNetworkReset(reset); + break; + case WindowFW.TYPE_ID: + final WindowFW window = windowRO.wrap(buffer, index, index + length); + onNetworkWindow(window); + break; + default: + // ignore + break; + } + } + + private void onNetworkBegin( + final BeginFW begin) + { + final long sequence = begin.sequence(); + final long acknowledge = begin.acknowledge(); + final int maximum = begin.maximum(); + final long traceId = begin.traceId(); + final long authorization = begin.authorization(); + final long affinity = begin.affinity(); + + assert acknowledge == sequence; + assert sequence >= initialSeq; + assert maximum == 0; + + initialSeq = sequence; + initialAck = acknowledge; + + state = PgsqlState.openingInitial(state); + + doNetworkWindow(traceId, authorization, 0L, 0, 0); + doNetworkBegin(traceId, authorization, affinity); + } + + private void onNetworkData( + final DataFW data) + { + final long sequence = data.sequence(); + final long acknowledge = data.acknowledge(); + final long traceId = data.traceId(); + final long budgetId = data.budgetId(); + authorization = data.authorization(); + + assert acknowledge <= sequence; + assert sequence >= initialSeq; + assert acknowledge <= initialAck; + + initialSeq = sequence + data.reserved(); + + assert initialAck <= initialSeq; + + if (initialSeq > initialAck + decodeMax) + { + cleanupNetwork(traceId, authorization); + } + else + { + final OctetsFW payload = data.payload(); + DirectBuffer buffer = payload.buffer(); + int offset = payload.offset(); + int limit = payload.limit(); + int reserved = data.reserved(); + + if (decodeSlot != NO_SLOT) + { + final MutableDirectBuffer slotBuffer = bufferPool.buffer(decodeSlot); + slotBuffer.putBytes(decodeSlotOffset, buffer, offset, limit - offset); + decodeSlotOffset += limit - offset; + decodeSlotReserved += reserved; + + buffer = slotBuffer; + offset = 0; + limit = decodeSlotOffset; + reserved = decodeSlotReserved; + } + + decodeNetwork(traceId, authorization, budgetId, reserved, buffer, offset, limit); + } + } + + private void onNetworkEnd( + final EndFW end) + { + final long traceId = end.traceId(); + final long authorization = end.authorization(); + + state = PgsqlState.closeInitial(state); + + cleanupDecodeSlotIfNecessary(); + + stream.doApplicationEnd(traceId, authorization); + } + + private void onNetworkAbort( + final AbortFW abort) + { + final long traceId = abort.traceId(); + final long authorization = abort.authorization(); + + state = PgsqlState.closeInitial(state); + + stream.doApplicationAbort(traceId, authorization); + } + + private void onNetworkReset( + final ResetFW reset) + { + final long traceId = reset.traceId(); + final long authorization = reset.authorization(); + + state = PgsqlState.closeReply(state); + + stream.doApplicationReset(traceId, authorization); + } + + private void onNetworkWindow( + final WindowFW window) + { + final long sequence = window.sequence(); + final long acknowledge = window.acknowledge(); + final long traceId = window.traceId(); + final long authorization = window.authorization(); + final long budgetId = window.budgetId(); + final int maximum = window.maximum(); + final int padding = window.padding(); + + assert acknowledge <= sequence; + assert sequence <= replySeq; + assert acknowledge >= replyAck; + assert maximum >= replyMax; + + replyBudgetId = budgetId; + replyAck = acknowledge; + replyMax = maximum; + replyPad = padding; + + assert replyAck <= replySeq; + + state = PgsqlState.openReply(state); + + stream.doApplicationWindow(traceId, authorization, budgetId, (int)(replySeq - replyAck), replyPad); + } + + private void doNetworkBegin( + long traceId, + long authorization, + long affinity) + { + doBegin(network, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, affinity, EMPTY_OCTETS); + + state = PgsqlState.openingReply(state); + } + + private void doNetworkData( + long traceId, + long authorization, + int flags, + long budgetId, + DirectBuffer buffer, + int offset, + int length) + { + final int reserved = length + replyPad; + + doData(network, originId, routedId, replyId, replySeq, replyAck, replyMax, traceId, authorization, + flags, budgetId, reserved, buffer, offset, length, EMPTY_EXTENSION); + + replySeq += reserved; + } + + private void doNetworkWindow( + long traceId, + long authorization, + long budgetId, + int pendingAck, + int paddingMin) + { + final long initialAckMax = Math.max(initialSeq - pendingAck, initialAck); + + if (initialAckMax > initialAck || + stream.initialMax > initialMax || + initialMax > stream.initialMax) + { + initialAck = initialAckMax; + initialMax = Math.max(stream.initialMax, initialMax); + initialPadding = paddingMin; + assert initialAck <= initialSeq; + + state = PgsqlState.openInitial(state); + + doWindow(network, originId, routedId, initialId, initialSeq, initialAck, initialMax, + traceId, authorization, budgetId, initialPadding); + } + } + + private void doNetworkResetAndAbort( + long traceId, + long authorization) + { + doNetworkReset(traceId, authorization); + doNetworkAbort(traceId, authorization); + } + + private void doNetworkEnd( + long traceId, + long authorization) + { + state = PgsqlState.closeReply(state); + + doEnd(network, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doNetworkAbort( + long traceId, + long authorization) + { + state = PgsqlState.closeReply(state); + + doAbort(network, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doNetworkReset( + long traceId, + long authorization) + { + state = PgsqlState.closingInitial(state); + + doReset(network, originId, routedId, initialId, initialSeq, initialAck, initialMax, + traceId, authorization, EMPTY_OCTETS); + + cleanupDecodeSlotIfNecessary(); + } + + private int decodeNetwork( + long traceId, + long authorization, + long budgetId, + int reserved, + DirectBuffer buffer, + int offset, + int limit) + { + PgsqlServerDecoder previous = null; + int progress = offset; + while (progress <= limit && previous != decoder) + { + previous = decoder; + progress = decoder.decode(this, traceId, authorization, budgetId, buffer, progress, limit); + } + + if (progress < limit) + { + if (decodeSlot == NO_SLOT) + { + decodeSlot = bufferPool.acquire(initialId); + } + + if (decodeSlot == NO_SLOT) + { + cleanupNetwork(traceId, authorization); + } + else + { + final MutableDirectBuffer decodeBuffer = bufferPool.buffer(decodeSlot); + decodeBuffer.putBytes(0, buffer, progress, limit - progress); + decodeSlotOffset = limit - progress; + decodeSlotReserved = (int)((long) reserved * (limit - progress) / (limit - offset)); + } + } + else + { + cleanupDecodeSlotIfNecessary(); + } + + if (!PgsqlState.initialClosed(state)) + { + doNetworkWindow(traceId, authorization, budgetId, decodeSlotReserved, initialPadding); + } + + return progress; + } + + public void onDecodeSslRequest( + long traceId, + long authorization) + { + PgsqlSslResponseFW sslResponse = sslResponseRW.wrap(messageBuffer, 0, messageBuffer.capacity()).build(); + doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, sslResponse.limit()); + } + + private void onDecodeStartup( + long traceId, + long authorization, + Array32FW parameters) + { + Consumer beginEx = e -> e.set((b, o, l) -> beginExRW.wrap(b, o, l) + .typeId(pgsqlTypeId) + .parameters(parameters) + .build().sizeof()); + stream.doApplicationBegin(traceId, authorization, beginEx); + + doNetworkWindow(traceId, authorization, authorization, decodeSlotReserved, initialPadding); + + PgsqlAuthenticationMessageFW authMessage = authMessageRW.wrap(messageBuffer, 0, messageBuffer.capacity()) + .build(); + doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, authMessage.limit()); + + PgsqlBackendKeyMessageFW backendKeyMessage = + backendKeyMessageRW.wrap(messageBuffer, 0, messageBuffer.capacity()).build(); + doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, backendKeyMessage.limit()); + + doEncodeParamStatus(traceId, "client_encoding", "UTF8"); + doEncodeParamStatus(traceId, "standard_conforming_strings", "on"); + doEncodeParamStatus(traceId, "server_version", "1.0.0"); + doEncodeParamStatus(traceId, "application_name", "zilla"); + + int progress = 0; + PgsqlMessageFW message = messageRW.wrap(messageBuffer, progress, messageBuffer.capacity()) + .type(MESSAGE_TYPE_READY) + .length(Integer.BYTES + Byte.BYTES) + .build(); + progress = message.limit(); + + messageBuffer.putByte(progress, (byte) PgsqlStatus.IDLE.value()); + progress += Byte.BYTES; + + doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, progress); + } + + private void doEncodeParamStatus( + long traceId, + String name, + String value) + { + int statusOffset = 0; + + PgsqlMessageFW status = messageRW.wrap(messageBuffer, statusOffset, messageBuffer.capacity()) + .type(MESSAGE_TYPE_PARAMETER_STATUS) + .length(0) + .build(); + statusOffset = status.limit(); + + messageBuffer.putBytes(statusOffset, name.getBytes()); + statusOffset += name.length(); + messageBuffer.putByte(statusOffset, (byte) END_OF_FIELD); + statusOffset += Byte.BYTES; + + messageBuffer.putBytes(statusOffset, value.getBytes()); + statusOffset += value.length(); + messageBuffer.putByte(statusOffset, (byte) END_OF_FIELD); + statusOffset += Byte.BYTES; + + messageBuffer.putInt(Byte.BYTES, statusOffset - Byte.BYTES, BIG_ENDIAN); + + doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, statusOffset); + } + + private void onDecodeMessageQuery( + long traceId, + long authorization, + int flags, + int deferred, + DirectBuffer buffer, + int offset, + int limit) + { + Consumer queryEx = e -> e.set((b, o, l) -> dataExRW.wrap(b, o, l) + .typeId(pgsqlTypeId) + .query(q -> q.deferred(deferred)) + .build().sizeof()); + + stream.doApplicationData(traceId, authorization, flags, buffer, offset, limit, queryEx); + } + + private void onDecodeMessageTermination( + long traceId, + long authorization) + { + stream.doApplicationEnd(traceId, authorization); + doNetworkEnd(traceId, authorization); + } + + private void cleanupNetwork( + long traceId, + long authorization) + { + cleanup(traceId, authorization, this::doNetworkResetAndAbort); + } + + private void cleanup( + long traceId, + long authorization, + LongLongConsumer cleanupHandler) + { + cleanupHandler.accept(traceId, authorization); + stream.doApplicationAbortAndReset(traceId, authorization); + } + + private void cleanupDecodeSlotIfNecessary() + { + if (decodeSlot != NO_SLOT) + { + bufferPool.release(decodeSlot); + decodeSlot = NO_SLOT; + decodeSlotOffset = 0; + decodeSlotReserved = 0; + } + } + } + + private final class PgsqlStream + { + private final PgsqlServer server; + + private MessageConsumer application; + + private final long initialId; + private final long replyId; + private final long originId; + private final long routedId; + + private long initialSeq; + private long initialAck; + private int initialMax; + private int initialPad; + private long initialBudgetId; + + private long replySeq; + private long replyAck; + private int replyMax; + + private int state; + + private PgsqlStream( + PgsqlServer server, + long originId, + long routedId) + { + this.server = server; + this.originId = originId; + this.routedId = routedId; + this.initialId = supplyInitialId.applyAsLong(routedId); + this.replyId = supplyReplyId.applyAsLong(initialId); + } + + private void onApplicationMessage( + final int msgTypeId, + final DirectBuffer buffer, + final int index, + final int length) + { + switch (msgTypeId) + { + case BeginFW.TYPE_ID: + final BeginFW begin = beginRO.wrap(buffer, index, index + length); + onApplicationBegin(begin); + break; + case DataFW.TYPE_ID: + final DataFW data = dataRO.wrap(buffer, index, index + length); + onApplicationData(data); + break; + case EndFW.TYPE_ID: + final EndFW end = endRO.wrap(buffer, index, index + length); + onApplicationEnd(end); + break; + case AbortFW.TYPE_ID: + final AbortFW abort = abortRO.wrap(buffer, index, index + length); + onApplicationAbort(abort); + break; + case FlushFW.TYPE_ID: + final FlushFW flush = flushRO.wrap(buffer, index, index + length); + onApplicationFlush(flush); + break; + case ResetFW.TYPE_ID: + final ResetFW reset = resetRO.wrap(buffer, index, index + length); + onApplicationReset(reset); + break; + case WindowFW.TYPE_ID: + final WindowFW window = windowRO.wrap(buffer, index, index + length); + onApplicationWindow(window); + break; + default: + // ignore + break; + } + } + + private void onApplicationBegin( + final BeginFW begin) + { + final long traceId = begin.traceId(); + final long authorization = begin.authorization(); + + state = PgsqlState.openingReply(state); + + doApplicationWindow(traceId, authorization, server.replyBudgetId, 0, 0); + } + + private void onApplicationData( + final DataFW data) + { + final long sequence = data.sequence(); + final long acknowledge = data.acknowledge(); + final long traceId = data.traceId(); + final long authorization = data.authorization(); + final long budgetId = data.budgetId(); + final int reserved = data.reserved(); + + assert acknowledge <= sequence; + assert sequence >= replySeq; + assert acknowledge <= replyAck; + assert budgetId == server.replyBudgetId; + + replySeq = sequence + reserved; + + assert replyAck <= replySeq; + + if (replySeq > replyAck + replyMax) + { + server.cleanupNetwork(traceId, authorization); + } + else + { + final OctetsFW extension = data.extension(); + final ExtensionFW dataEx = extension.get(extensionRO::tryWrap); + + final PgsqlDataExFW pgsqlDataEx = dataEx != null && dataEx.typeId() == pgsqlTypeId ? + extension.get(pgsqlDataExRO::tryWrap) : null; + + if (pgsqlDataEx.kind() == PgsqlDataExFW.KIND_ROW) + { + final OctetsFW payload = data.payload(); + + if (payload != null) + { + doEncodeRow(traceId, authorization, payload); + } + } + } + } + + private void onApplicationFlush( + final FlushFW flush) + { + final long sequence = flush.sequence(); + final long acknowledge = flush.acknowledge(); + final long traceId = flush.traceId(); + final long authorization = flush.authorization(); + final int reserved = flush.reserved(); + + assert acknowledge <= sequence; + assert sequence >= replySeq; + assert acknowledge <= replyAck; + + replySeq = sequence; + + assert replyAck <= replySeq; + + if (replySeq > replySeq + replyMax) + { + server.cleanupNetwork(traceId, authorization); + } + + final OctetsFW extension = flush.extension(); + final ExtensionFW flushEx = extension.get(extensionRO::tryWrap); + + final PgsqlFlushExFW pgsqlFlushEx = flushEx != null && flushEx.typeId() == pgsqlTypeId ? + extension.get(pgsqlFlushExRO::tryWrap) : null; + + assert pgsqlFlushEx != null; + + switch (pgsqlFlushEx.kind()) + { + case PgsqlFlushExFW.KIND_TYPE: + doEncodeType(traceId, authorization, pgsqlFlushEx.type()); + break; + case PgsqlFlushExFW.KIND_COMPLETION: + doEncodeCompletion(traceId, authorization, pgsqlFlushEx.completion()); + break; + case PgsqlFlushExFW.KIND_READY: + doEncodeReady(traceId, authorization, pgsqlFlushEx.ready()); + break; + default: + assert false; + break; + } + } + + private void onApplicationEnd( + final EndFW end) + { + final long traceId = end.traceId(); + final long authorization = end.authorization(); + + if (!PgsqlState.closed(server.state)) + { + doEncodeTerminate(traceId, authorization); + + state = PgsqlState.closeReply(state); + + server.doNetworkEnd(traceId, authorization); + } + } + + private void onApplicationAbort( + final AbortFW abort) + { + final long traceId = abort.traceId(); + final long authorization = abort.authorization(); + + state = PgsqlState.closeReply(state); + + server.doNetworkAbort(traceId, authorization); + } + + private void onApplicationReset( + final ResetFW reset) + { + final long traceId = reset.traceId(); + final long authorization = reset.authorization(); + + state = PgsqlState.closeInitial(state); + + server.doNetworkReset(traceId, authorization); + } + + private void onApplicationWindow( + final WindowFW window) + { + final long sequence = window.sequence(); + final long acknowledge = window.acknowledge(); + final int maximum = window.maximum(); + final long traceId = window.traceId(); + final long authorization = window.authorization(); + final long budgetId = window.budgetId(); + final int padding = window.padding(); + + assert acknowledge <= sequence; + assert acknowledge >= initialAck; + assert maximum + acknowledge >= initialMax + initialAck; + + initialBudgetId = budgetId; + initialAck = acknowledge; + initialMax = maximum; + initialPad = padding; + + assert initialAck <= initialSeq; + + server.doNetworkWindow(traceId, authorization, budgetId, (int)(initialSeq - initialAck), initialPad); + } + + private void doApplicationBegin( + long traceId, + long authorization, + Consumer extension) + { + final BeginFW begin = beginRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(initialId) + .sequence(initialSeq) + .acknowledge(initialAck) + .maximum(initialMax) + .traceId(traceId) + .authorization(authorization) + .affinity(server.affinity) + .extension(extension) + .build(); + + application = streamFactory.newStream(begin.typeId(), begin.buffer(), begin.offset(), begin.sizeof(), + this::onApplicationMessage); + + application.accept(begin.typeId(), begin.buffer(), begin.offset(), begin.sizeof()); + } + + private void doApplicationData( + long traceId, + long authorization, + int flags, + DirectBuffer buffer, + int offset, + int limit, + Consumer extension) + { + final int length = limit - offset; + final int reserved = length + initialPad; + + doData(application, originId, routedId, initialId, initialSeq, initialAck, initialMax, traceId, authorization, + flags, initialBudgetId, reserved, buffer, offset, length, extension); + + initialSeq += reserved; + assert initialSeq <= initialAck + initialMax; + } + + private void doApplicationEnd( + long traceId, + long authorization) + { + doEnd(application, originId, routedId, initialId, initialSeq, initialAck, initialMax, + traceId, authorization, EMPTY_OCTETS); + + state = PgsqlState.closeInitial(state); + } + + private void doApplicationAbort( + long traceId, + long authorization) + { + state = PgsqlState.closeInitial(state); + + doAbort(application, originId, routedId, initialId, initialSeq, initialAck, initialMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doApplicationReset( + long traceId, + long authorization) + { + state = PgsqlState.closeReply(state); + + doReset(application, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, EMPTY_OCTETS); + } + + private void doApplicationAbortAndReset( + long traceId, + long authorization) + { + doApplicationAbort(traceId, authorization); + doApplicationReset(traceId, authorization); + } + + private void doApplicationWindow( + long traceId, + long authorization, + long budgetId, + int pendingAck, + int paddingMin) + { + final long replyAckMax = Math.max(replySeq - pendingAck, replyAck); + if (PgsqlState.replyOpening(state) && + (replyAckMax > replyAck || server.replyMax > replyMax)) + { + replyAck = replyAckMax; + replyMax = server.replyMax; + assert replyAck <= replySeq; + + state = PgsqlState.openReply(state); + + doWindow(application, originId, routedId, replyId, replySeq, replyAck, replyMax, + traceId, authorization, budgetId, paddingMin); + } + } + + private void doEncodeType( + long traceId, + long authorization, + PgsqlTypeFlushExFW type) + { + final MutableInteger typeOffset = new MutableInteger(0); + + PgsqlMessageFW messageType = messageRW.wrap(messageBuffer, 0, messageBuffer.capacity()) + .type(MESSAGE_TYPE_TYPE) + .length(0) + .build(); + typeOffset.getAndAdd(messageType.limit()); + + messageBuffer.putShort(typeOffset.value, (short) type.columns().fieldCount(), BIG_ENDIAN); + typeOffset.getAndAdd(Short.BYTES); + + type.columns().forEach(c -> + { + final DirectBuffer nameBuffer = c.name().value(); + final int nameSize = nameBuffer.capacity(); + + messageBuffer.putBytes(typeOffset.value, nameBuffer, 0, nameSize); + typeOffset.getAndAdd(nameSize); + messageBuffer.putInt(typeOffset.value, c.tableOid(), BIG_ENDIAN); + typeOffset.getAndAdd(Integer.BYTES); + messageBuffer.putShort(typeOffset.value, c.index(), BIG_ENDIAN); + typeOffset.getAndAdd(Short.BYTES); + messageBuffer.putInt(typeOffset.value, c.typeOid(), BIG_ENDIAN); + typeOffset.getAndAdd(Integer.BYTES); + messageBuffer.putShort(typeOffset.value, c.length(), BIG_ENDIAN); + typeOffset.getAndAdd(Short.BYTES); + messageBuffer.putInt(typeOffset.value, c.modifier(), BIG_ENDIAN); + typeOffset.getAndAdd(Integer.BYTES); + messageBuffer.putShort(typeOffset.value, (short) c.format().get().value(), BIG_ENDIAN); + typeOffset.getAndAdd(Short.BYTES); + }); + + messageRW.wrap(messageBuffer, 0, messageBuffer.capacity()) + .type(MESSAGE_TYPE_TYPE) + .length(typeOffset.get() - Byte.BYTES) + .build(); + + server.doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, typeOffset.value); + } + + private void doEncodeRow( + long traceId, + long authorization, + OctetsFW row) + { + final DirectBuffer rowBuffer = row.value(); + final int rowSize = rowBuffer.capacity(); + + int rowOffset = 0; + + PgsqlMessageFW messageRow = messageRW.wrap(messageBuffer, 0, messageBuffer.capacity()) + .type(MESSAGE_TYPE_DATA_ROW) + .length(rowSize + Integer.BYTES) + .build(); + rowOffset += messageRow.limit(); + + messageBuffer.putBytes(rowOffset, rowBuffer, 0, rowSize); + rowOffset += rowSize; + + server.doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, rowOffset); + } + + private void doEncodeCompletion( + long traceId, + long authorization, + PgsqlCompletedFlushExFW completion) + { + final DirectBuffer tagBuffer = completion.tag().value(); + final int tagSize = tagBuffer.capacity(); + + int completionOffset = 0; + + PgsqlMessageFW messageCompleted = messageRW.wrap(messageBuffer, 0, messageBuffer.capacity()) + .type(MESSAGE_TYPE_COMPLETION) + .length(Integer.BYTES + tagSize) + .build(); + completionOffset += messageCompleted.limit(); + + messageBuffer.putBytes(completionOffset, tagBuffer, 0, tagSize); + completionOffset += tagSize; + + server.doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, completionOffset); + } + + private void doEncodeReady( + long traceId, + long authorization, + PgsqlReadyFlushExFW ready) + { + int readyOffset = 0; + + PgsqlMessageFW messageReady = messageRW.wrap(messageBuffer, 0, messageBuffer.capacity()) + .type(MESSAGE_TYPE_READY) + .length(ready.status().sizeof() + Integer.BYTES) + .build(); + readyOffset += messageReady.limit(); + + messageBuffer.putByte(messageReady.limit(), (byte) ready.status().get().value()); + readyOffset += Byte.BYTES; + + server.doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, readyOffset); + } + + private void doEncodeTerminate( + long traceId, + long authorization) + { + PgsqlMessageFW messageReady = messageRW.wrap(messageBuffer, 0, messageBuffer.capacity()) + .type(MESSAGE_TYPE_TERMINATE) + .length(Integer.BYTES) + .build(); + + server.doNetworkData(traceId, authorization, FLAGS_COMP, 0L, messageBuffer, 0, messageReady.limit()); + } + } + + private void doBegin( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final long affinity, + final OctetsFW extension) + { + final BeginFW begin = beginRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .affinity(affinity) + .extension(extension) + .build(); + + receiver.accept(begin.typeId(), begin.buffer(), begin.offset(), begin.sizeof()); + } + + private void doData( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final int flags, + final long budgetId, + final int reserved, + DirectBuffer buffer, + int offset, + int length, + Consumer extension) + { + final DataFW data = dataRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .flags(flags) + .budgetId(budgetId) + .reserved(reserved) + .payload(buffer, offset, length) + .extension(extension) + .build(); + + receiver.accept(data.typeId(), data.buffer(), data.offset(), data.sizeof()); + } + + private void doAbort( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final OctetsFW extension) + { + final AbortFW abort = abortRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .extension(extension) + .build(); + + receiver.accept(abort.typeId(), abort.buffer(), abort.offset(), abort.sizeof()); + } + + private void doEnd( + final MessageConsumer receiver, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final OctetsFW extension) + { + final EndFW end = endRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .extension(extension) + .build(); + + receiver.accept(end.typeId(), end.buffer(), end.offset(), end.sizeof()); + } + + private void doReset( + final MessageConsumer sender, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + final long authorization, + final OctetsFW extension) + { + final ResetFW reset = resetRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .extension(extension) + .build(); + + sender.accept(reset.typeId(), reset.buffer(), reset.offset(), reset.sizeof()); + } + + private void doWindow( + final MessageConsumer sender, + final long originId, + final long routedId, + final long streamId, + final long sequence, + final long acknowledge, + final int maximum, + final long traceId, + long authorization, + final long budgetId, + final int padding) + { + final WindowFW window = windowRW.wrap(writeBuffer, 0, writeBuffer.capacity()) + .originId(originId) + .routedId(routedId) + .streamId(streamId) + .sequence(sequence) + .acknowledge(acknowledge) + .maximum(maximum) + .traceId(traceId) + .authorization(authorization) + .budgetId(budgetId) + .padding(padding) + .build(); + + sender.accept(window.typeId(), window.buffer(), window.offset(), window.sizeof()); + } + + private int decodePgsqlInitial( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + final PgsqlSslRequestFW pgsqlSslRequest = sslRequestRO.tryWrap(buffer, offset, limit); + final PgsqlCancelRequestMessageFW cancelRequest = cancelReqMessageRO.tryWrap(buffer, offset, limit); + final PgsqlStartupMessageFW startupMessage = startupMessageRO.tryWrap(buffer, offset, limit); + + if (pgsqlSslRequest != null && + pgsqlSslRequest.code() == SSL_REQUEST_CODE) + { + server.decoder = decodePgsqlSslRequest; + } + else if (cancelRequest != null && + cancelRequest.code() == CANCEL_REQUEST_CODE) + { + server.decoder = decodePgsqlCancelRequest; + } + else if (startupMessage != null) + { + server.decoder = decodePgsqlStartupMessage; + } + else + { + server.decoder = decodePgsqlIgnoreAll; + } + + return offset; + } + + private int decodePgsqlSslRequest( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + PgsqlSslRequestFW sslRequest = sslRequestRO.wrap(buffer, offset, limit); + + server.onDecodeSslRequest(traceId, authorization); + server.decoder = decodePgsqlStartupMessage; + + return sslRequest.limit(); + } + + private int decodePgsqlStartupMessage( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + progress.set(offset); + + PgsqlStartupMessageFW startupMessage = startupMessageRO.tryWrap(buffer, offset, limit); + + if (startupMessage != null) + { + progress.set(startupMessage.limit()); + Array32FW.Builder parameterBuilder = + parametersRW.wrap(messageBuffer, 0, messageBuffer.capacity()); + final int maxLimit = startupMessage.length() + progress.value - startupMessage.sizeof() - Integer.BYTES; + while (progress.value < maxLimit) + { + final int nameLength = getLengthOfString(buffer, progress.value); + final int valueLength = getLengthOfString(buffer, progress.value + nameLength); + + parameterBuilder.item(i -> i + .name(buffer, progress.value, nameLength) + .value(buffer, progress.value + nameLength, valueLength)); + + progress.addAndGet(nameLength + valueLength); + + if (buffer.getByte(progress.value) == (byte) END_OF_FIELD) + { + progress.addAndGet(Byte.BYTES); + } + } + + server.onDecodeStartup(traceId, authorization, parametersRW.build()); + server.decoder = decodePgsqlMessageType; + } + + return progress.value; + } + + private int decodePgsqlCancelRequest( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + PgsqlSslRequestFW sslRequest = sslRequestRO.wrap(buffer, offset, limit); + + server.onDecodeSslRequest(traceId, authorization); + server.decoder = decodePgsqlStartupMessage; + + return sslRequest.limit(); + } + + private int decodePgsqlMessageType( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progress = offset; + + final PgsqlMessageFW pgsqlMessage = messageRO.tryWrap(buffer, offset, limit); + + if (pgsqlMessage != null) + { + final int type = pgsqlMessage.type(); + + final PgsqlServerDecoder decoder = decodersByType.getOrDefault(type, decodePgsqlIgnoreOne); + server.decoder = decoder; + } + + return progress; + } + + private int decodePgsqlMessageQuery( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progressOffset = offset; + + final PgsqlMessageFW pgsqlQuery = messageRO.tryWrap(buffer, progressOffset, limit); + if (pgsqlQuery != null) + { + progressOffset = pgsqlQuery.limit(); + + final int querySize = pgsqlQuery.length() - Integer.BYTES; + payloadRemaining.set(querySize); + + final int length = Math.min(payloadRemaining.value, limit - progressOffset); + + if (length > 0) + { + final int flags = querySize == length ? FLAGS_COMP : FLAGS_INIT; + final int deferred = querySize - length; + + server.onDecodeMessageQuery(traceId, authorization, flags, deferred, + buffer, progressOffset, progressOffset + length); + progressOffset += length; + payloadRemaining.set(querySize - length); + + assert payloadRemaining.get() >= 0; + + server.decoder = querySize == length + ? decodePgsqlMessageType + : decodePgsqlPayload; + } + } + + return progressOffset; + } + + private int decodePgsqlMessagePayload( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + final int payloadSize = payloadRemaining.get(); + final int length = Math.min(payloadSize, limit - offset); + + final int flags = payloadSize == length ? FLAGS_FIN : FLAGS_CONT; + + final int maxLimit = offset + length; + server.stream.doApplicationData(traceId, authorization, flags, buffer, offset, maxLimit, EMPTY_EXTENSION); + payloadRemaining.set(payloadSize - length); + + assert payloadRemaining.get() >= 0; + + if (payloadSize == length) + { + server.decoder = decodePgsqlMessageType; + } + + return maxLimit; + } + + private int decodePgsqlMessageTerminator( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + int progressOffset = offset; + + final PgsqlMessageFW pgsqlTerminate = messageRO.tryWrap(buffer, offset, limit); + + if (pgsqlTerminate != null) + { + server.onDecodeMessageTermination(traceId, authorization); + + server.decoder = decodePgsqlIgnoreAll; + progressOffset = limit; + } + + return progressOffset; + } + + private int decodePgsqlIgnoreOne( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + final PgsqlMessageFW messageType = messageRO.wrap(buffer, offset, limit); + final int progress = messageType.limit() + messageType.length(); + + server.decoder = decodePgsqlMessageType; + return progress; + } + + private int decodePgsqlIgnoreAll( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit) + { + return limit; + } + + @FunctionalInterface + private interface PgsqlServerDecoder + { + int decode( + PgsqlServer server, + long traceId, + long authorization, + long budgetId, + DirectBuffer buffer, + int offset, + int limit); + } + + private int getLengthOfString( + DirectBuffer buffer, + int offset) + { + int length = -1; + loop: + for (int progress = offset; progress < buffer.capacity(); progress++) + { + if (buffer.getByte(progress) == END_OF_FIELD) + { + length = progress - offset + 1; + break loop; + } + } + return length; + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlState.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlState.java new file mode 100644 index 0000000000..3ce9569e75 --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlState.java @@ -0,0 +1,128 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal.stream; + +public final class PgsqlState +{ + private static final int INITIAL_OPENING = 0x10; + private static final int INITIAL_OPENED = 0x20; + private static final int INITIAL_CLOSING = 0x40; + private static final int INITIAL_CLOSED = 0x80; + private static final int REPLY_OPENING = 0x01; + private static final int REPLY_OPENED = 0x02; + private static final int REPLY_CLOSING = 0x04; + private static final int REPLY_CLOSED = 0x08; + + static int openingInitial( + int state) + { + return state | INITIAL_OPENING; + } + + static int openInitial( + int state) + { + return openingInitial(state) | INITIAL_OPENED; + } + + static int closingInitial( + int state) + { + return state | INITIAL_CLOSING; + } + + static int closeInitial( + int state) + { + return closingInitial(state) | INITIAL_CLOSED; + } + + static boolean initialOpening( + int state) + { + return (state & INITIAL_OPENING) != 0; + } + + static boolean initialOpened( + int state) + { + return (state & INITIAL_OPENED) != 0; + } + + static boolean initialClosing( + int state) + { + return (state & INITIAL_CLOSING) != 0; + } + + static boolean initialClosed( + int state) + { + return (state & INITIAL_CLOSED) != 0; + } + + static boolean closed( + int state) + { + return initialClosed(state) && replyClosed(state); + } + + static int openingReply( + int state) + { + return state | REPLY_OPENING; + } + + static int openReply( + int state) + { + return openingReply(state) | REPLY_OPENED; + } + + static boolean replyOpening( + int state) + { + return (state & REPLY_OPENING) != 0; + } + + static boolean replyOpened( + int state) + { + return (state & REPLY_OPENED) != 0; + } + + static int closingReply( + int state) + { + return state | REPLY_CLOSING; + } + + static int closeReply( + int state) + { + return closingReply(state) | REPLY_CLOSED; + } + + static boolean replyClosed( + int state) + { + return (state & REPLY_CLOSED) != 0; + } + + private PgsqlState() + { + // utility + } +} diff --git a/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlStreamFactory.java b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlStreamFactory.java new file mode 100644 index 0000000000..dc8005fb2f --- /dev/null +++ b/incubator/binding-pgsql/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/PgsqlStreamFactory.java @@ -0,0 +1,27 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal.stream; + +import io.aklivity.zilla.runtime.engine.binding.BindingHandler; +import io.aklivity.zilla.runtime.engine.config.BindingConfig; + +public interface PgsqlStreamFactory extends BindingHandler +{ + void attach( + BindingConfig binding); + + void detach( + long bindingId); +} diff --git a/incubator/binding-pgsql/src/main/moditect/module-info.java b/incubator/binding-pgsql/src/main/moditect/module-info.java new file mode 100644 index 0000000000..3868d46eb3 --- /dev/null +++ b/incubator/binding-pgsql/src/main/moditect/module-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +module io.aklivity.zilla.runtime.binding.pgsql +{ + requires io.aklivity.zilla.runtime.engine; + + provides io.aklivity.zilla.runtime.engine.binding.BindingFactorySpi + with io.aklivity.zilla.runtime.binding.pgsql.internal.PgsqlBindingFactorySpi; +} diff --git a/incubator/binding-pgsql/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.binding.BindingFactorySpi b/incubator/binding-pgsql/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.binding.BindingFactorySpi new file mode 100644 index 0000000000..0ec23084e3 --- /dev/null +++ b/incubator/binding-pgsql/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.binding.BindingFactorySpi @@ -0,0 +1 @@ +io.aklivity.zilla.runtime.binding.pgsql.internal.PgsqlBindingFactorySpi diff --git a/incubator/binding-pgsql/src/main/zilla/protocol.idl b/incubator/binding-pgsql/src/main/zilla/protocol.idl new file mode 100644 index 0000000000..b2e864b06d --- /dev/null +++ b/incubator/binding-pgsql/src/main/zilla/protocol.idl @@ -0,0 +1,78 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +scope protocol +{ + option byteorder network; + + scope codec + { + struct PgsqlSslRequest + { + int32 length = 4; + int32 code = 80877103; + } + + struct PgsqlSslResponse + { + uint8 answer = 78; + } + + struct PgsqlStartupMessage + { + int32 length; + uint16 majorVersion; + uint16 minorVersion; + } + + struct PgsqlCancelRequestMessage + { + int32 length; + int32 code = 80877102; + int32 pid = 0; + int32 key = 0; + } + + struct PgsqlAuthenticationMessage + { + uint8 type = 82; + int32 length = 8; + int32 authenticationType = 0; + } + + struct PgsqlBackendKeyMessage + { + uint8 type = 75; + int32 length = 12; + int32 pid = 0; + int32 key = 0; + } + + struct PgsqlMessage + { + uint8 type; + int32 length; + } + + struct PgsqlRowDescription + { + int32 tableOid; + int16 index; + int32 typeOid; + int16 length; + int32 modifier; + int16 format; + } + } +} diff --git a/incubator/binding-pgsql/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/ClientIT.java b/incubator/binding-pgsql/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/ClientIT.java new file mode 100644 index 0000000000..d309166c54 --- /dev/null +++ b/incubator/binding-pgsql/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/ClientIT.java @@ -0,0 +1,100 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal.stream; + +import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_DRAIN_ON_CLOSE; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.rules.RuleChain.outerRule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.DisableOnDebug; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +import io.aklivity.k3po.runtime.junit.annotation.Specification; +import io.aklivity.k3po.runtime.junit.rules.K3poRule; +import io.aklivity.zilla.runtime.engine.test.EngineRule; +import io.aklivity.zilla.runtime.engine.test.annotation.Configuration; + +public class ClientIT +{ + private final K3poRule k3po = new K3poRule() + .addScriptRoot("net", "io/aklivity/zilla/specs/binding/pgsql/streams/network") + .addScriptRoot("app", "io/aklivity/zilla/specs/binding/pgsql/streams/application"); + + private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS)); + + private final EngineRule engine = new EngineRule() + .directory("target/zilla-itests") + .countersBufferCapacity(8192) + .configure(ENGINE_DRAIN_ON_CLOSE, false) + .configurationRoot("io/aklivity/zilla/specs/binding/pgsql/config") + .external("net0") + .clean(); + + @Rule + public final TestRule chain = outerRule(engine).around(k3po).around(timeout); + + @Test + @Configuration("client.yaml") + @Specification({ + "${app}/create.table.with.primary.key/client", + "${net}/create.table.with.primary.key/server" }) + public void shouldCreateTableWithPrimaryKey() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("client.yaml") + @Specification({ + "${app}/termination.request/client", + "${net}/termination.request/server" }) + public void shouldHandleTerminationRequest() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("client.yaml") + @Specification({ + "${app}/select.table/client", + "${net}/select.table/server" }) + public void shouldSelectTable() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("client.yaml") + @Specification({ + "${app}/client.sent.write.abort/client", + "${net}/client.sent.write.abort/server" }) + public void shouldHandleClientSentWriteAbort() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("client.yaml") + @Specification({ + "${app}/client.sent.read.abort/client", + "${net}/client.sent.read.abort/server" }) + public void shouldHandleClientSentReadAbort() throws Exception + { + k3po.finish(); + } +} diff --git a/incubator/binding-pgsql/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/ServerIT.java b/incubator/binding-pgsql/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/ServerIT.java new file mode 100644 index 0000000000..6bcfdc2b64 --- /dev/null +++ b/incubator/binding-pgsql/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/internal/stream/ServerIT.java @@ -0,0 +1,120 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.binding.pgsql.internal.stream; + +import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_DRAIN_ON_CLOSE; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.rules.RuleChain.outerRule; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.DisableOnDebug; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +import io.aklivity.k3po.runtime.junit.annotation.Specification; +import io.aklivity.k3po.runtime.junit.rules.K3poRule; +import io.aklivity.zilla.runtime.engine.test.EngineRule; +import io.aklivity.zilla.runtime.engine.test.annotation.Configuration; + +public class ServerIT +{ + private final K3poRule k3po = new K3poRule() + .addScriptRoot("net", "io/aklivity/zilla/specs/binding/pgsql/streams/network") + .addScriptRoot("app", "io/aklivity/zilla/specs/binding/pgsql/streams/application"); + + private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS)); + + private final EngineRule engine = new EngineRule() + .directory("target/zilla-itests") + .countersBufferCapacity(8192) + .configure(ENGINE_DRAIN_ON_CLOSE, false) + .configurationRoot("io/aklivity/zilla/specs/binding/pgsql/config") + .external("app0") + .clean(); + + @Rule + public final TestRule chain = outerRule(engine).around(k3po).around(timeout); + + @Test + @Configuration("server.yaml") + @Specification({ + "${net}/ssl.request/client", + "${app}/ssl.request/server" }) + public void shouldHandleSslRequest() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("server.yaml") + @Specification({ + "${net}/termination.request/client", + "${app}/termination.request/server" }) + public void shouldHandleTerminationRequest() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("server.yaml") + @Specification({ + "${net}/create.table.with.primary.key/client", + "${app}/create.table.with.primary.key/server" }) + public void shouldCreateTableWithPrimaryKey() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("server.yaml") + @Specification({ + "${net}/select.table/client", + "${app}/select.table/server" }) + public void shouldSelectTable() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("server.yaml") + @Specification({ + "${net}/client.sent.write.abort/client", + "${app}/client.sent.write.abort/server" }) + public void shouldHandleClientSentWriteAbort() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("server.yaml") + @Specification({ + "${net}/client.sent.read.abort/client", + "${app}/client.sent.read.abort/server" }) + public void shouldHandleClientSentReadAbort() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("server.yaml") + @Specification({ + "${net}/create.table.fragmented/client", + "${app}/create.table.fragmented/server" }) + public void shouldHandleFragmentedCreateTable() throws Exception + { + k3po.finish(); + } +} diff --git a/incubator/binding-risingwave.spec/COPYRIGHT b/incubator/binding-risingwave.spec/COPYRIGHT new file mode 100644 index 0000000000..0cb10b6f62 --- /dev/null +++ b/incubator/binding-risingwave.spec/COPYRIGHT @@ -0,0 +1,12 @@ +Copyright ${copyrightYears} Aklivity Inc + +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/incubator/binding-risingwave.spec/LICENSE b/incubator/binding-risingwave.spec/LICENSE new file mode 100644 index 0000000000..f6abb6327b --- /dev/null +++ b/incubator/binding-risingwave.spec/LICENSE @@ -0,0 +1,114 @@ + Aklivity Community License Agreement + Version 1.0 + +This Aklivity Community License Agreement Version 1.0 (the “Agreement”) sets +forth the terms on which Aklivity, Inc. (“Aklivity”) makes available certain +software made available by Aklivity under this Agreement (the “Software”). BY +INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, +YOU AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO +SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE SOFTWARE. IF YOU ARE RECEIVING +THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU +HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS +AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you, an individual, or +the entity on whose behalf you are receiving the Software. + + 1. LICENSE GRANT AND CONDITIONS. + + 1.1 License. Subject to the terms and conditions of this Agreement, + Aklivity hereby grants to Licensee a non-exclusive, royalty-free, + worldwide, non-transferable, non-sublicenseable license during the term + of this Agreement to: (a) use the Software; (b) prepare modifications and + derivative works of the Software; (c) distribute the Software (including + without limitation in source code or object code form); and (d) reproduce + copies of the Software (the “License”). Licensee is not granted the + right to, and Licensee shall not, exercise the License for an Excluded + Purpose. For purposes of this Agreement, “Excluded Purpose” means making + available any software-as-a-service, platform-as-a-service, + infrastructure-as-a-service or other similar online service that competes + with Aklivity products or services that provide the Software. + + 1.2 Conditions. In consideration of the License, Licensee’s distribution + of the Software is subject to the following conditions: + + (a) Licensee must cause any Software modified by Licensee to carry + prominent notices stating that Licensee modified the Software. + + (b) On each Software copy, Licensee shall reproduce and not remove or + alter all Aklivity or third party copyright or other proprietary + notices contained in the Software, and Licensee must provide the + notice below with each copy. + + “This software is made available by Aklivity, Inc., under the + terms of the Aklivity Community License Agreement, Version 1.0 + located at http://www.Aklivity.io/Aklivity-community-license. BY + INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF + THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.” + + 1.3 Licensee Modifications. Licensee may add its own copyright notices + to modifications made by Licensee and may provide additional or different + license terms and conditions for use, reproduction, or distribution of + Licensee’s modifications. While redistributing the Software or + modifications thereof, Licensee may choose to offer, for a fee or free of + charge, support, warranty, indemnity, or other obligations. Licensee, and + not Aklivity, will be responsible for any such obligations. + + 1.4 No Sublicensing. The License does not include the right to + sublicense the Software, however, each recipient to which Licensee + provides the Software may exercise the Licenses so long as such recipient + agrees to the terms and conditions of this Agreement. + + 2. TERM AND TERMINATION. This Agreement will continue unless and until + earlier terminated as set forth herein. If Licensee breaches any of its + conditions or obligations under this Agreement, this Agreement will + terminate automatically and the License will terminate automatically and + permanently. + + 3. INTELLECTUAL PROPERTY. As between the parties, Aklivity will retain all + right, title, and interest in the Software, and all intellectual property + rights therein. Aklivity hereby reserves all rights not expressly granted + to Licensee in this Agreement. Aklivity hereby reserves all rights in its + trademarks and service marks, and no licenses therein are granted in this + Agreement. + + 4. DISCLAIMER. Aklivity HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND + CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY + DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR + PURPOSE, WITH RESPECT TO THE SOFTWARE. + + 5. LIMITATION OF LIABILITY. Aklivity WILL NOT BE LIABLE FOR ANY DAMAGES OF + ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL, + SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL + APPLY TO THE EXTENT PERMITTED BY APPLICABLE LAW. + + 6.GENERAL. + + 6.1 Governing Law. This Agreement will be governed by and interpreted in + accordance with the laws of the state of California, without reference to + its conflict of laws principles. If Licensee is located within the + United States, all disputes arising out of this Agreement are subject to + the exclusive jurisdiction of courts located in Santa Clara County, + California. USA. If Licensee is located outside of the United States, + any dispute, controversy or claim arising out of or relating to this + Agreement will be referred to and finally determined by arbitration in + accordance with the JAMS International Arbitration Rules. The tribunal + will consist of one arbitrator. The place of arbitration will be Palo + Alto, California. The language to be used in the arbitral proceedings + will be English. Judgment upon the award rendered by the arbitrator may + be entered in any court having jurisdiction thereof. + + 6.2 Assignment. Licensee is not authorized to assign its rights under + this Agreement to any third party. Aklivity may freely assign its rights + under this Agreement to any third party. + + 6.3 Other. This Agreement is the entire agreement between the parties + regarding the subject matter hereof. No amendment or modification of + this Agreement will be valid or binding upon the parties unless made in + writing and signed by the duly authorized representatives of both + parties. In the event that any provision, including without limitation + any condition, of this Agreement is held to be unenforceable, this + Agreement and all licenses and rights granted hereunder will immediately + terminate. Waiver by Aklivity of a breach of any provision of this + Agreement or the failure by Aklivity to exercise any right hereunder + will not be construed as a waiver of any subsequent breach of that right + or as a waiver of any other right. \ No newline at end of file diff --git a/incubator/binding-risingwave.spec/NOTICE b/incubator/binding-risingwave.spec/NOTICE new file mode 100644 index 0000000000..f99ca0e278 --- /dev/null +++ b/incubator/binding-risingwave.spec/NOTICE @@ -0,0 +1,19 @@ +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +This project includes: + agrona under The Apache License, Version 2.0 + ICU4J under Unicode/ICU License + Jakarta JSON Processing API under Eclipse Public License 2.0 or GNU General Public License, version 2 with the GNU Classpath Exception + org.leadpony.justify under The Apache Software License, Version 2.0 + zilla::incubator::binding-pgsql.spec under Aklivity Community License Agreement + zilla::specs::engine.spec under The Apache Software License, Version 2.0 + diff --git a/incubator/binding-risingwave.spec/NOTICE.template b/incubator/binding-risingwave.spec/NOTICE.template new file mode 100644 index 0000000000..209ca12f74 --- /dev/null +++ b/incubator/binding-risingwave.spec/NOTICE.template @@ -0,0 +1,13 @@ +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +This project includes: +#GENERATED_NOTICES# diff --git a/incubator/binding-risingwave.spec/mvnw b/incubator/binding-risingwave.spec/mvnw new file mode 100755 index 0000000000..d2f0ea3808 --- /dev/null +++ b/incubator/binding-risingwave.spec/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/incubator/binding-risingwave.spec/mvnw.cmd b/incubator/binding-risingwave.spec/mvnw.cmd new file mode 100644 index 0000000000..b26ab24f03 --- /dev/null +++ b/incubator/binding-risingwave.spec/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/incubator/binding-risingwave.spec/pom.xml b/incubator/binding-risingwave.spec/pom.xml new file mode 100644 index 0000000000..f3d89ea60d --- /dev/null +++ b/incubator/binding-risingwave.spec/pom.xml @@ -0,0 +1,142 @@ + + + + 4.0.0 + + io.aklivity.zilla + incubator + 0.9.93 + ../pom.xml + + + binding-risingwave.spec + zilla::incubator::binding-risingwave.spec + + + + Aklivity Community License Agreement + https://www.aklivity.io/aklivity-community-license/ + repo + + + + + 1.00 + 0 + + + + + io.aklivity.k3po + lang + provided + + + ${project.groupId} + binding-pgsql.spec + ${project.version} + + + junit + junit + test + + + io.aklivity.k3po + control-junit + test + + + org.hamcrest + hamcrest-library + test + + + + + + + src/main/resources + + + src/main/scripts + + + + + + org.jasig.maven + maven-notice-plugin + + + com.mycila + license-maven-plugin + + + maven-checkstyle-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.moditect + moditect-maven-plugin + + + io.aklivity.k3po + k3po-maven-plugin + + + ${project.groupId} + engine + ${project.version} + test-jar + + + ${project.groupId} + engine + ${project.version} + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.jacoco + jacoco-maven-plugin + + + io/aklivity/zilla/specs/binding/risingwave/internal/types/**/*.class + + + + BUNDLE + + + INSTRUCTION + COVEREDRATIO + ${jacoco.coverage.ratio} + + + CLASS + MISSEDCOUNT + ${jacoco.missed.count} + + + + + + + + + diff --git a/incubator/binding-risingwave.spec/src/main/moditect/module-info.java b/incubator/binding-risingwave.spec/src/main/moditect/module-info.java new file mode 100644 index 0000000000..2b879f784c --- /dev/null +++ b/incubator/binding-risingwave.spec/src/main/moditect/module-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +open module io.aklivity.zilla.specs.binding.risingwave +{ + requires transitive io.aklivity.zilla.specs.engine; +} diff --git a/incubator/binding-risingwave/COPYRIGHT b/incubator/binding-risingwave/COPYRIGHT new file mode 100644 index 0000000000..0cb10b6f62 --- /dev/null +++ b/incubator/binding-risingwave/COPYRIGHT @@ -0,0 +1,12 @@ +Copyright ${copyrightYears} Aklivity Inc + +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff --git a/incubator/binding-risingwave/LICENSE b/incubator/binding-risingwave/LICENSE new file mode 100644 index 0000000000..f6abb6327b --- /dev/null +++ b/incubator/binding-risingwave/LICENSE @@ -0,0 +1,114 @@ + Aklivity Community License Agreement + Version 1.0 + +This Aklivity Community License Agreement Version 1.0 (the “Agreement”) sets +forth the terms on which Aklivity, Inc. (“Aklivity”) makes available certain +software made available by Aklivity under this Agreement (the “Software”). BY +INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, +YOU AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO +SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE SOFTWARE. IF YOU ARE RECEIVING +THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU +HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS +AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you, an individual, or +the entity on whose behalf you are receiving the Software. + + 1. LICENSE GRANT AND CONDITIONS. + + 1.1 License. Subject to the terms and conditions of this Agreement, + Aklivity hereby grants to Licensee a non-exclusive, royalty-free, + worldwide, non-transferable, non-sublicenseable license during the term + of this Agreement to: (a) use the Software; (b) prepare modifications and + derivative works of the Software; (c) distribute the Software (including + without limitation in source code or object code form); and (d) reproduce + copies of the Software (the “License”). Licensee is not granted the + right to, and Licensee shall not, exercise the License for an Excluded + Purpose. For purposes of this Agreement, “Excluded Purpose” means making + available any software-as-a-service, platform-as-a-service, + infrastructure-as-a-service or other similar online service that competes + with Aklivity products or services that provide the Software. + + 1.2 Conditions. In consideration of the License, Licensee’s distribution + of the Software is subject to the following conditions: + + (a) Licensee must cause any Software modified by Licensee to carry + prominent notices stating that Licensee modified the Software. + + (b) On each Software copy, Licensee shall reproduce and not remove or + alter all Aklivity or third party copyright or other proprietary + notices contained in the Software, and Licensee must provide the + notice below with each copy. + + “This software is made available by Aklivity, Inc., under the + terms of the Aklivity Community License Agreement, Version 1.0 + located at http://www.Aklivity.io/Aklivity-community-license. BY + INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF + THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.” + + 1.3 Licensee Modifications. Licensee may add its own copyright notices + to modifications made by Licensee and may provide additional or different + license terms and conditions for use, reproduction, or distribution of + Licensee’s modifications. While redistributing the Software or + modifications thereof, Licensee may choose to offer, for a fee or free of + charge, support, warranty, indemnity, or other obligations. Licensee, and + not Aklivity, will be responsible for any such obligations. + + 1.4 No Sublicensing. The License does not include the right to + sublicense the Software, however, each recipient to which Licensee + provides the Software may exercise the Licenses so long as such recipient + agrees to the terms and conditions of this Agreement. + + 2. TERM AND TERMINATION. This Agreement will continue unless and until + earlier terminated as set forth herein. If Licensee breaches any of its + conditions or obligations under this Agreement, this Agreement will + terminate automatically and the License will terminate automatically and + permanently. + + 3. INTELLECTUAL PROPERTY. As between the parties, Aklivity will retain all + right, title, and interest in the Software, and all intellectual property + rights therein. Aklivity hereby reserves all rights not expressly granted + to Licensee in this Agreement. Aklivity hereby reserves all rights in its + trademarks and service marks, and no licenses therein are granted in this + Agreement. + + 4. DISCLAIMER. Aklivity HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND + CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY + DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR + PURPOSE, WITH RESPECT TO THE SOFTWARE. + + 5. LIMITATION OF LIABILITY. Aklivity WILL NOT BE LIABLE FOR ANY DAMAGES OF + ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL, + SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL + APPLY TO THE EXTENT PERMITTED BY APPLICABLE LAW. + + 6.GENERAL. + + 6.1 Governing Law. This Agreement will be governed by and interpreted in + accordance with the laws of the state of California, without reference to + its conflict of laws principles. If Licensee is located within the + United States, all disputes arising out of this Agreement are subject to + the exclusive jurisdiction of courts located in Santa Clara County, + California. USA. If Licensee is located outside of the United States, + any dispute, controversy or claim arising out of or relating to this + Agreement will be referred to and finally determined by arbitration in + accordance with the JAMS International Arbitration Rules. The tribunal + will consist of one arbitrator. The place of arbitration will be Palo + Alto, California. The language to be used in the arbitral proceedings + will be English. Judgment upon the award rendered by the arbitrator may + be entered in any court having jurisdiction thereof. + + 6.2 Assignment. Licensee is not authorized to assign its rights under + this Agreement to any third party. Aklivity may freely assign its rights + under this Agreement to any third party. + + 6.3 Other. This Agreement is the entire agreement between the parties + regarding the subject matter hereof. No amendment or modification of + this Agreement will be valid or binding upon the parties unless made in + writing and signed by the duly authorized representatives of both + parties. In the event that any provision, including without limitation + any condition, of this Agreement is held to be unenforceable, this + Agreement and all licenses and rights granted hereunder will immediately + terminate. Waiver by Aklivity of a breach of any provision of this + Agreement or the failure by Aklivity to exercise any right hereunder + will not be construed as a waiver of any subsequent breach of that right + or as a waiver of any other right. \ No newline at end of file diff --git a/incubator/binding-risingwave/NOTICE b/incubator/binding-risingwave/NOTICE new file mode 100644 index 0000000000..9024d8926d --- /dev/null +++ b/incubator/binding-risingwave/NOTICE @@ -0,0 +1,13 @@ +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +This project includes: + diff --git a/incubator/binding-risingwave/NOTICE.template b/incubator/binding-risingwave/NOTICE.template new file mode 100644 index 0000000000..209ca12f74 --- /dev/null +++ b/incubator/binding-risingwave/NOTICE.template @@ -0,0 +1,13 @@ +Licensed under the Aklivity Community License (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at + + https://www.aklivity.io/aklivity-community-license/ + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. + +This project includes: +#GENERATED_NOTICES# diff --git a/incubator/binding-risingwave/mvnw b/incubator/binding-risingwave/mvnw new file mode 100755 index 0000000000..d2f0ea3808 --- /dev/null +++ b/incubator/binding-risingwave/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/incubator/binding-risingwave/mvnw.cmd b/incubator/binding-risingwave/mvnw.cmd new file mode 100644 index 0000000000..b26ab24f03 --- /dev/null +++ b/incubator/binding-risingwave/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/incubator/binding-risingwave/pom.xml b/incubator/binding-risingwave/pom.xml new file mode 100644 index 0000000000..629e535e60 --- /dev/null +++ b/incubator/binding-risingwave/pom.xml @@ -0,0 +1,233 @@ + + + + 4.0.0 + + io.aklivity.zilla + incubator + 0.9.93 + ../pom.xml + + + binding-risingwave + zilla::incubator::binding-risingwave + + + + Aklivity Community License Agreement + https://www.aklivity.io/aklivity-community-license/ + repo + + + + + 1.00 + 0 + + + + + ${project.groupId} + binding-risingwave.spec + ${project.version} + provided + + + ${project.groupId} + engine + ${project.version} + provided + + + ${project.groupId} + engine + test-jar + ${project.version} + test + + + junit + junit + test + + + org.hamcrest + hamcrest-library + test + + + org.mockito + mockito-core + test + + + io.aklivity.k3po + control-junit + test + + + io.aklivity.k3po + lang + test + + + org.openjdk.jmh + jmh-core + test + + + org.openjdk.jmh + jmh-generator-annprocess + test + + + + + + + org.jasig.maven + maven-notice-plugin + + + ${project.groupId} + flyweight-maven-plugin + ${project.version} + + core pgsql + io.aklivity.zilla.runtime.binding.risingwave.internal.types + + + + + generate + + + + + + com.mycila + license-maven-plugin + + + maven-checkstyle-plugin + + + maven-dependency-plugin + + + process-resources + + unpack + + + + + ${project.groupId} + binding-risingwave.spec + + + ^\Qio/aklivity/zilla/specs/binding/risingwave/\E + io/aklivity/zilla/runtime/binding/risingwave/internal/ + + + + + io/aklivity/zilla/specs/binding/risingwave/schema/risingwave.schema.patch.json + ${project.build.directory}/classes + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.moditect + moditect-maven-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + io.aklivity.k3po + k3po-maven-plugin + + + ${project.groupId} + engine + ${project.version} + test-jar + + + ${project.groupId} + engine + ${project.version} + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + org.jacoco + jacoco-maven-plugin + + + io/aklivity/zilla/runtime/binding/risingwave/internal/types/**/*.class + + + + BUNDLE + + + INSTRUCTION + COVEREDRATIO + ${jacoco.coverage.ratio} + + + CLASS + MISSEDCOUNT + ${jacoco.missed.count} + + + + + + + + io.gatling + maven-shade-plugin + + + + org.agrona:agrona + io.aklivity.zilla:engine + org.openjdk.jmh:jmh-core + net.sf.jopt-simple:jopt-simple + org.apache.commons:commons-math3 + commons-cli:commons-cli + com.github.biboudis:jmh-profilers + + + + + + + diff --git a/incubator/binding-risingwave/src/main/moditect/module-info.java b/incubator/binding-risingwave/src/main/moditect/module-info.java new file mode 100644 index 0000000000..bea78da164 --- /dev/null +++ b/incubator/binding-risingwave/src/main/moditect/module-info.java @@ -0,0 +1,34 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +module io.aklivity.zilla.runtime.binding.risingwave +{ + requires io.aklivity.zilla.runtime.engine; + +/* + exports io.aklivity.zilla.runtime.binding.risingwave.config; + + provides io.aklivity.zilla.runtime.engine.binding.BindingFactorySpi + with io.aklivity.zilla.runtime.binding.risingwave.internal.RisingwaveBindingFactorySpi; + + provides io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi + with io.aklivity.zilla.runtime.binding.risingwave.internal.config.RisingwaveOptionsConfigAdapter; + + provides io.aklivity.zilla.runtime.engine.config.ConditionConfigAdapterSpi + with io.aklivity.zilla.runtime.binding.risingwave.internal.config.RisingwaveConditionConfigAdapter; + + provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi + with io.aklivity.zilla.runtime.binding.risingwave.internal.RisingwaveEventFormatterFactory; +*/ +} diff --git a/incubator/command-dump/pom.xml b/incubator/command-dump/pom.xml index 7feb0e9d62..b180033a91 100644 --- a/incubator/command-dump/pom.xml +++ b/incubator/command-dump/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla incubator - 0.9.92 + 0.9.93 ../pom.xml diff --git a/incubator/command-log/NOTICE b/incubator/command-log/NOTICE index f8254841cf..fc2a97b70c 100644 --- a/incubator/command-log/NOTICE +++ b/incubator/command-log/NOTICE @@ -13,7 +13,7 @@ under the License. This project includes: agrona under The Apache License, Version 2.0 - Apache Commons CLI under Apache-2.0 + Apache Commons CLI under Apache License, Version 2.0 ICU4J under Unicode/ICU License Jackson-annotations under The Apache Software License, Version 2.0 Jackson-core under The Apache Software License, Version 2.0 diff --git a/incubator/command-log/pom.xml b/incubator/command-log/pom.xml index ca3fbc34bf..b28e2eb36b 100644 --- a/incubator/command-log/pom.xml +++ b/incubator/command-log/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla incubator - 0.9.92 + 0.9.93 ../pom.xml @@ -79,7 +79,6 @@ commons-cli commons-cli - 1.7.0 diff --git a/incubator/command-tune/pom.xml b/incubator/command-tune/pom.xml index 405ede2300..104c16f99c 100644 --- a/incubator/command-tune/pom.xml +++ b/incubator/command-tune/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla incubator - 0.9.92 + 0.9.93 ../pom.xml diff --git a/incubator/pom.xml b/incubator/pom.xml index 41d8e0d3d1..c4b064ed57 100644 --- a/incubator/pom.xml +++ b/incubator/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla zilla - 0.9.92 + 0.9.93 ../pom.xml @@ -18,8 +18,12 @@ binding-amqp.spec + binding-pgsql.spec + binding-risingwave.spec binding-amqp + binding-pgsql + binding-risingwave command-log command-dump @@ -33,6 +37,16 @@ binding-amqp ${project.version} + + ${project.groupId} + binding-pgsql + ${project.version} + + + ${project.groupId} + binding-risingwave + ${project.version} + ${project.groupId} command-log diff --git a/manager/pom.xml b/manager/pom.xml index fca25e18d2..c06887b7d2 100644 --- a/manager/pom.xml +++ b/manager/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla zilla - 0.9.92 + 0.9.93 ../pom.xml diff --git a/pom.xml b/pom.xml index 7b183fe120..34b5865837 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ 4.0.0 io.aklivity.zilla zilla - 0.9.92 + 0.9.93 pom zilla https://github.com/aklivity/zilla @@ -425,7 +425,7 @@ maven-surefire-plugin 3.0.0-M5 - @{jacoco.java.option} --add-opens java.base/sun.nio.ch=ALL-UNNAMED + @{jacoco.java.option} -Xshare:off --add-opens java.base/sun.nio.ch=ALL-UNNAMED @@ -438,7 +438,7 @@ maven-failsafe-plugin 3.0.0-M4 - @{jacoco.java.option} --add-opens java.base/sun.nio.ch=ALL-UNNAMED -Djdk.attach.allowAttachSelf=true + @{jacoco.java.option} -Xshare:off --add-opens java.base/sun.nio.ch=ALL-UNNAMED -Djdk.attach.allowAttachSelf=true diff --git a/runtime/binding-asyncapi/pom.xml b/runtime/binding-asyncapi/pom.xml index ce05e2c2f8..5598c3a377 100644 --- a/runtime/binding-asyncapi/pom.xml +++ b/runtime/binding-asyncapi/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/composite/AsyncapiClientGenerator.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/composite/AsyncapiClientGenerator.java index 329fa530b8..b4a8fd0ede 100644 --- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/composite/AsyncapiClientGenerator.java +++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/composite/AsyncapiClientGenerator.java @@ -336,14 +336,17 @@ private KafkaTopicConfigBuilder injectKafkaTopicTransforms( AsyncapiChannelView channel, List topics) { - Optional topicConfig = topics.stream() - .filter(t -> t.name.equals(channel.address)) - .findFirst(); - topicConfig.ifPresent(kafkaTopicConfig -> topic - .transforms() - .extractKey(kafkaTopicConfig.transforms.extractKey) - .extractHeaders(kafkaTopicConfig.transforms.extractHeaders) - .build()); + if (topics != null) + { + Optional topicConfig = topics.stream() + .filter(t -> t.name.equals(channel.address)) + .findFirst(); + topicConfig.ifPresent(kafkaTopicConfig -> topic + .transforms() + .extractKey(kafkaTopicConfig.transforms.extractKey) + .extractHeaders(kafkaTopicConfig.transforms.extractHeaders) + .build()); + } return topic; } diff --git a/runtime/binding-asyncapi/src/main/moditect/module-info.java b/runtime/binding-asyncapi/src/main/moditect/module-info.java index 9af11d62aa..47a4ed8587 100644 --- a/runtime/binding-asyncapi/src/main/moditect/module-info.java +++ b/runtime/binding-asyncapi/src/main/moditect/module-info.java @@ -46,6 +46,7 @@ opens io.aklivity.zilla.runtime.binding.asyncapi.internal.model.bindings.kafka; opens io.aklivity.zilla.runtime.binding.asyncapi.internal.model.bindings.sse; opens io.aklivity.zilla.runtime.binding.asyncapi.internal.model.bindings.sse.kafka; + opens io.aklivity.zilla.runtime.binding.asyncapi.internal.model.parser; opens io.aklivity.zilla.runtime.binding.asyncapi.internal.view; exports io.aklivity.zilla.runtime.binding.asyncapi.config; diff --git a/runtime/binding-echo/pom.xml b/runtime/binding-echo/pom.xml index 4ed9644fd2..1dc98a1f84 100644 --- a/runtime/binding-echo/pom.xml +++ b/runtime/binding-echo/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-fan/pom.xml b/runtime/binding-fan/pom.xml index 849f022211..d78a6e09d5 100644 --- a/runtime/binding-fan/pom.xml +++ b/runtime/binding-fan/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-filesystem/pom.xml b/runtime/binding-filesystem/pom.xml index 4e9578369f..57a901e593 100644 --- a/runtime/binding-filesystem/pom.xml +++ b/runtime/binding-filesystem/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-grpc-kafka/pom.xml b/runtime/binding-grpc-kafka/pom.xml index 928aa31548..a7fa8e9740 100644 --- a/runtime/binding-grpc-kafka/pom.xml +++ b/runtime/binding-grpc-kafka/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-grpc-kafka/src/main/java/io/aklivity/zilla/runtime/binding/grpc/kafka/internal/config/GrpcKafkaConditionConfigAdapter.java b/runtime/binding-grpc-kafka/src/main/java/io/aklivity/zilla/runtime/binding/grpc/kafka/internal/config/GrpcKafkaConditionConfigAdapter.java index fa829dc196..ed43228c99 100644 --- a/runtime/binding-grpc-kafka/src/main/java/io/aklivity/zilla/runtime/binding/grpc/kafka/internal/config/GrpcKafkaConditionConfigAdapter.java +++ b/runtime/binding-grpc-kafka/src/main/java/io/aklivity/zilla/runtime/binding/grpc/kafka/internal/config/GrpcKafkaConditionConfigAdapter.java @@ -128,6 +128,8 @@ public ConditionConfig adaptFromJson( textValue = ((JsonString) v).getString(); base64Value = encoder64.encodeToString(textValue.getBytes()); break; + default: + break; } GrpcKafkaMetadataValueConfig metadataValue = new GrpcKafkaMetadataValueConfig(new String16FW(textValue), diff --git a/runtime/binding-grpc-kafka/src/main/java/io/aklivity/zilla/runtime/binding/grpc/kafka/internal/config/GrpcKafkaWithProduceHash.java b/runtime/binding-grpc-kafka/src/main/java/io/aklivity/zilla/runtime/binding/grpc/kafka/internal/config/GrpcKafkaWithProduceHash.java index a3a9e7483a..17d6d2446b 100644 --- a/runtime/binding-grpc-kafka/src/main/java/io/aklivity/zilla/runtime/binding/grpc/kafka/internal/config/GrpcKafkaWithProduceHash.java +++ b/runtime/binding-grpc-kafka/src/main/java/io/aklivity/zilla/runtime/binding/grpc/kafka/internal/config/GrpcKafkaWithProduceHash.java @@ -66,7 +66,7 @@ public OctetsFW correlationId() if (digest != null && correlationId != null) { - octetsRW.reset(); + octetsRW.rewrap(); newCorrelationId = octetsRW.put(correlationId).put(dashOctets).put(toHex(digest).getBytes()).build(); } else diff --git a/runtime/binding-grpc/pom.xml b/runtime/binding-grpc/pom.xml index 2416642240..4cb77e58c5 100644 --- a/runtime/binding-grpc/pom.xml +++ b/runtime/binding-grpc/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-grpc/src/main/java/io/aklivity/zilla/runtime/binding/grpc/internal/stream/GrpcServerFactory.java b/runtime/binding-grpc/src/main/java/io/aklivity/zilla/runtime/binding/grpc/internal/stream/GrpcServerFactory.java index c3ead3e2ee..d91738fba8 100644 --- a/runtime/binding-grpc/src/main/java/io/aklivity/zilla/runtime/binding/grpc/internal/stream/GrpcServerFactory.java +++ b/runtime/binding-grpc/src/main/java/io/aklivity/zilla/runtime/binding/grpc/internal/stream/GrpcServerFactory.java @@ -299,6 +299,7 @@ public MessageConsumer newStream( final OctetsFW extension = begin.extension(); final HttpBeginExFW httpBeginEx = extension.get(httpBeginExRO::tryWrap); + @SuppressWarnings("resource") MessageConsumer newStream = (t, b, i, l) -> {}; if (!isGrpcRequestMethod(httpBeginEx)) diff --git a/runtime/binding-grpc/src/main/zilla/protocol.idl b/runtime/binding-grpc/src/main/zilla/protocol.idl index 30ef20e8fb..9643ceffda 100644 --- a/runtime/binding-grpc/src/main/zilla/protocol.idl +++ b/runtime/binding-grpc/src/main/zilla/protocol.idl @@ -18,10 +18,10 @@ scope protocol scope codec { - struct GrpcMessage - { - uint8 flag; - int32 length; - } + struct GrpcMessage + { + uint8 flag; + int32 length; + } } } diff --git a/runtime/binding-http-filesystem/pom.xml b/runtime/binding-http-filesystem/pom.xml index ad3c8d0c38..f4c89c534e 100644 --- a/runtime/binding-http-filesystem/pom.xml +++ b/runtime/binding-http-filesystem/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-http-kafka/pom.xml b/runtime/binding-http-kafka/pom.xml index 0f42c6e539..4555a8ce16 100644 --- a/runtime/binding-http-kafka/pom.xml +++ b/runtime/binding-http-kafka/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-http/pom.xml b/runtime/binding-http/pom.xml index 9c9f217797..6eb2903986 100644 --- a/runtime/binding-http/pom.xml +++ b/runtime/binding-http/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/config/HttpWithConfig.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/config/HttpWithConfig.java index 2edb587c60..004a0ab12d 100644 --- a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/config/HttpWithConfig.java +++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/config/HttpWithConfig.java @@ -15,12 +15,17 @@ */ package io.aklivity.zilla.runtime.binding.http.config; +import java.util.Map; import java.util.function.Function; +import io.aklivity.zilla.runtime.binding.http.internal.types.String16FW; +import io.aklivity.zilla.runtime.binding.http.internal.types.String8FW; import io.aklivity.zilla.runtime.engine.config.WithConfig; public final class HttpWithConfig extends WithConfig { + public final Map overrides; + public static HttpWithConfigBuilder builder() { return new HttpWithConfigBuilder<>(HttpWithConfig.class::cast); @@ -33,8 +38,10 @@ public static HttpWithConfigBuilder builder( } HttpWithConfig( - long compositeId) + long compositeId, + Map overrides) { super(compositeId); + this.overrides = overrides; } } diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/config/HttpWithConfigBuilder.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/config/HttpWithConfigBuilder.java index bd047a7cf4..0581f45244 100644 --- a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/config/HttpWithConfigBuilder.java +++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/config/HttpWithConfigBuilder.java @@ -17,8 +17,12 @@ import static io.aklivity.zilla.runtime.engine.config.WithConfig.NO_COMPOSITE_ID; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.function.Function; +import io.aklivity.zilla.runtime.binding.http.internal.types.String16FW; +import io.aklivity.zilla.runtime.binding.http.internal.types.String8FW; import io.aklivity.zilla.runtime.engine.config.ConfigBuilder; import io.aklivity.zilla.runtime.engine.config.WithConfig; @@ -27,6 +31,7 @@ public final class HttpWithConfigBuilder extends ConfigBuilder mapper; private long compositeId = NO_COMPOSITE_ID; + private Map overrides; HttpWithConfigBuilder( Function mapper) @@ -34,6 +39,17 @@ public final class HttpWithConfigBuilder extends ConfigBuilder builder() + { + return new HttpWithConfigBuilder<>(HttpWithConfig.class::cast); + } + + public static HttpWithConfigBuilder builder( + Function mapper) + { + return new HttpWithConfigBuilder<>(mapper); + } + @Override @SuppressWarnings("unchecked") protected Class> thisType() @@ -48,8 +64,20 @@ public HttpWithConfigBuilder compositeId( return this; } + public HttpWithConfigBuilder override( + String8FW name, + String16FW value) + { + if (overrides == null) + { + overrides = new LinkedHashMap<>(); + } + overrides.put(name, value); + return this; + } + public T build() { - return mapper.apply(new HttpWithConfig(compositeId)); + return mapper.apply(new HttpWithConfig(compositeId, overrides)); } } diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpBindingConfig.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpBindingConfig.java index 05a6eea2c4..7dbb8ad5a5 100644 --- a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpBindingConfig.java +++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpBindingConfig.java @@ -78,7 +78,8 @@ public HttpBindingConfig( this.name = binding.name; this.kind = binding.kind; this.options = HttpOptionsConfig.class.cast(binding.options); - this.routes = binding.routes.stream().map(HttpRouteConfig::new).collect(toList()); + this.routes = binding.routes.stream().map(route -> + new HttpRouteConfig(route, options != null ? options.overrides : null)).collect(toList()); this.resolveId = binding.resolveId; this.credentials = options != null && options.authorization != null ? asAccessor(options.authorization.credentials) : DEFAULT_CREDENTIALS; diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpConditionMatcher.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpConditionMatcher.java index 253040c8b3..ad5c4bacdc 100644 --- a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpConditionMatcher.java +++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpConditionMatcher.java @@ -17,6 +17,7 @@ import java.util.LinkedHashMap; import java.util.Map; +import java.util.function.Consumer; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -26,6 +27,7 @@ public final class HttpConditionMatcher { private final Map headersMatch; + private Consumer observer; public HttpConditionMatcher( HttpConditionConfig condition) @@ -33,6 +35,28 @@ public HttpConditionMatcher( this.headersMatch = condition.headers != null ? asMatcherMap(condition.headers) : null; } + public void observe( + Consumer observer) + { + this.observer = observer; + } + + private boolean observeMatched() + { + if (observer != null) + { + observer.accept(this); + } + + return true; + } + + public String parameter( + String name) + { + return headersMatch.get(":path").group(name); + } + public boolean matches( Function headerByName) { @@ -49,7 +73,7 @@ public boolean matches( } } - return match; + return match && observeMatched(); } private static Map asMatcherMap( @@ -64,7 +88,10 @@ private static Matcher asMatcher( String header, String wildcard) { - String pattern = wildcard.replace(".", "\\.").replace("*", ".*"); + String pattern = wildcard + .replace(".", "\\.") + .replace("*", ".*") + .replaceAll("\\{([a-zA-Z_]+)\\}", "(?<$1>.+)"); if (":path".equals(header) && !pattern.endsWith(".*")) { diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpRouteConfig.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpRouteConfig.java index 740f9b1702..f0e2a16e34 100644 --- a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpRouteConfig.java +++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpRouteConfig.java @@ -18,12 +18,17 @@ import static io.aklivity.zilla.runtime.engine.config.WithConfig.NO_COMPOSITE_ID; import static java.util.stream.Collectors.toList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.function.Function; import java.util.function.LongPredicate; import io.aklivity.zilla.runtime.binding.http.config.HttpConditionConfig; import io.aklivity.zilla.runtime.binding.http.config.HttpWithConfig; +import io.aklivity.zilla.runtime.binding.http.internal.types.String16FW; +import io.aklivity.zilla.runtime.binding.http.internal.types.String8FW; import io.aklivity.zilla.runtime.engine.config.RouteConfig; public final class HttpRouteConfig @@ -31,24 +36,44 @@ public final class HttpRouteConfig public final long id; private final List when; - private final HttpWithConfig with; + private final HttpWithResolver with; private final LongPredicate authorized; + private final Map overrides; public HttpRouteConfig( - RouteConfig route) + RouteConfig route, + Map overrides) { this.id = route.id; + this.with = Optional.ofNullable(route.with) + .map(HttpWithConfig.class::cast) + .map(HttpWithResolver::new) + .orElse(null); this.when = route.when.stream() .map(HttpConditionConfig.class::cast) .map(HttpConditionMatcher::new) + .peek(m -> Optional.ofNullable(with).ifPresent(w -> m.observe(w::onConditionMatched))) .collect(toList()); - this.with = (HttpWithConfig)route.with; this.authorized = route.authorized; + this.overrides = new LinkedHashMap<>(); + if (overrides != null) + { + this.overrides.putAll(overrides); + } } public long compositeId() { - return with != null ? with.compositeId : NO_COMPOSITE_ID; + return with != null ? with.compositeId() : NO_COMPOSITE_ID; + } + + public Map overrides() + { + if (with != null) + { + overrides.putAll(with.resolveOverrides()); + } + return overrides; } boolean authorized( diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithConfigAdapter.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithConfigAdapter.java new file mode 100644 index 0000000000..43ec50f2f8 --- /dev/null +++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithConfigAdapter.java @@ -0,0 +1,82 @@ +/* + * Copyright 2021-2023 Aklivity Inc. + * + * Aklivity licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.aklivity.zilla.runtime.binding.http.internal.config; + +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonObjectBuilder; +import jakarta.json.JsonString; +import jakarta.json.bind.adapter.JsonbAdapter; + +import io.aklivity.zilla.runtime.binding.http.config.HttpWithConfig; +import io.aklivity.zilla.runtime.binding.http.config.HttpWithConfigBuilder; +import io.aklivity.zilla.runtime.binding.http.internal.HttpBinding; +import io.aklivity.zilla.runtime.binding.http.internal.types.String16FW; +import io.aklivity.zilla.runtime.binding.http.internal.types.String8FW; +import io.aklivity.zilla.runtime.engine.config.WithConfig; +import io.aklivity.zilla.runtime.engine.config.WithConfigAdapterSpi; + +public class HttpWithConfigAdapter implements WithConfigAdapterSpi, JsonbAdapter +{ + private static final String HEADERS_NAME = "headers"; + private static final String OVERRIDES_NAME = "overrides"; + + @Override + public String type() + { + return HttpBinding.NAME; + } + + @Override + public JsonObject adaptToJson( + WithConfig with) + { + HttpWithConfig config = (HttpWithConfig) with; + + JsonObjectBuilder object = Json.createObjectBuilder(); + + if (config.overrides != null && + !config.overrides.isEmpty()) + { + JsonObjectBuilder entries = Json.createObjectBuilder(); + config.overrides.forEach((k, v) -> entries.add(k.asString(), v.asString())); + + object.add(HEADERS_NAME, object.add(OVERRIDES_NAME, entries)); + } + + return object.build(); + } + + @Override + public WithConfig adaptFromJson( + JsonObject object) + { + HttpWithConfigBuilder with = HttpWithConfigBuilder.builder(); + + if (object.containsKey(HEADERS_NAME)) + { + JsonObject headers = object.getJsonObject(HEADERS_NAME); + if (headers.containsKey(OVERRIDES_NAME)) + { + headers.getJsonObject(OVERRIDES_NAME) + .forEach((k, v) -> + with.override(new String8FW(k), new String16FW(JsonString.class.cast(v).getString()))); + } + } + + return with.build(); + } +} diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithResolver.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithResolver.java new file mode 100644 index 0000000000..df3967a712 --- /dev/null +++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithResolver.java @@ -0,0 +1,76 @@ +/* + * Copyright 2021-2023 Aklivity Inc. + * + * Aklivity licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.aklivity.zilla.runtime.binding.http.internal.config; + +import static io.aklivity.zilla.runtime.engine.config.WithConfig.NO_COMPOSITE_ID; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import io.aklivity.zilla.runtime.binding.http.config.HttpWithConfig; +import io.aklivity.zilla.runtime.binding.http.internal.types.String16FW; +import io.aklivity.zilla.runtime.binding.http.internal.types.String8FW; + +public class HttpWithResolver +{ + private static final Pattern PARAMS_PATTERN = Pattern.compile("\\$\\{params\\.([a-zA-Z_]+)\\}"); + + private final Matcher paramsMatcher; + private final HttpWithConfig with; + + private Function replacer = r -> null; + + public HttpWithResolver( + HttpWithConfig with) + { + this.paramsMatcher = PARAMS_PATTERN.matcher(""); + this.with = with; + } + + public void onConditionMatched( + HttpConditionMatcher condition) + { + this.replacer = r -> condition.parameter(r.group(1)); + } + + public long compositeId() + { + return with != null ? with.compositeId : NO_COMPOSITE_ID; + } + + public Map resolveOverrides() + { + Map overrides = new LinkedHashMap<>(); + if (with != null && with.overrides != null) + { + with.overrides.forEach((k, v) -> + { + String value = v.asString(); + Matcher overrideMatcher = paramsMatcher.reset(value); + if (overrideMatcher.find()) + { + value = overrideMatcher.replaceAll(replacer); + } + overrides.put(k, new String16FW(value)); + }); + } + return overrides; + } +} diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/stream/HttpServerFactory.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/stream/HttpServerFactory.java index ac13062a0b..9b07035fe3 100644 --- a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/stream/HttpServerFactory.java +++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/stream/HttpServerFactory.java @@ -1072,9 +1072,10 @@ else if (!isCorsRequestAllowed(server.binding, headers)) HttpRouteConfig route = binding.resolve(exchangeAuth, headers::get); if (route != null) { - if (binding.options != null && binding.options.overrides != null) + Map overrides = route.overrides(); + if (overrides != null) { - binding.options.overrides.forEach((k, v) -> headers.put(k.asString(), v.asString())); + overrides.forEach((k, v) -> headers.put(k.asString(), v.asString())); final HttpBeginExFW.Builder newBeginEx = newBeginExRW.wrap(codecBuffer, 0, codecBuffer.capacity()) .typeId(httpTypeId); @@ -1274,13 +1275,13 @@ else if (!"chunked".equals(value)) break; case "upgrade": - if (server.decoder != decodeHeadersOnly) + if ("h2c".equals(value)) { - error = ERROR_400_BAD_REQUEST; + // TODO: h2c } - else if ("h2c".equals(value)) + else if (server.decoder != decodeHeadersOnly) { - // TODO: h2c + error = ERROR_400_BAD_REQUEST; } else { @@ -5014,9 +5015,10 @@ else if (!isCorsRequestAllowed(binding, headers)) HttpPolicyConfig policy = binding.access().effectivePolicy(headers); final String origin = policy == CROSS_ORIGIN ? headers.get(HEADER_NAME_ORIGIN) : null; - if (binding.options != null && binding.options.overrides != null) + Map overrides = route.overrides(); + if (overrides != null) { - binding.options.overrides.forEach((k, v) -> headers.put(k.asString(), v.asString())); + overrides.forEach((k, v) -> headers.put(k.asString(), v.asString())); } final HttpBeginExFW beginEx = beginExRW.wrap(extBuffer, 0, extBuffer.capacity()) @@ -5395,9 +5397,10 @@ private void doEncodePromise( if (pushId != -1) { - if (binding.options != null && binding.options.overrides != null) + Map overrides = route.overrides(); + if (overrides != null) { - binding.options.overrides.forEach((k, v) -> headers.put(k.asString(), v.asString())); + overrides.forEach((k, v) -> headers.put(k.asString(), v.asString())); } final long originId = this.routedId; diff --git a/runtime/binding-http/src/main/moditect/module-info.java b/runtime/binding-http/src/main/moditect/module-info.java index b837b223eb..337a22e0e8 100644 --- a/runtime/binding-http/src/main/moditect/module-info.java +++ b/runtime/binding-http/src/main/moditect/module-info.java @@ -30,4 +30,7 @@ provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi with io.aklivity.zilla.runtime.binding.http.internal.HttpEventFormatterFactory; + + provides io.aklivity.zilla.runtime.engine.config.WithConfigAdapterSpi + with io.aklivity.zilla.runtime.binding.http.internal.config.HttpWithConfigAdapter; } diff --git a/runtime/binding-http/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.config.WithConfigAdapterSpi b/runtime/binding-http/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.config.WithConfigAdapterSpi new file mode 100644 index 0000000000..60e65efc04 --- /dev/null +++ b/runtime/binding-http/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.config.WithConfigAdapterSpi @@ -0,0 +1 @@ +io.aklivity.zilla.runtime.binding.http.internal.config.HttpWithConfigAdapter diff --git a/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithConfigAdapterTest.java b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithConfigAdapterTest.java new file mode 100644 index 0000000000..77072c7086 --- /dev/null +++ b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/config/HttpWithConfigAdapterTest.java @@ -0,0 +1,89 @@ +/* + * Copyright 2021-2023 Aklivity Inc. + * + * Aklivity licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.aklivity.zilla.runtime.binding.http.internal.config; + +import static java.util.Collections.singletonMap; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; + +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; + +import org.junit.Before; +import org.junit.Test; + +import io.aklivity.zilla.runtime.binding.http.config.HttpWithConfig; +import io.aklivity.zilla.runtime.binding.http.internal.types.String16FW; +import io.aklivity.zilla.runtime.binding.http.internal.types.String8FW; + +public class HttpWithConfigAdapterTest +{ + private Jsonb jsonb; + + @Before + public void initJson() + { + JsonbConfig config = new JsonbConfig() + .withAdapters(new HttpWithConfigAdapter()); + jsonb = JsonbBuilder.create(config); + } + + @Test + public void shouldReadWith() + { + String text = + "{" + + "\"headers\":" + + "{" + + "\"overrides\":" + + "{" + + "\":authority\":\"example.com:443\"" + + "}" + + "}" + + "}"; + + HttpWithConfig with = jsonb.fromJson(text, HttpWithConfig.class); + + assertThat(with, not(nullValue())); + assertThat(with.overrides, equalTo(singletonMap(new String8FW(":authority"), new String16FW("example.com:443")))); + } + + @Test + public void shouldWriteWith() + { + HttpWithConfig with = HttpWithConfig.builder() + .override(new String8FW(":authority"), new String16FW("example.com:443")).build(); + + String text = jsonb.toJson(with); + + String expected = + "{" + + "\"headers\":" + + "{" + + "\"overrides\":" + + "{" + + "\":authority\":\"example.com:443\"" + + "}" + + "}" + + "}"; + + assertThat(text, not(nullValue())); + assertThat(text, equalTo(expected)); + } +} diff --git a/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7230/server/ConnectionManagementIT.java b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7230/server/ConnectionManagementIT.java index b4d836ddc3..6929a57c79 100644 --- a/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7230/server/ConnectionManagementIT.java +++ b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7230/server/ConnectionManagementIT.java @@ -69,6 +69,16 @@ public void shouldSendRequestWithHeaderOverride() throws Exception k3po.finish(); } + @Test + @Configuration("server.with.route.header.overrides.yaml") + @Specification({ + "${net}/request.with.route.header.overrides/client", + "${app}/request.with.route.header.overrides/server" }) + public void shouldSendRequestWithRouteHeaderOverrides() throws Exception + { + k3po.finish(); + } + @Test @Configuration("server.yaml") @Specification({ diff --git a/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/ConnectionManagementIT.java b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/ConnectionManagementIT.java index 1df4192ad0..430788c466 100644 --- a/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/ConnectionManagementIT.java +++ b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/ConnectionManagementIT.java @@ -82,6 +82,16 @@ public void httpGetExchangeWithHeaderOverride() throws Exception k3po.finish(); } + @Test + @Configuration("server.with.route.header.overrides.yaml") + @Specification({ + "${net}/http.get.exchange.with.route.header.overrides/client", + "${app}/http.get.exchange.with.route.header.overrides/server" }) + public void httpGetExchangeWithRouteHeaderOverrides() throws Exception + { + k3po.finish(); + } + @Test @Configuration("server.yaml") @Specification({ diff --git a/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/StartingIT.java b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/StartingIT.java index c0c9f9fc89..353a3d4bcc 100644 --- a/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/StartingIT.java +++ b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/StartingIT.java @@ -79,6 +79,16 @@ public void shouldNotUpgradeViaCleartextWithTlsAndNoAlpn() throws Exception k3po.finish(); } + @Test + @Configuration("server.yaml") + @Specification({ + "${net}/upgrade.h2c.with.no.settings/client", + "${app}/upgrade.http/server" }) + public void shouldUpgradeViaCleartextWithNoSettings() throws Exception + { + k3po.finish(); + } + @Ignore("TODO") @Test @Configuration("server.yaml") diff --git a/runtime/binding-kafka-grpc/pom.xml b/runtime/binding-kafka-grpc/pom.xml index 4b5989d488..8737cc65df 100644 --- a/runtime/binding-kafka-grpc/pom.xml +++ b/runtime/binding-kafka-grpc/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-kafka/pom.xml b/runtime/binding-kafka/pom.xml index 2a346dcd47..551d2c6310 100644 --- a/runtime/binding-kafka/pom.xml +++ b/runtime/binding-kafka/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/cache/KafkaCachePartition.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/cache/KafkaCachePartition.java index 5e5ff2402b..e043c21e25 100644 --- a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/cache/KafkaCachePartition.java +++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/cache/KafkaCachePartition.java @@ -128,7 +128,7 @@ public final class KafkaCachePartition private final KafkaCachePaddedKeyFW.Builder paddedKeyRW = new KafkaCachePaddedKeyFW.Builder() .wrap(new UnsafeBuffer(new byte[8192]), 0, 8192);; private final String32FW.Builder stringRW = new String32FW.Builder() - .wrap(new UnsafeBuffer(new byte[256]), 0, 256);; + .wrap(new UnsafeBuffer(new byte[256]), 0, 256); private final Varint32FW.Builder varintRW = new Varint32FW.Builder().wrap(new UnsafeBuffer(new byte[5]), 0, 5); private final Array32FW headersRO = new Array32FW(new KafkaHeaderFW()); private final Array32FW.Builder trailersRW = diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaCacheClientProduceFactory.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaCacheClientProduceFactory.java index d7d13978ae..c0b2ec05cf 100644 --- a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaCacheClientProduceFactory.java +++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaCacheClientProduceFactory.java @@ -800,15 +800,15 @@ stream.valueMark, stream.valueLimit, now().toEpochMilli(), stream.initialId, PRO Array32FW trailers = EMPTY_TRAILERS; partition.writeProduceEntryFin(stream.segment, stream.entryMark, stream.valueLimit, stream.initialSeq, trailers); + markEntryDirty(traceId, stream.partitionOffset); flushClientFanInitialIfNecessary(traceId); } else { error = ERROR_RECORD_LIST_TOO_LARGE; + markEntryDirty(traceId, stream.partitionOffset); } - markEntryDirty(traceId, stream.partitionOffset); - if (error != NO_ERROR) { stream.cleanupClient(traceId, error); @@ -1390,6 +1390,8 @@ private void onClientInitialFlush( } } + initialAck += reserved; + final int noAck = (int) (initialSeq - initialAck); doClientInitialWindow(traceId, noAck, initialBudgetMax); } diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientConnectionPool.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientConnectionPool.java index 12ff00897a..0aed054b56 100644 --- a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientConnectionPool.java +++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientConnectionPool.java @@ -1651,6 +1651,7 @@ private void cleanupStreams( streamsByInitialId.remove(s); }); streams.clear(); + signalerCorrelations.clear(); } private void onConnectionSignal( @@ -1808,11 +1809,7 @@ private void cleanupConnection( doConnectionAbort(traceId); doConnectionReset(traceId); - streams.clear(); - requests.clear(); - responses.clear(); - responseAcks.clear(); - signalerCorrelations.clear(); + cleanupStreams(traceId); } private void cleanupBudgetCreditorIfNecessary() diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientProduceFactory.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientProduceFactory.java index 7ecd21c10c..c0c713d083 100644 --- a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientProduceFactory.java +++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientProduceFactory.java @@ -111,7 +111,7 @@ public final class KafkaClientProduceFactory extends KafkaClientSaslHandshaker i private static final DirectBuffer EMPTY_BUFFER = new UnsafeBuffer(); private static final OctetsFW EMPTY_OCTETS = new OctetsFW().wrap(EMPTY_BUFFER, 0, 0); private static final Consumer EMPTY_EXTENSION = ex -> {}; - private static final Array32FW EMPTY_HEADER = + private static final Array32FW EMPTY_HEADERS = new Array32FW.Builder<>(new KafkaHeaderFW.Builder(), new KafkaHeaderFW()) .wrap(new UnsafeBuffer(new byte[64]), 0, 64).build(); @@ -128,7 +128,6 @@ public final class KafkaClientProduceFactory extends KafkaClientSaslHandshaker i private final ExtensionFW extensionRO = new ExtensionFW(); private final KafkaBeginExFW kafkaBeginExRO = new KafkaBeginExFW(); private final KafkaDataExFW kafkaDataExRO = new KafkaDataExFW(); - private final Array32FW kafkaHeaderRO = new Array32FW<>(new KafkaHeaderFW()); private final BeginFW.Builder beginRW = new BeginFW.Builder(); private final DataFW.Builder dataRW = new DataFW.Builder(); @@ -594,7 +593,17 @@ private int flushRecordContFin( if ((flags & FLAGS_FIN) == FLAGS_FIN) { - client.doEncodeRecordFin(traceId, budgetId); + Array32FW headers = EMPTY_HEADERS; + + final KafkaDataExFW kafkaDataEx = extension.get(kafkaDataExRO::tryWrap); + if (kafkaDataEx != null) + { + assert kafkaDataEx.kind() == KafkaDataExFW.KIND_PRODUCE; + final KafkaProduceDataExFW kafkaProduceDataEx = kafkaDataEx.produce(); + headers = kafkaProduceDataEx.headers(); + } + + client.doEncodeRecordFin(traceId, budgetId, headers); assert progress == limit; client.flusher = flushRecord; client.flushFlags = FLAGS_FIN; @@ -1223,7 +1232,6 @@ private final class KafkaProduceClient extends KafkaSaslClient private int encodeSlotLimit; private long encodeSlotTraceId; - private int flushableRecordHeadersBytes; private int encodeableRecordBytesDeferred; private int encodeableRecordBatchSlotOffset; private int flushableRequestBytes; @@ -1320,6 +1328,8 @@ private void onNetworkBegin( } private long networkBytesReceived; + private long headersChecksum; + private int headersSize; private void onNetworkData( DataFW data) @@ -1605,8 +1615,7 @@ private void flush( final int length = limit - progress; if (encodeSlot != NO_SLOT && flushableRequestBytes > 0 && - encodeSlotLimit + length + produceRecordFramingSize + flushableRecordHeadersBytes > - encodePool.slotCapacity()) + encodeSlotLimit + length + produceRecordFramingSize > encodePool.slotCapacity()) { doNetworkData(traceId, budgetId, EMPTY_BUFFER, 0, 0); } @@ -1738,14 +1747,7 @@ private void doEncodeRecordInit( encodeSlotBuffer.putInt(encodeableRecordBatchSlotOffset + RecordBatchFW.FIELD_OFFSET_RECORD_COUNT, recordCount + 1, BIG_ENDIAN); - if (headersCount > 0) - { - flushableRecordHeadersBytes = headers.sizeof(); - - final int encodeSlotMaxLimit = encodePool.slotCapacity() - flushableRecordHeadersBytes; - encodeSlotBuffer.putBytes(encodeSlotMaxLimit, headers.buffer(), headers.offset(), - flushableRecordHeadersBytes); - } + doEncodeHeadersChecksum(headers); } private void doEncodeRecordCont( @@ -1758,8 +1760,7 @@ private void doEncodeRecordCont( { final int length = value.sizeof(); - final int encodeableBytes = produceRecordFramingSize + encodeSlotLimit + - length + flushableRecordHeadersBytes; + final int encodeableBytes = produceRecordFramingSize + encodeSlotLimit + length; if (encodeableBytes >= encodePool.slotCapacity()) { doEncodeRequestIfNecessary(traceId, budgetId); @@ -1780,7 +1781,8 @@ private void doEncodeRecordCont( private void doEncodeRecordFin( long traceId, - long budgetId) + long budgetId, + Array32FW headers) { assert encodeSlot != NO_SLOT; final MutableDirectBuffer encodeSlotBuffer = encodePool.buffer(encodeSlot); @@ -1789,14 +1791,6 @@ private void doEncodeRecordFin( final int encodeLimit = writeBuffer.capacity(); int encodeProgress = 0; - Array32FW headers = EMPTY_HEADER; - if (flushableRecordHeadersBytes > 0) - { - final int encodeSlotMaxLimit = encodePool.slotCapacity(); - headers = kafkaHeaderRO.wrap(encodeSlotBuffer, encodeSlotMaxLimit - flushableRecordHeadersBytes, - encodeSlotMaxLimit); - flushableRecordHeadersBytes = 0; - } final int headersCount = headers.fieldCount(); final RecordTrailerFW recordTrailer = recordTrailerRW.wrap(encodeBuffer, encodeProgress, encodeLimit) .headerCount(headersCount) @@ -1816,7 +1810,7 @@ private void doEncodeRecordFin( encodeSlotBuffer.putBytes(encodeSlotLimit, encodeBuffer, 0, encodeProgress); encodeSlotLimit += encodeProgress; - if (encodeableRecordBytesDeferred > 0) + if (encodeableRecordBytesDeferred > 0 && flushableRequestBytes > 0) { doNetworkData(traceId, budgetId, EMPTY_BUFFER, 0, 0); } @@ -1952,9 +1946,40 @@ private void doEncodeProduceRequest( decoder = decodeProduceResponse; } - private void encodeCrc() + private void doEncodeHeadersChecksum( + Array32FW headers) { final MutableDirectBuffer encodeBuffer = writeBuffer; + final int encodeLimit = writeBuffer.capacity(); + + int encodeProgress = 0; + + final int headersCount = headers.fieldCount(); + final RecordTrailerFW recordTrailer = recordTrailerRW.wrap(encodeBuffer, encodeProgress, encodeLimit) + .headerCount(headersCount) + .build(); + + encodeProgress = recordTrailer.limit(); + + if (headersCount > 0) + { + final DirectBuffer headerItems = headers.items(); + final int headerItemsSize = headerItems.capacity(); + + encodeBuffer.putBytes(encodeProgress, headerItems, 0, headerItemsSize); + encodeProgress += headerItemsSize; + } + + final byte[] encodeByteBuf = encodeBuffer.byteArray(); + crc32c.reset(); + crc32c.update(encodeByteBuf, 0, encodeProgress); + + headersChecksum = crc32c.getValue(); + headersSize = encodeProgress; + } + + private void encodeCrc() + { final MutableDirectBuffer encodeSlotBuffer = encodePool.buffer(encodeSlot); final int encodeLimit = encodeSlotLimit; @@ -1969,7 +1994,8 @@ private void encodeCrc() final int crcOffset = recordBatch.offset() + RecordBatchFW.FIELD_OFFSET_CRC; final int crcDataOffset = recordBatch.offset() + RecordBatchFW.FIELD_OFFSET_ATTRIBUTES; - final int crcDataLimit = recordBatchLimit <= encodeLimit ? recordBatchLimit : recordBatch.limit(); + final int recordHeaderLimit = encodeLimit - (valueCompleteSize - encodeableRecordBytesDeferred); + final int crcDataLimit = recordBatchLimit <= encodeLimit ? recordBatchLimit : recordHeaderLimit; final ByteBuffer encodeSlotByteBuffer = encodePool.byteBuffer(encodeSlot); final int encodePosition = encodeSlotByteBuffer.position(); @@ -1981,10 +2007,10 @@ private void encodeCrc() crc.update(encodeSlotByteBuffer); long checksum = crc.getValue(); - - if (crcDataLimit == recordBatch.limit()) + if (crcDataLimit == recordHeaderLimit && valueCompleteSize != 0) { - checksum = computeChecksum(encodeBuffer, encodeLimit, encodeProgress, encodeSlotBuffer, checksum); + checksum = combineCRC32C(checksum, valueChecksum, valueCompleteSize); + checksum = combineCRC32C(checksum, headersChecksum, headersSize); } encodeSlotBuffer.putInt(crcOffset, (int) checksum, BIG_ENDIAN); @@ -1993,48 +2019,6 @@ private void encodeCrc() } } - private long computeChecksum( - MutableDirectBuffer encodeBuffer, - int encodeLimit, - int encodeProgress, - MutableDirectBuffer encodeSlotBuffer, - long checksum) - { - final int oldEncodeProgress = encodeProgress; - - checksum = combineCRC32C(checksum, valueChecksum, valueCompleteSize); - - Array32FW headers = EMPTY_HEADER; - if (flushableRecordHeadersBytes > 0) - { - final int encodeSlotMaxLimit = encodePool.slotCapacity(); - headers = kafkaHeaderRO.wrap(encodeSlotBuffer, encodeSlotMaxLimit - flushableRecordHeadersBytes, - encodeSlotMaxLimit); - } - final int headersCount = headers.fieldCount(); - final RecordTrailerFW recordTrailer = recordTrailerRW.wrap(encodeBuffer, encodeProgress, encodeLimit) - .headerCount(headersCount) - .build(); - - encodeProgress = recordTrailer.limit(); - - if (headersCount > 0) - { - final DirectBuffer headerItems = headers.items(); - final int headerItemsSize = headerItems.capacity(); - - encodeBuffer.putBytes(encodeProgress, headerItems, 0, headerItemsSize); - encodeProgress += headerItemsSize; - } - - final int length = encodeProgress - oldEncodeProgress; - final byte[] encodeByteBuf = encodeBuffer.byteArray(); - crc32c.reset(); - crc32c.update(encodeByteBuf, oldEncodeProgress, length); - checksum = combineCRC32C(checksum, crc32c.getValue(), length); - return checksum; - } - private void encodeNetwork( long traceId, long authorization, @@ -2121,9 +2105,9 @@ private void encodeNetwork( } else if (encodeableRecordBytesDeferred > 0 && flushableRequestBytes != 0) { - final int encodeBytesBuffered = encodeSlotLimit - encodeSlotOffset + flushableRecordHeadersBytes; - final int encodeRequestBytesBuffered = Math.max(flushableRequestBytes - encodeableRecordBytesDeferred - - Math.max(flushableRecordHeadersBytes, 1), 0); + final int encodeBytesBuffered = encodeSlotLimit - encodeSlotOffset; + final int encodeRequestBytesBuffered = + Math.max(flushableRequestBytes - encodeableRecordBytesDeferred - 1, 0); final int encodeNoAck = Math.max(encodeRequestBytesBuffered, encodeBytesBuffered); final int noAck = (int) (stream.initialSeq - stream.initialAck); stream.doAppWindow(traceId, noAck, noAck + encodeMaxBytes - encodeNoAck); @@ -2310,9 +2294,9 @@ private void onDecodeProduceResponse( { nextResponseId++; - final int encodeBytesBuffered = encodeSlotLimit - encodeSlotOffset + flushableRecordHeadersBytes; - final int encodeRequestBytesBuffered = Math.max(flushableRequestBytes - encodeableRecordBytesDeferred - - Math.max(flushableRecordHeadersBytes, 1), 0); + final int encodeBytesBuffered = encodeSlotLimit - encodeSlotOffset; + final int encodeRequestBytesBuffered = + Math.max(flushableRequestBytes - encodeableRecordBytesDeferred - 1, 0); final int encodeNoAck = Math.max(encodeRequestBytesBuffered, encodeBytesBuffered); stream.doAppWindow(traceId, encodeNoAck, encodeMaxBytes); diff --git a/runtime/binding-kafka/src/test/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/ClientProduceIT.java b/runtime/binding-kafka/src/test/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/ClientProduceIT.java index 3d71429543..79b37e51fd 100644 --- a/runtime/binding-kafka/src/test/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/ClientProduceIT.java +++ b/runtime/binding-kafka/src/test/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/ClientProduceIT.java @@ -203,6 +203,36 @@ public void shouldSendMessageValue() throws Exception k3po.finish(); } + @Test + @Configuration("client.when.topic.yaml") + @Specification({ + "${app}/message.empty.crc/client", + "${net}/message.empty.crc/server"}) + public void shouldSendMessageEmptyWithCrc() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("client.when.topic.yaml") + @Specification({ + "${app}/message.null.crc/client", + "${net}/message.null.crc/server"}) + public void shouldSendMessageNullWithCrc() throws Exception + { + k3po.finish(); + } + + @Test + @Configuration("client.when.topic.yaml") + @Specification({ + "${app}/messages.fragmented.crc/client", + "${net}/messages.fragmented.crc/server"}) + public void shouldSendFragmentedMessagesWithCrc() throws Exception + { + k3po.finish(); + } + @Test @Configuration("client.when.topic.yaml") @Specification({ @@ -327,6 +357,17 @@ public void shouldSendMessageValueRepeated() throws Exception k3po.finish(); } + @Test + @Configuration("client.when.topic.yaml") + @Specification({ + "${app}/message.value.repeated.fragmented/client", + "${net}/message.value.repeated/server"}) + @Configure(name = KafkaConfigurationTest.KAFKA_CLIENT_PRODUCE_MAX_REQUEST_MILLIS_NAME, value = "200") + public void shouldSendMessageValueRepeatedWhenFragmented() throws Exception + { + k3po.finish(); + } + @Test @Configuration("client.when.topic.yaml") @Specification({ diff --git a/runtime/binding-mqtt-kafka/pom.xml b/runtime/binding-mqtt-kafka/pom.xml index c1947c80f2..bd3382f031 100644 --- a/runtime/binding-mqtt-kafka/pom.xml +++ b/runtime/binding-mqtt-kafka/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-mqtt-kafka/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/kafka/internal/config/MqttKafkaConditionMatcher.java b/runtime/binding-mqtt-kafka/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/kafka/internal/config/MqttKafkaConditionMatcher.java index 7d1af3446c..70c0f01a24 100644 --- a/runtime/binding-mqtt-kafka/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/kafka/internal/config/MqttKafkaConditionMatcher.java +++ b/runtime/binding-mqtt-kafka/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/kafka/internal/config/MqttKafkaConditionMatcher.java @@ -14,7 +14,6 @@ */ package io.aklivity.zilla.runtime.binding.mqtt.kafka.internal.config; -import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import java.util.regex.Matcher; @@ -65,22 +64,6 @@ private boolean observeMatched() return true; } - private static List asTopicMatchers( - List wildcards) - { - final List matchers = new ArrayList<>(); - for (String wildcard : wildcards) - { - String patternBegin = wildcard.startsWith("/") ? "(" : "^(?!\\/)("; - String fixedPattern = patternBegin + asRegexPattern(wildcard, 0, true) + ")?\\/?\\#?"; - String nonFixedPattern = patternBegin + asRegexPattern(wildcard, 0, false) + ")?\\/?\\#"; - fixedPattern = fixedPattern.replaceAll("\\{([a-zA-Z_]+)\\}", "(?<$1>.+)"); - nonFixedPattern = nonFixedPattern.replaceAll("\\{([a-zA-Z_]+)\\}", ""); - matchers.add(Pattern.compile(nonFixedPattern + "|" + fixedPattern).matcher("")); - } - return matchers; - } - private static Matcher asTopicMatcher( List wildcards) { diff --git a/runtime/binding-mqtt-kafka/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/kafka/internal/stream/MqttKafkaPublishFactory.java b/runtime/binding-mqtt-kafka/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/kafka/internal/stream/MqttKafkaPublishFactory.java index dee573d4c3..5697efb2e4 100644 --- a/runtime/binding-mqtt-kafka/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/kafka/internal/stream/MqttKafkaPublishFactory.java +++ b/runtime/binding-mqtt-kafka/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/kafka/internal/stream/MqttKafkaPublishFactory.java @@ -610,7 +610,7 @@ private void onMqttData( .capabilities(c -> c.set(KafkaCapabilities.PRODUCE_ONLY)) .key(key))) .build(); - retained.doKafkaFlush(traceId, authorization, budgetId, kafkaFlushEx); + retained.doKafkaFlush(traceId, authorization, budgetId, reserved, kafkaFlushEx); } } @@ -1629,7 +1629,7 @@ else if (delegate.qos < MqttQoS.EXACTLY_ONCE.value()) .typeId(kafkaTypeId) .merged(m -> m.produce(p -> p.hashKey(hashKey))) .build(); - doKafkaFlush(traceId, authorization, 0, kafkaFlushEx); + doKafkaFlush(traceId, authorization, 0, 0, kafkaFlushEx); } } @@ -1674,12 +1674,13 @@ private void doKafkaFlush( long traceId, long authorization, long budgetId, + int reserved, KafkaFlushExFW extension) { doFlush(kafka, originId, routedId, initialId, initialSeq, initialAck, initialMax, - traceId, authorization, budgetId, initialPad, extension); + traceId, authorization, budgetId, reserved, extension); - initialSeq += initialPad; + initialSeq += reserved; assert initialSeq <= initialAck + initialMax; } diff --git a/runtime/binding-mqtt/pom.xml b/runtime/binding-mqtt/pom.xml index 7520bea62e..5d79b9fa8c 100644 --- a/runtime/binding-mqtt/pom.xml +++ b/runtime/binding-mqtt/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttClientFactory.java b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttClientFactory.java index d979b67d0b..8a1af94e87 100644 --- a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttClientFactory.java +++ b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttClientFactory.java @@ -944,7 +944,6 @@ private int decodePublish( int progress = offset; - decode: if (length >= client.decodeablePacketBytes) { int reasonCode = SUCCESS; @@ -1051,7 +1050,7 @@ private int decodePublishPayload( if (canPublish && subscriber.debitorIndex != NO_DEBITOR_INDEX && reserved != 0) { final int minimum = reserved; // TODO: fragmentation - reserved = subscriber.debitor.claim(subscriber.debitorIndex, subscriber.replyId, minimum, reserved); + reserved = subscriber.debitor.claim(traceId, subscriber.debitorIndex, subscriber.replyId, minimum, reserved, 0); } if (canPublish && (reserved != 0 || payloadSize == 0)) diff --git a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttServerFactory.java b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttServerFactory.java index 6e012eef4b..3e728870fc 100644 --- a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttServerFactory.java +++ b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttServerFactory.java @@ -1326,7 +1326,7 @@ private int decodePublishV4( // special case, when payload is empty -> wait for window break decode; } - server.publishPayloadBytes = decodeablePublishPayloadBytes; + server.decodeablePublishPayloadBytes = decodeablePublishPayloadBytes; server.decodeablePacketBytes = limit - publishLimit; server.decoder = decodePublishPayload; progress = publishLimit; @@ -1462,7 +1462,7 @@ private int decodePublishV5( // special case, when payload is empty -> wait for window break decode; } - server.publishPayloadBytes = decodeablePublishPayloadBytes; + server.decodeablePublishPayloadBytes = decodeablePublishPayloadBytes; server.decodeablePacketBytes = limit - publishLimit; server.decoder = decodePublishPayload; progress = publishLimit; @@ -1492,30 +1492,32 @@ private int decodePublishPayload( int progress = offset; int reasonCode = SUCCESS; - decode: if (length >= 0) { MqttServer.MqttPublishStream publisher = server.publishes.get(server.decodePublisherKey); - int publishablePayloadSize = - Math.min(Math.min(server.publishPayloadBytes, publisher.initialBudget()), length); - - final OctetsFW payload = payloadRO.wrap(buffer, offset, offset + publishablePayloadSize); + int initialBudget = publisher.initialBudget(); + int lengthMax = Math.min(length, server.decodeablePublishPayloadBytes); + int reservedMax = Math.max(publisher.initialPad, Math.min(lengthMax + publisher.initialPad, initialBudget)); boolean canPublish = MqttState.initialOpened(publisher.state); - final int maximum = publishablePayloadSize; - final int minimum = Math.min(maximum, Math.max(publisher.initialMin, 1024)); + final int maximum = reservedMax; + final int minimum = Math.min(maximum, Math.max(publisher.initialMin, 1024) + publisher.initialPad); int valueClaimed = maximum; - if (canPublish && publisher.debitorIndex != NO_DEBITOR_INDEX && publishablePayloadSize != 0) + if (canPublish && publisher.debitorIndex != NO_DEBITOR_INDEX && lengthMax != 0) { valueClaimed = - publisher.debitor.claim(publisher.debitorIndex, publisher.initialId, minimum, maximum); + publisher.debitor.claim(traceId, publisher.debitorIndex, publisher.initialId, minimum, maximum, 0); } - if (canPublish && (valueClaimed != 0 || payload.sizeof() == 0)) + int sizeClaimed = valueClaimed - publisher.initialPad; + + final OctetsFW payload = payloadRO.wrap(buffer, offset, offset + sizeClaimed); + + if (canPublish && (sizeClaimed != 0 || payload.sizeof() == 0)) { if (server.publishPayloadDeferred == 0) { @@ -1526,12 +1528,12 @@ private int decodePublishPayload( server.onDecodePublishPayload(traceId, authorization, valueClaimed, server.decodedPacketId, server.decodedQos, server.decodedFlags, server.decodedExpiryInterval, server.decodedContentType, server.decodedPayloadFormat, server.decodedResponseTopic, server.decodedCorrelationData, server.decodedUserProperties, - payload, payload.offset(), payload.offset() + valueClaimed, publisher.contentType); + payload, payload.offset(), payload.offset() + sizeClaimed, publisher.contentType); - progress = payload.offset() + valueClaimed; + progress = payload.offset() + sizeClaimed; - if (server.publishPayloadBytes == 0) + if (server.decodeablePublishPayloadBytes == 0) { server.decoder = decodePacketTypeByVersion.get(server.version); } @@ -2448,7 +2450,7 @@ private final class MqttServer private long decodePublisherKey; private int decodeablePacketBytes; private int publishPayloadDeferred; - public int publishPayloadBytes; + public int decodeablePublishPayloadBytes; private int willPayloadDeferred; public int willPayloadBytes; @@ -2949,7 +2951,7 @@ else if (this.authField.equals(MqttConnectProperty.PASSWORD)) this.sessionId = sessionAuth; - this.session = new MqttSessionStream(originId, resolved.id, 0); + this.session = new MqttSessionStream(routedId, resolved.id, 0); final int capabilities = versions.contains(MqttVersion.V_5) && versions.size() == 1 ? REDIRECT_MASK : 0; @@ -3080,79 +3082,78 @@ private int onDecodeConnectWillPayload( int limit) { int progress = offset; - decode: - { - final int willFlags = decodeWillFlags(connectFlags); - final int willQos = decodeWillQos(connectFlags); - final boolean willFlagSet = isSetWillFlag(connectFlags); - if (willFlagSet && MqttState.initialOpened(session.state)) - { - int publishedWillSize = 0; - if (willPayloadDeferred == 0) + final int willFlags = decodeWillFlags(connectFlags); + final int willQos = decodeWillQos(connectFlags); + final boolean willFlagSet = isSetWillFlag(connectFlags); + + if (willFlagSet && MqttState.initialOpened(session.state)) + { + int publishedWillSize = 0; + if (willPayloadDeferred == 0) + { + final MqttWillMessageFW.Builder willMessageBuilder = + mqttWillMessageRW.wrap(willMessageBuffer, 0, willMessageBuffer.capacity()) + .topic(mqttConnectPayloadRO.willTopic) + .delay(mqttConnectPayloadRO.willDelay) + .qos(willQos) + .flags(willFlags) + .expiryInterval(mqttConnectPayloadRO.expiryInterval) + .contentType(mqttConnectPayloadRO.contentType) + .format(f -> f.set(mqttConnectPayloadRO.payloadFormat)) + .responseTopic(mqttConnectPayloadRO.responseTopic) + .correlation(c -> c.bytes(mqttConnectPayloadRO.correlationData)) + .payloadSize(mqttConnectPayloadRO.payloadSize); + + if (version == 5) { - final MqttWillMessageFW.Builder willMessageBuilder = - mqttWillMessageRW.wrap(willMessageBuffer, 0, willMessageBuffer.capacity()) - .topic(mqttConnectPayloadRO.willTopic) - .delay(mqttConnectPayloadRO.willDelay) - .qos(willQos) - .flags(willFlags) - .expiryInterval(mqttConnectPayloadRO.expiryInterval) - .contentType(mqttConnectPayloadRO.contentType) - .format(f -> f.set(mqttConnectPayloadRO.payloadFormat)) - .responseTopic(mqttConnectPayloadRO.responseTopic) - .correlation(c -> c.bytes(mqttConnectPayloadRO.correlationData)) - .payloadSize(mqttConnectPayloadRO.payloadSize); - - if (version == 5) - { - final Array32FW userProperties = willUserPropertiesRW.build(); - userProperties.forEach( - c -> willMessageBuilder.propertiesItem(p -> p.key(c.key()).value(c.value()))); - } - - final MqttWillMessageFW will = willMessageBuilder.build(); - final int headerSize = willMessageBuilder.sizeof(); - int payloadSize = Math.min(limit - offset, session.initialBudget() - headerSize); + final Array32FW userProperties = willUserPropertiesRW.build(); + userProperties.forEach( + c -> willMessageBuilder.propertiesItem(p -> p.key(c.key()).value(c.value()))); + } - final OctetsFW payload = payloadRO.wrap(buffer, offset, offset + payloadSize); + final MqttWillMessageFW will = willMessageBuilder.build(); + final int headerSize = willMessageBuilder.sizeof(); + int payloadSize = Math.min(limit - offset, session.initialBudget() - headerSize); - willMessageBuffer.putBytes(will.limit(), payload.buffer(), payload.offset(), payload.limit()); + final OctetsFW payload = payloadRO.wrap(buffer, offset, offset + payloadSize); - int flags = willPayloadBytes + headerSize > session.initialBudget() ? FLAG_INIT : FLAG_INIT | FLAG_FIN; - int deferred = Math.max(willPayloadBytes + headerSize - session.initialBudget(), 0); - willPayloadDeferred = deferred; + willMessageBuffer.putBytes(will.limit(), payload.buffer(), payload.offset(), payload.limit()); - final MqttDataExFW.Builder sessionDataExBuilder = - mqttSessionDataExRW.wrap(sessionExtBuffer, 0, sessionExtBuffer.capacity()) - .typeId(mqttTypeId) - .session(s -> s.deferred(deferred).kind(k -> k.set(MqttSessionDataKind.WILL))); + int flags = willPayloadBytes + headerSize > session.initialBudget() ? FLAG_INIT : FLAG_INIT | FLAG_FIN; + int deferred = Math.max(willPayloadBytes + headerSize - session.initialBudget(), 0); + willPayloadDeferred = deferred; - publishedWillSize = session.doSessionData(traceId, flags, - willMessageBuffer, 0, headerSize + payload.sizeof(), headerSize, sessionDataExBuilder.build()); + final MqttDataExFW.Builder sessionDataExBuilder = + mqttSessionDataExRW.wrap(sessionExtBuffer, 0, sessionExtBuffer.capacity()) + .typeId(mqttTypeId) + .session(s -> s.deferred(deferred).kind(k -> k.set(MqttSessionDataKind.WILL))); - if (publishedWillSize < headerSize) - { - willPayloadDeferred = 0; - } + publishedWillSize = session.doSessionData(traceId, flags, + willMessageBuffer, 0, headerSize + payload.sizeof(), headerSize, sessionDataExBuilder.build()); - willPayloadBytes -= payloadSize; - progress += payloadSize; - } - else + if (publishedWillSize < headerSize) { - final OctetsFW payload = payloadRO.wrap(buffer, offset, limit); - assert willPayloadDeferred >= 0; - int flags = willPayloadDeferred - payload.sizeof() > 0 ? FLAG_CONT : FLAG_FIN; - - publishedWillSize = session.doSessionData(traceId, flags, - payload.buffer(), offset, limit, 0, EMPTY_OCTETS); - willPayloadDeferred -= publishedWillSize; - willPayloadBytes -= publishedWillSize; - progress += publishedWillSize; + willPayloadDeferred = 0; } + + willPayloadBytes -= payloadSize; + progress += payloadSize; + } + else + { + final OctetsFW payload = payloadRO.wrap(buffer, offset, limit); + assert willPayloadDeferred >= 0; + int flags = willPayloadDeferred - payload.sizeof() > 0 ? FLAG_CONT : FLAG_FIN; + + publishedWillSize = session.doSessionData(traceId, flags, + payload.buffer(), offset, limit, 0, EMPTY_OCTETS); + willPayloadDeferred -= publishedWillSize; + willPayloadBytes -= publishedWillSize; + progress += publishedWillSize; } } + return progress; } @@ -3268,7 +3269,7 @@ private void onDecodePublishPayload( if (publishPayloadDeferred == 0) { - publishPayloadDeferred = publishPayloadBytes - length; + publishPayloadDeferred = decodeablePublishPayloadBytes - length; final Flyweight dataEx = mqttPublishDataExRW.wrap(dataExtBuffer, 0, dataExtBuffer.capacity()) .typeId(mqttTypeId) .publish(p -> @@ -3294,7 +3295,7 @@ private void onDecodePublishPayload( { stream.doPublishData(traceId, authorization, reserved, packetId, payload, dataFlags, offset, limit, dataEx); - publishPayloadBytes -= length; + decodeablePublishPayloadBytes -= length; } } else @@ -3307,13 +3308,13 @@ private void onDecodePublishPayload( { stream.doPublishData(traceId, authorization, reserved, packetId, payload, dataFlags, offset, limit, EMPTY_OCTETS); - publishPayloadBytes -= length; + decodeablePublishPayloadBytes -= length; } } } else { - publishPayloadBytes -= length; + decodeablePublishPayloadBytes -= length; } } } @@ -6011,7 +6012,7 @@ private void onPublishExpiredSignal( final long traceId = signal.traceId(); final long now = System.currentTimeMillis(); - if (now >= publishExpiresAt && publishPayloadBytes == 0) + if (now >= publishExpiresAt && decodeablePublishPayloadBytes == 0) { doPublishAppEnd(traceId); } @@ -6133,7 +6134,7 @@ private void cleanupAbort( private int initialBudget() { - return initialMax - (int)(initialSeq - initialAck) - initialPad; + return initialMax - (int)(initialSeq - initialAck); } } diff --git a/runtime/binding-openapi-asyncapi/pom.xml b/runtime/binding-openapi-asyncapi/pom.xml index 200845e8bd..daf70d5f85 100644 --- a/runtime/binding-openapi-asyncapi/pom.xml +++ b/runtime/binding-openapi-asyncapi/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml @@ -44,37 +44,30 @@ io.aklivity.zilla binding-openapi - ${project.version} io.aklivity.zilla binding-asyncapi - ${project.version} io.aklivity.zilla binding-http-kafka - ${project.version} io.aklivity.zilla binding-mqtt-kafka - ${project.version} io.aklivity.zilla binding-http - ${project.version} io.aklivity.zilla binding-mqtt - ${project.version} io.aklivity.zilla binding-kafka - ${project.version} ${project.groupId} diff --git a/runtime/binding-openapi-asyncapi/src/test/java/io/aklivity/zilla/runtime/binding/openapi/asyncapi/internal/config/OpenapiAsyncapiConditionConfigAdapterTest.java b/runtime/binding-openapi-asyncapi/src/test/java/io/aklivity/zilla/runtime/binding/openapi/asyncapi/internal/config/OpenapiAsyncapiConditionConfigAdapterTest.java index 3dc345e468..ede2be2eac 100644 --- a/runtime/binding-openapi-asyncapi/src/test/java/io/aklivity/zilla/runtime/binding/openapi/asyncapi/internal/config/OpenapiAsyncapiConditionConfigAdapterTest.java +++ b/runtime/binding-openapi-asyncapi/src/test/java/io/aklivity/zilla/runtime/binding/openapi/asyncapi/internal/config/OpenapiAsyncapiConditionConfigAdapterTest.java @@ -14,10 +14,10 @@ */ package io.aklivity.zilla.runtime.binding.openapi.asyncapi.internal.config; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; diff --git a/runtime/binding-openapi/pom.xml b/runtime/binding-openapi/pom.xml index 61a5d840b2..b0aa505914 100644 --- a/runtime/binding-openapi/pom.xml +++ b/runtime/binding-openapi/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml @@ -44,32 +44,26 @@ io.aklivity.zilla binding-http - ${project.version} io.aklivity.zilla binding-tcp - ${project.version} io.aklivity.zilla binding-tls - ${project.version} io.aklivity.zilla catalog-inline - ${project.version} io.aklivity.zilla model-core - ${project.version} io.aklivity.zilla model-json - ${project.version} ${project.groupId} diff --git a/runtime/binding-proxy/pom.xml b/runtime/binding-proxy/pom.xml index 6d59876b7d..539c7bc1a9 100644 --- a/runtime/binding-proxy/pom.xml +++ b/runtime/binding-proxy/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-sse-kafka/pom.xml b/runtime/binding-sse-kafka/pom.xml index 44bec20351..d3141f3dc4 100644 --- a/runtime/binding-sse-kafka/pom.xml +++ b/runtime/binding-sse-kafka/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-sse/pom.xml b/runtime/binding-sse/pom.xml index d2bcef0790..933cd8ff33 100644 --- a/runtime/binding-sse/pom.xml +++ b/runtime/binding-sse/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-tcp/pom.xml b/runtime/binding-tcp/pom.xml index bfd883d530..c5a3b8bb7c 100644 --- a/runtime/binding-tcp/pom.xml +++ b/runtime/binding-tcp/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/stream/TcpClientRouter.java b/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/stream/TcpClientRouter.java index 41ef1b2469..86feb20b3e 100644 --- a/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/stream/TcpClientRouter.java +++ b/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/stream/TcpClientRouter.java @@ -306,6 +306,8 @@ private InetSocketAddress resolveInetSocketAddress( destinationInet6.buffer().getBytes(destinationInet6.offset(), ipv6); resolved = new InetSocketAddress(InetAddress.getByAddress(ipv6), destinationPortInet6); break; + default: + break; } } catch (UnknownHostException e) @@ -318,6 +320,8 @@ private InetSocketAddress resolveInetSocketAddress( private static final class TcpDnsFailedException extends RuntimeException { + private static final long serialVersionUID = 1L; + private final String hostname; TcpDnsFailedException( diff --git a/runtime/binding-tls/pom.xml b/runtime/binding-tls/pom.xml index bf05af4943..157ad6acb1 100644 --- a/runtime/binding-tls/pom.xml +++ b/runtime/binding-tls/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml @@ -47,18 +47,6 @@ ${project.version} test - - ${project.groupId} - vault-filesystem - ${project.version} - test - - - ${project.groupId} - binding-echo - ${project.version} - test - junit junit diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsConfiguration.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsConfiguration.java index c88108b9de..a1c4f736a7 100644 --- a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsConfiguration.java +++ b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsConfiguration.java @@ -17,18 +17,12 @@ import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_VERBOSE; -import java.security.KeyStore; - import io.aklivity.zilla.runtime.engine.Configuration; public class TlsConfiguration extends Configuration { public static final IntPropertyDef TLS_HANDSHAKE_WINDOW_BYTES; public static final IntPropertyDef TLS_HANDSHAKE_TIMEOUT; - public static final PropertyDef TLS_KEY_MANAGER_ALGORITHM; - public static final PropertyDef TLS_CACERTS_STORE_TYPE; - public static final PropertyDef TLS_CACERTS_STORE; - public static final PropertyDef TLS_CACERTS_STORE_PASS; public static final BooleanPropertyDef TLS_IGNORE_EMPTY_VAULT_REFS; public static final LongPropertyDef TLS_AWAIT_SYNC_CLOSE_MILLIS; public static final BooleanPropertyDef TLS_PROACTIVE_CLIENT_REPLY_BEGIN; @@ -41,10 +35,6 @@ public class TlsConfiguration extends Configuration final ConfigurationDef config = new ConfigurationDef("zilla.binding.tls"); TLS_HANDSHAKE_WINDOW_BYTES = config.property("handshake.window.bytes", 65536); TLS_HANDSHAKE_TIMEOUT = config.property("handshake.timeout", 10); - TLS_KEY_MANAGER_ALGORITHM = config.property("handshake.key.manager.algorithm", "PKIX"); - TLS_CACERTS_STORE_TYPE = config.property("cacerts.store.type", TlsConfiguration::cacertsStoreTypeDefault); - TLS_CACERTS_STORE = config.property("cacerts.store", TlsConfiguration::cacertsStoreDefault); - TLS_CACERTS_STORE_PASS = config.property("cacerts.store.pass"); TLS_IGNORE_EMPTY_VAULT_REFS = config.property("ignore.empty.vault.refs", false); TLS_AWAIT_SYNC_CLOSE_MILLIS = config.property("await.sync.close.millis", 3000L); TLS_PROACTIVE_CLIENT_REPLY_BEGIN = config.property("proactive.client.reply.begin", false); @@ -68,26 +58,6 @@ public int handshakeTimeout() return TLS_HANDSHAKE_TIMEOUT.getAsInt(this); } - public String keyManagerAlgorithm() - { - return TLS_KEY_MANAGER_ALGORITHM.get(this); - } - - public String cacertsStoreType() - { - return TLS_CACERTS_STORE_TYPE.get(this); - } - - public String cacertsStore() - { - return TLS_CACERTS_STORE.get(this); - } - - public String cacertsStorePass() - { - return TLS_CACERTS_STORE_PASS.get(this); - } - public boolean ignoreEmptyVaultRefs() { return TLS_IGNORE_EMPTY_VAULT_REFS.getAsBoolean(this); @@ -108,18 +78,6 @@ public boolean verbose() return TLS_VERBOSE.getAsBoolean(this); } - private static String cacertsStoreTypeDefault( - Configuration config) - { - return System.getProperty("javax.net.ssl.trustStoreType", KeyStore.getDefaultType()); - } - - private static String cacertsStoreDefault( - Configuration config) - { - return System.getProperty("javax.net.ssl.trustStore"); - } - private static boolean verboseDefault( Configuration config) { diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventContext.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventContext.java index 385df6c450..1ed0cdb060 100644 --- a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventContext.java +++ b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventContext.java @@ -18,11 +18,8 @@ import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_FAILED; import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_HANDSHAKE_FAILED; import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_KEY_REJECTED; -import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_KEY_VERIFICATION_FAILED; import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_PEER_NOT_VERIFIED; import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_PROTOCOL_REJECTED; -import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsKeyFailureType.TLS_KEY_INVALID; -import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsKeyFailureType.TLS_KEY_MISSING; import java.nio.ByteBuffer; import java.time.Clock; @@ -32,7 +29,6 @@ import io.aklivity.zilla.runtime.binding.tls.internal.types.event.EventFW; import io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventExFW; -import io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsKeyFailureType; import io.aklivity.zilla.runtime.engine.EngineContext; import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer; @@ -50,7 +46,6 @@ public class TlsEventContext private final int tlsKeyRejectedEventId; private final int tlsPeerNotVerifiedEventId; private final int tlsHandshakeFailedEventId; - private final int tlsKeyPairVerificationFailedEventId; private final MessageConsumer eventWriter; private final Clock clock; @@ -63,7 +58,6 @@ public TlsEventContext( this.tlsKeyRejectedEventId = context.supplyEventId("binding.tls.key.rejected"); this.tlsPeerNotVerifiedEventId = context.supplyEventId("binding.tls.peer.not.verified"); this.tlsHandshakeFailedEventId = context.supplyEventId("binding.tls.handshake.failed"); - this.tlsKeyPairVerificationFailedEventId = context.supplyEventId("binding.tls.key.pair.verification.failed"); this.eventWriter = context.supplyEventWriter(); this.clock = context.clock(); } @@ -172,42 +166,4 @@ public void tlsHandshakeFailed( .build(); eventWriter.accept(tlsTypeId, event.buffer(), event.offset(), event.limit()); } - - public void tlsKeyPairMissing( - long bindingId, - String keyName) - { - tlsKeyPairVerificationFailed(TLS_KEY_MISSING, bindingId, keyName); - } - - public void tlsKeyPairInvalid( - long bindingId, - String keyName) - { - tlsKeyPairVerificationFailed(TLS_KEY_INVALID, bindingId, keyName); - } - - private void tlsKeyPairVerificationFailed( - TlsKeyFailureType failureType, - long bindingId, - String keyName) - { - TlsEventExFW extension = tlsEventExRW - .wrap(extensionBuffer, 0, extensionBuffer.capacity()) - .tlsKeyVerificationFailed(e -> e - .typeId(TLS_KEY_VERIFICATION_FAILED.value()) - .failureType(t -> t.set(failureType)) - .keyName(keyName) - ) - .build(); - EventFW event = eventRW - .wrap(eventBuffer, 0, eventBuffer.capacity()) - .id(tlsKeyPairVerificationFailedEventId) - .timestamp(clock.millis()) - .traceId(0L) - .namespacedId(bindingId) - .extension(extension.buffer(), extension.offset(), extension.limit()) - .build(); - eventWriter.accept(tlsTypeId, event.buffer(), event.offset(), event.limit()); - } } diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatter.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatter.java index 10dbd107b7..992946d7f6 100644 --- a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatter.java +++ b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatter.java @@ -19,7 +19,6 @@ import io.aklivity.zilla.runtime.binding.tls.internal.types.event.EventFW; import io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventExFW; -import io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsKeyVerificationFailedExFW; import io.aklivity.zilla.runtime.engine.Configuration; import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi; @@ -69,16 +68,6 @@ public String format( result = "The client and server could not negotiate the desired level of security."; break; } - case TLS_KEY_VERIFICATION_FAILED: - { - TlsKeyVerificationFailedExFW ex = extension.tlsKeyVerificationFailed(); - result = switch (ex.failureType().get()) - { - case TLS_KEY_MISSING -> String.format("Key (%s) is missing.", ex.keyName()); - case TLS_KEY_INVALID -> String.format("Key (%s) is invalid.", ex.keyName()); - }; - break; - } } return result; } diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsBindingConfig.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsBindingConfig.java index 2fafaa55b3..a2bca55814 100644 --- a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsBindingConfig.java +++ b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsBindingConfig.java @@ -25,10 +25,7 @@ import static javax.net.ssl.StandardConstants.SNI_HOST_NAME; import java.security.KeyStore; -import java.security.KeyStore.TrustedCertificateEntry; import java.security.SecureRandom; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -45,7 +42,6 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509ExtendedKeyManager; -import javax.security.auth.x500.X500Principal; import org.agrona.LangUtil; @@ -60,12 +56,11 @@ import io.aklivity.zilla.runtime.binding.tls.internal.types.stream.ProxyBeginExFW; import io.aklivity.zilla.runtime.engine.config.BindingConfig; import io.aklivity.zilla.runtime.engine.config.KindConfig; +import io.aklivity.zilla.runtime.engine.security.Trusted; import io.aklivity.zilla.runtime.engine.vault.VaultHandler; public final class TlsBindingConfig { - private static final String TYPE_DEFAULT = "PKCS12"; - private static final TlsOptionsConfig OPTIONS_DEFAULT = TlsOptionsConfig.builder().build(); public final long id; @@ -94,20 +89,15 @@ public void init( VaultHandler vault, SecureRandom random) { - TlsKeyPairVerifier verifier = new TlsKeyPairVerifier(); - char[] keysPass = "generated".toCharArray(); - KeyStore keys = newKeys(config, vault, keysPass, verifier, events, options.keys, options.signers); - KeyStore trust = newTrust(config, vault, options.trust, options.trustcacerts && kind == KindConfig.CLIENT); + KeyManagerFactory keys = newKeys(config, vault, options.keys, options.signers); + TrustManagerFactory trust = newTrust(config, vault, options.trust, options.trustcacerts && kind == KindConfig.CLIENT); try { KeyManager[] keyManagers = null; if (keys != null) { - String keyManagerAlgorithm = config.keyManagerAlgorithm(); - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgorithm); - keyManagerFactory.init(keys, keysPass); - keyManagers = keyManagerFactory.getKeyManagers(); + keyManagers = keys.getKeyManagers(); if (keyManagers != null && kind == KindConfig.CLIENT) { @@ -125,10 +115,7 @@ public void init( TrustManager[] trustManagers = null; if (trust != null) { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( - TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(trust); - trustManagers = trustManagerFactory.getTrustManagers(); + trustManagers = trust.getTrustManagers(); } String version = options.version != null ? options.version : "TLS"; @@ -406,16 +393,13 @@ private String selectAlpn( return selected; } - private KeyStore newKeys( + private KeyManagerFactory newKeys( TlsConfiguration config, VaultHandler vault, - char[] password, - TlsKeyPairVerifier verifier, - TlsEventContext events, List keyNames, List signerNames) { - KeyStore store = null; + KeyManagerFactory keys = null; keys: try @@ -425,64 +409,23 @@ private KeyStore newKeys( break keys; } - if (config.ignoreEmptyVaultRefs()) - { - keyNames = ignoreEmptyNames(keyNames); - signerNames = ignoreEmptyNames(signerNames); - } - - if (keyNames != null || signerNames != null) - { - store = KeyStore.getInstance(TYPE_DEFAULT); - store.load(null, password); - } - if (keyNames != null) { - assert store != null; - - for (String keyName : keyNames) + if (config.ignoreEmptyVaultRefs()) { - KeyStore.PrivateKeyEntry entry = vault.key(keyName); - if (entry == null) - { - events.tlsKeyPairMissing(this.id, keyName); - continue; - } - boolean valid = verifier.verify(entry); - if (!valid) - { - events.tlsKeyPairInvalid(this.id, keyName); - continue; - } - KeyStore.ProtectionParameter protection = new KeyStore.PasswordProtection(password); - store.setEntry(keyName, entry, protection); + keyNames = ignoreEmptyNames(keyNames); } - } - if (signerNames != null) + keys = vault.initKeys(keyNames); + } + else if (signerNames != null) { - assert store != null; - - for (String signerName : signerNames) + if (config.ignoreEmptyVaultRefs()) { - KeyStore.PrivateKeyEntry[] entries = vault.keys(signerName); - if (entries != null) - { - for (KeyStore.PrivateKeyEntry entry : entries) - { - KeyStore.ProtectionParameter protection = new KeyStore.PasswordProtection(password); - Certificate certificate = entry.getCertificate(); - if (certificate instanceof X509Certificate) - { - X509Certificate x509 = (X509Certificate) certificate; - X500Principal x500 = x509.getSubjectX500Principal(); - String alias = String.format("%s %d", x500.getName(), x509.getSerialNumber()); - store.setEntry(alias, entry, protection); - } - } - } + signerNames = ignoreEmptyNames(signerNames); } + + keys = vault.initSigners(signerNames); } } catch (Exception ex) @@ -490,16 +433,16 @@ private KeyStore newKeys( LangUtil.rethrowUnchecked(ex); } - return store; + return keys; } - private KeyStore newTrust( + private TrustManagerFactory newTrust( TlsConfiguration config, VaultHandler vault, List trustNames, boolean trustcacerts) { - KeyStore store = null; + TrustManagerFactory trust = null; try { @@ -508,34 +451,17 @@ private KeyStore newTrust( trustNames = ignoreEmptyNames(trustNames); } - if (trustNames != null || trustcacerts) - { - store = KeyStore.getInstance(TYPE_DEFAULT); - store.load(null, null); - } + KeyStore cacerts = trustcacerts ? Trusted.cacerts(config) : null; - if (vault != null && trustNames != null) + if (vault != null) { - for (String trustName : trustNames) - { - KeyStore.TrustedCertificateEntry entry = vault.certificate(trustName); - - store.setEntry(trustName, entry, null); - } + trust = vault.initTrust(trustNames, cacerts); } - - if (trustcacerts) + else if (cacerts != null) { - TrustedCertificateEntry[] cacerts = TlsTrust.cacerts(config); - - for (TrustedCertificateEntry cacert : cacerts) - { - X509Certificate trusted = (X509Certificate) cacert.getTrustedCertificate(); - X500Principal subject = trusted.getSubjectX500Principal(); - String name = subject.getName(); - - store.setCertificateEntry(name, trusted); - } + TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + factory.init(cacerts); + trust = factory; } } catch (Exception ex) @@ -543,7 +469,7 @@ private KeyStore newTrust( LangUtil.rethrowUnchecked(ex); } - return store; + return trust; } private List ignoreEmptyNames( diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsKeyPairVerifier.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsKeyPairVerifier.java deleted file mode 100644 index 03a800810c..0000000000 --- a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsKeyPairVerifier.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2021-2023 Aklivity Inc. - * - * Aklivity licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.aklivity.zilla.runtime.binding.tls.internal.config; - -import static org.agrona.LangUtil.rethrowUnchecked; - -import java.security.InvalidKeyException; -import java.security.KeyStore; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.SignatureException; -import java.util.concurrent.ThreadLocalRandom; - -public class TlsKeyPairVerifier -{ - private static final String ALGORITHM = "SHA256withRSA"; - - public boolean verify( - KeyStore.PrivateKeyEntry entry) - { - boolean valid = false; - try - { - PrivateKey privateKey = entry.getPrivateKey(); - PublicKey publicKey = entry.getCertificate().getPublicKey(); - - // create a challenge - byte[] challenge = new byte[10000]; - ThreadLocalRandom.current().nextBytes(challenge); - - // sign using the private key - Signature sig = Signature.getInstance(ALGORITHM); - sig.initSign(privateKey); - sig.update(challenge); - byte[] signature = sig.sign(); - - // verify signature using the public key - sig.initVerify(publicKey); - sig.update(challenge); - valid = sig.verify(signature); - } - catch (InvalidKeyException | SignatureException ex) - { - // key invalid - } - catch (NoSuchAlgorithmException ex) - { - rethrowUnchecked(ex); - } - return valid; - } -} diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsTrust.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsTrust.java deleted file mode 100644 index 0528234984..0000000000 --- a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsTrust.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2021-2023 Aklivity Inc. - * - * Aklivity licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.aklivity.zilla.runtime.binding.tls.internal.config; - -import static java.util.Collections.list; - -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStore.TrustedCertificateEntry; -import java.util.LinkedList; -import java.util.List; - -import io.aklivity.zilla.runtime.binding.tls.internal.TlsConfiguration; - -public final class TlsTrust -{ - private TlsTrust() - { - } - - public static TrustedCertificateEntry[] cacerts( - TlsConfiguration config) - { - String storeType = config.cacertsStoreType(); - String store = config.cacertsStore(); - String storePass = config.cacertsStorePass(); - - TrustedCertificateEntry[] certificates = null; - - if (store == null || !Files.exists(Paths.get(store))) - { - String home = System.getProperty("java.home"); - - store = String.format("%s/lib/security/jssecacerts", home); - - if (!Files.exists(Paths.get(store))) - { - store = String.format("%s/lib/security/cacerts", home); - - if (!Files.exists(Paths.get(store))) - { - store = null; - } - } - } - - if (store != null) - { - try - { - KeyStore cacerts = KeyStore.getInstance(storeType); - cacerts.load(new FileInputStream(store), storePass != null ? storePass.toCharArray() : null); - - List trusted = new LinkedList<>(); - for (String alias : list(cacerts.aliases())) - { - if (cacerts.isCertificateEntry(alias)) - { - TrustedCertificateEntry entry = (TrustedCertificateEntry) cacerts.getEntry(alias, null); - trusted.add(entry); - } - } - - certificates = trusted.toArray(TrustedCertificateEntry[]::new); - } - catch (GeneralSecurityException | IOException ex) - { - // unable to load - } - } - - return certificates; - } -} diff --git a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsConfigurationTest.java b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsConfigurationTest.java index deaa584caf..ed6647312d 100644 --- a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsConfigurationTest.java +++ b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsConfigurationTest.java @@ -15,9 +15,6 @@ */ package io.aklivity.zilla.runtime.binding.tls.internal; -import static io.aklivity.zilla.runtime.binding.tls.internal.TlsConfiguration.TLS_CACERTS_STORE; -import static io.aklivity.zilla.runtime.binding.tls.internal.TlsConfiguration.TLS_CACERTS_STORE_PASS; -import static io.aklivity.zilla.runtime.binding.tls.internal.TlsConfiguration.TLS_CACERTS_STORE_TYPE; import static io.aklivity.zilla.runtime.binding.tls.internal.TlsConfiguration.TLS_HANDSHAKE_TIMEOUT; import static io.aklivity.zilla.runtime.binding.tls.internal.TlsConfiguration.TLS_HANDSHAKE_WINDOW_BYTES; import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_TASK_PARALLELISM; @@ -27,9 +24,6 @@ public class TlsConfigurationTest { - public static final String TLS_CACERTS_STORE_TYPE_NAME = "zilla.binding.tls.cacerts.store.type"; - public static final String TLS_CACERTS_STORE_NAME = "zilla.binding.tls.cacerts.store"; - public static final String TLS_CACERTS_STORE_PASS_NAME = "zilla.binding.tls.cacerts.store.pass"; public static final String TLS_HANDSHAKE_WINDOW_BYTES_NAME = "zilla.binding.tls.handshake.window.bytes"; public static final String TLS_HANDSHAKE_TIMEOUT_NAME = "zilla.binding.tls.handshake.timeout"; public static final String ENGINE_TASK_PARALLELISM_NAME = "zilla.engine.task.parallelism"; @@ -37,9 +31,6 @@ public class TlsConfigurationTest @Test public void shouldVerifyConstants() throws Exception { - assertEquals(TLS_CACERTS_STORE_TYPE.name(), TLS_CACERTS_STORE_TYPE_NAME); - assertEquals(TLS_CACERTS_STORE.name(), TLS_CACERTS_STORE_NAME); - assertEquals(TLS_CACERTS_STORE_PASS.name(), TLS_CACERTS_STORE_PASS_NAME); assertEquals(TLS_HANDSHAKE_WINDOW_BYTES.name(), TLS_HANDSHAKE_WINDOW_BYTES_NAME); assertEquals(TLS_HANDSHAKE_TIMEOUT.name(), TLS_HANDSHAKE_TIMEOUT_NAME); assertEquals(ENGINE_TASK_PARALLELISM.name(), ENGINE_TASK_PARALLELISM_NAME); diff --git a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/bench/TlsHandshakeBM.java b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/bench/TlsHandshakeBM.java index a1bcf842db..80f1880cb0 100644 --- a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/bench/TlsHandshakeBM.java +++ b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/bench/TlsHandshakeBM.java @@ -51,7 +51,7 @@ import io.aklivity.zilla.runtime.engine.binding.BindingHandler; import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer; import io.aklivity.zilla.runtime.engine.config.NamespaceConfig; -import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfig; +import io.aklivity.zilla.runtime.engine.test.internal.vault.config.TestVaultOptionsConfig; @State(Scope.Benchmark) @BenchmarkMode(Mode.Throughput) @@ -84,17 +84,148 @@ public void init() .vault() .name("server") .type("filesystem") - .options(FileSystemOptionsConfig.builder() - .keys() - .store("stores/server/keys") - .type("pkcs12") - .password("generated") - .build() - .trust() - .store("stores/client/trust") - .type("pkcs12") - .password("generated") - .build() + .options(TestVaultOptionsConfig.builder() + .key("localhost", + """ + -----BEGIN PRIVATE KEY----- + MIIJRQIBADANBgkqhkiG9w0BAQEFAASCCS8wggkrAgEAAoICAQDPk6zIt8JoQLQQ + AIYYws3lJAq6tBjPFTuuqgvly/EelozPzW4ycbpXXrpGSe3EU7tBBcGuv81gO3UX + VlYGQQroY1kXB1khZM8YTBcCZMq0ByunmKRF6nGxhHPDu7qmQhreRDioodsxiN0I + PxCjgxBKTFniF3hFVG8btPB6WMr39oyHGon0RlMqV92ia8c+XFnTHWyqVc10KhSA + WNpeF7Boic1QF7oi5EWVz2bJbI1tOSeUz8C1OlUhb9r8/zFvacJSIdCwhOtuHHJu + 1pSdIiOYzMtJfXWkueN2hc46tZQ3ZoyD27u8GMkk1dA1tPH9ouZlS13UoxcinOuE + ffMiONrT2miAmeqGQwbyNENNcdyMec4+fWJyft01+zNf5w5ybZgpYy5N8H5tVjwi + cOq9Mx+atBxVimaRmj9wh0PofqLgpaxrXHk8ToiMAkoveIsdjFq/JXrV2RvVPaU4 + YeivwZiA9DTZ1USRPU3YA/zYTf+Dm/cBxEK9wMfygQoP8zaO3RWNFe4Ulpw883r5 + O4fyhxvVVIngUcoVXi2wfBanW3ErnvYZVJ9RuZHiFnB0jzBhMuj0yedgYnuopMzY + EjIfXtf5ep5k0pMPLQYCQ9Wp9ge9txbWy2V0wZJUFBX7yMFs1/gFG/hxxD4w40Uu + xcIDG+26LrY9HfOA7tEB+GA/LRZjkQIDAQABAoICAQDG+KMS8zHihMMU46umaHS8 + REQUmzV8qrm+vzkQWOETlPP87MnIiMM5pI+heJP1MN25gi8ZtrjCmbuvVw62h/pQ + r4piTKTfIaZxf94+aSb0UjtCN0qfyg6ZPoFJCdXsMElY7MPywNM/NBXLJchpM+SV + k4JE+oJK0ph+Un6AiERmU2p4xrOd9xsY54iHfBBMcnGXsAjNbdm2k+9657DJqKNs + UUsAjv3ZHD6nT1sTkH4wSCzstAfgr72Sg4nCIUvdo96ko81Kpt6VeacnH4Ds7iB5 + AzWJiD0QXS7wGWqJVCxyvlXKvwHBV3DXYixmjr+3hEKcrhWPEZXHk+sd4S0BjMYT + up7mj2GmVSTwL/XS7cCVk4QS4901P2xhnINrw40W40JWinFJ3mW2Z4oySTNsWy0N + hugHlw+O0fRFPlVwh9uu8fpLIJQAbO0XwnJ2y7G1dkvFzTEtAxHyVanfwvepwAHl + +pszn/LsvAcLO9ncWUvt2pGm4Zz3sAHDYHoTEUUFvJfF33m49Vdgl9SeHVcAIbXc + XOnaw8NLoxyR4Q+jtvlr1yFF8Kt3zrA02Bj9W2TIyWJdbwJLjfTK7X4l9Bzin1Ec + 17r4XCEsWSKQ9E19AmSriNoGLczhfDCr26BQDVLCwmnKmF86CWrL53PZ9iEXEEVA + yruQItpmIRsG4Fu5FKkNAQKCAQEA7Iom5vVMt0sibUYozumEQJ/FdG1vyIn5a3tj + ROqGExFy9fwAQi734a45VuooUw7ot9kaGaGrqy6l2a0EyxJNUnF90cuvfX/ZrFwk + /w9fWc0TSOFlEVCraSghmZ9TsGAg9NyhGQa1HNrq4XnR9LSWftyOWr6GGUJeufdn + qs/gpBBDtMVIAbusbtxuEAMtIfbuc3vvhP0HdTmeXAnUcgQCC+kPZTh/iE0YhCdZ + WKxRWoj5HhSMrWvmL/29G3/qN8eMzz0aZLjCweCi8lji69QIVyf90y0MAQ0e20EC + n+HX7gzdAvpS+K1I+lMYh9PivcYjiO3fVPMoHUCd6EiKiEy1GQKCAQEA4KeG3/Z9 + PzSgNWq0HZi62CM/ixFNxgxsPKFxK4zntOAIQIihPR8CpT3Z5UeD4SbP7f5Jep49 + 7y7zc5CaIb0+bNVSdoSIp/d6/0iNgXwhJEkP3JIpWbhlT/K1OF8V2ItvOFfBkMYl + WmHH+V1i00CQAthczmrdYMWCr38S+Pfbcz1ywNyLH1Unh4xo1USXADgpISfLapDH + AlUexIyJE3X8XurR0h7BIiAc8oyRfPVEtyASz/aDxLVrG9HpSWS8fsMcQWUKHGBa + KrK0sFi7Tc9OPCnLU6dnCT6cLM0qqGGLqqM8Cmmcz+HdhHAAt5XBn53HhERvM1og + VtlNosVEl5u5OQKCAQEAnx0roA8ARQgop2Mbjlws15/iHjiDil2txyxgEXrFJ8yE + DY4vylV373rYHWw0JfMQfqNu2DEVnngpnmyxnby5AK1RWq/uY7h9/2CYjm6T0H+P + 6mWcK/Kc64bQW1t+21U+thg30fLeIAPvHi9pGXflCH9qzwX8hL9No0EWniNp1FMQ + iGhw0KGjE4v6CZFpacCGlG6ZJ1diDevtZ7JBE1U43zQuZAOGXnSl+jfR9UEtFH6x + PRfLrdi4Ji5EaFw6fL0iLkHHIFvcvrhSRD2gn8yos6A2MTjLK2XdDNYFYvFz5DEI + 9rjW2WsPfTwqcywICWpgevqwUZ+jq1HNJvStI5Sd+QKCAQEAnAHaeNcMXQMnqlCi + KddxET1RGDr4/mqME4KtO2gLVCErudzn07EgPi34je8e1xED3irzTfJr4hiBuaQW + VQ29Nwjgzir1V2dWA8eXdO8FeNQ/7pWVn5ecy2spi68EVa9mmgLfCbGAKQa0Pygp + w7gXCdLEiBfQCi6+tS6St1AwFhP7B5FgD28sF0ZbWpbaIa3eagbfjO5jNOx1hFpv + qpMJocSB1t/CkPcqAwm40sTkZiMgzUhMcyLk8ZnQ3kXVXFYT3hnTbqc+ll4pejj0 + QXGPy9neOAaNV+8htz72u52ZxvK6dCSpX/dixGCfLt4Ras2/ystXSZrx0D3xWvKQ + 0pOyiQKCAQEAtGU0KDx5aC+zpf1Jd6xd9jPoKY9OBLIuwp1BL7Oio1d7JKrxleOt + zjtZrxZXFDdFDUeOCPy4xWv/zblbVIRhp93ruQX/j5bDZvWo85aozTf80t2+aZgr + 5msAz3/UBQ5GY0ASJreJlbuSfPn5s9fLBbHNgFg29cmqjxPKU8vUiHXNxcBbRhpU + Mp/Kplij+O6hKJeqECq5610CgqLg24vPLQKDsXtC2+ZAHvDJzShN8nu1FQnsqmsj + xuxpFoXU+KgeFwOIHD2SkB7w2kmvHQ2TUnvqbcWxcA6F2o0U9uEAAWYE7iq6V1hD + HiTCqXKPrP1QCU1/TXWVjEgnVnlruNTahA== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIFYDCCA0gCCQDYZ1VzcCw3pjANBgkqhkiG9w0BAQsFADBxMQswCQYDVQQGEwJV + UzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMREwDwYD + VQQKDAhBa2xpdml0eTEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEDAOBgNVBAMMB1Rl + c3QgQ0EwHhcNMjExMjIxMjMwNDE0WhcNMzExMjE5MjMwNDE0WjBzMQswCQYDVQQG + EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMREw + DwYDVQQKDAhBa2xpdml0eTEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEjAQBgNVBAMM + CWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM+TrMi3 + wmhAtBAAhhjCzeUkCrq0GM8VO66qC+XL8R6WjM/NbjJxuldeukZJ7cRTu0EFwa6/ + zWA7dRdWVgZBCuhjWRcHWSFkzxhMFwJkyrQHK6eYpEXqcbGEc8O7uqZCGt5EOKih + 2zGI3Qg/EKODEEpMWeIXeEVUbxu08HpYyvf2jIcaifRGUypX3aJrxz5cWdMdbKpV + zXQqFIBY2l4XsGiJzVAXuiLkRZXPZslsjW05J5TPwLU6VSFv2vz/MW9pwlIh0LCE + 624ccm7WlJ0iI5jMy0l9daS543aFzjq1lDdmjIPbu7wYySTV0DW08f2i5mVLXdSj + FyKc64R98yI42tPaaICZ6oZDBvI0Q01x3Ix5zj59YnJ+3TX7M1/nDnJtmCljLk3w + fm1WPCJw6r0zH5q0HFWKZpGaP3CHQ+h+ouClrGtceTxOiIwCSi94ix2MWr8letXZ + G9U9pThh6K/BmID0NNnVRJE9TdgD/NhN/4Ob9wHEQr3Ax/KBCg/zNo7dFY0V7hSW + nDzzevk7h/KHG9VUieBRyhVeLbB8FqdbcSue9hlUn1G5keIWcHSPMGEy6PTJ52Bi + e6ikzNgSMh9e1/l6nmTSkw8tBgJD1an2B723FtbLZXTBklQUFfvIwWzX+AUb+HHE + PjDjRS7FwgMb7boutj0d84Du0QH4YD8tFmORAgMBAAEwDQYJKoZIhvcNAQELBQAD + ggIBAAjyCVGqLUl1EGpRmAAcwtFi2uy7isW+RoyQFOycY5hQBi83KxQ9jnl2VmfO + A3kb1AKlPhCyNMlaW+qTxiwdWtEx3lf6Efm83ePsbwialMGb0ybQRRdvyEOkw5LO + Q5TOUI7R5tijZQMb6qxPjOJwkgQRl6iOqIDAZmO1ttnqZgxtWCWpajLtCpWO2nDk + fLq5UsEFv5heyheUjtOu9pGRzNNAHFMgtOqsAmH8wOTqjxAf3YtMPSanM+fW738T + akd1mFhtSp2YjVDMUggix9IrFcBJTpDZBHQJdeBPVjoslfGtVaTcpFBSzcqboCwL + 8eJwoFYqBzekV0ZjSY2Vo0z9d6TkNDptrwZYDk9MgmN1qV3coBBCTRYxRUhA/kqF + slO3nb+RlcUVwQCZY9twzO845kRsrwaT/xpcmuMCA7xSvKAPVz8nDOEAaZF4CISv + mRa2Td6UWajJ/RB0G4BkTO+fBa68sWyIFOANAenRP2laMCoLqAS2ApORHVaZ3d3x + bF7Mf+BG70ukLzGwK/6XPe79xEr8F3X9eBJ0sbTqXrgvNmpKN/qIixdDqa6UQDUr + 7g2E6OCYhMgxXmoWAMshYRTBEVlsG6EGn0v6m5IzWAua+Kg5Jur8j8+JEUArsvt8 + MdoPFL6oo+FNgQrkHwHkiONYd+iuunJTJEeXFQEzpoxNvrc1 + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIFXjCCA0YCCQCuorYrG5wG+DANBgkqhkiG9w0BAQsFADBxMQswCQYDVQQGEwJV + UzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMREwDwYD + VQQKDAhBa2xpdml0eTEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEDAOBgNVBAMMB1Rl + c3QgQ0EwHhcNMjExMjIxMjMwNDExWhcNMzExMjE5MjMwNDExWjBxMQswCQYDVQQG + EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMREw + DwYDVQQKDAhBa2xpdml0eTEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEDAOBgNVBAMM + B1Rlc3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGPVgVO/zd + ebwGWujKymJmztWZ5LIaZC+zY1SwKUBUA3+vrtO79ndi6WePiV0a2e7wov/ajFLp + mor2RfGSMD8Yb9e98QSqnfy9Q5+ABmxFulgSJNwDjnxugZuk/6MILKMg7AsgqaxK + wROSSLcom8b+gkbwXgHm57RKiitXlRM9ujdKibeHwfu7JTk6A7LwRbCVurTRqckw + Q0/mA4mNuZ2AMGW+YL36TwTLfTAa4AVHEbI3U5+TyY3DoV7OoHI4Ec1/7B0CGzqK + smKM3dKmXpRIc5NBZt+eKqphAhp0CD1eAnutWtepahjWyY1fAYk9hZ+ayU52dAMf + +TbkPdMn5jfHhqs95VdfQjsKZPyNTYjhjHN9tAph1wKUG4XRATAvxhA2gpYgN9de + 9ztWPboVzGosauQxPrXklO8CF7hsft0RlCCP9ojVLUkZ42vI/M1S3lD8pCDtPe46 + 2zQ9S3F1R7goF3AqWm4EQqu237+zL45pCbbWyyHeXHeDrv3DNXHcWXoFicNmCBl6 + nPPsVn9qgdhmJf5QcUKLkJEEtk94Uedv5qEqiJQYSPAIZHKnv4L5Li69kghTbUv/ + Xquz2JdY5daj5eRurgZVjutkmMIaR4rJdhifBonlcKxoeSZoVbnoGzS5KcF9saz8 + 9qYU9LtF98CUMY7U4RPlVbA8D4YwDICgcwIDAQABMA0GCSqGSIb3DQEBCwUAA4IC + AQDEzoEbCsHpae5M1I+vezg7w5NAItMU4WU9IccTylSB/gfIT+hWwIv9KiqTWjxw + Y5Aj6XJ1mATHAMSQnNZCnP2Hw39/Nc3HcKmek2na2zK/TBSEFXudJmox8SK32r26 + nLstNlcYf7ixqJ5T7SOE2GJOcEUWpvTSbvQD0NvG81BVnSyUfX3FgkQLwwlyBoSE + 7FwFz+ybrbisUHHqzPVnSblEDbKv6T9ai3FjbBegzPVSd9RmtB/DzxhdSk+kL1oD + VSEPweSHEqamEnq2RIgLb7rYhmfohl0fGF5W6I3LvLqqe0KLRRID9V/jwBUGyICG + W3jGu+68jOIUqXA4+gfOwXNktd4F7So48ySbghgrY0Umr4KSs6CTHhvSZ4ZG8QO/ + ZyC+DjXsU3mihIBP/Q43YU7dYxFSdlCw79YnXvdWu7K7lZ1bIcbdH+RShcbvPcwg + iM2qAvCgZBA8xHMDQeev8QdQjxtN+uBfee0mkvbzPbIh/0prywPHjAie/bXVBPVt + VK6Gej2egPCIA5ThvGpmXh8kPd5Aqy1J++cmrzfYfPPsbmPGTLI0HFMhUuzIhFbd + TzAV/Qj83r722s6f0v3KEEhfi3EZu3bRSGIyxVtebtOLGvEb2PjJrktyVJgivVFX + uHHpz76QFOcLy1F962Hfj51NnIROOySyl12JkhPRTlMoiQ== + -----END CERTIFICATE----- + """) + .trust("serverca", + """ + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- + """) .build()) .build() .binding() diff --git a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsKeyPairVerifierTest.java b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsKeyPairVerifierTest.java deleted file mode 100644 index 770fe20ed7..0000000000 --- a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsKeyPairVerifierTest.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright 2021-2023 Aklivity Inc. - * - * Aklivity licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package io.aklivity.zilla.runtime.binding.tls.internal.config; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; - -import java.io.ByteArrayInputStream; -import java.security.KeyFactory; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.PKCS8EncodedKeySpec; -import java.util.Base64; - -import org.junit.Test; - -public class TlsKeyPairVerifierTest -{ - private static final String RSA_PRIVATE_KEY = """ - -----BEGIN PRIVATE KEY----- - MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDp62LciNw3yMp9 - 0jeeGO+kdGmqZUQqRFZlckggahlxZnLfvckSpdw18+FOvybX+T4RT5KsCwWgl6eM - DnyDZYnfK0mIk5TW6gX0oNOB/uR4n9DauN2+owlC1144nWauH0xi7clR0OU/MHPY - n+36bSIYLzOyxJYvs0fWU5j+wkl62nUo3yiII+h+tPhYmWCBmSDhXCD0BIoHzCYP - A5+c60uws9tSuzy2l8qVa41HDOdIru79GVoYP8jXJoGugoQ/uJBLJd1dCh2Egfi9 - TOJZafR2hWkdY6wzfaC68fWhS1GAnzjChoVCa0P6nUNYkj7BH4MDoHNUkrurU6zN - sG7gK1lLAgMBAAECggEAT7LETzFOHq+J1k6eZn5Gf/it28F+9QutiAjk7C5aFtn5 - /6NQ88qQ+czrEgJswJ8J96nt5jInK60gB8cTw00AKYo9Fox55LN9bfixt5PZ0gNZ - jHv6CS7RQ/XPA2kVh/Pf+cDcm8SZpuriPYdX9L/kIutKKPlz1jK2Ih7/fKVDldhb - xffwdxqmexnLwNHseNevQbhZKjjllLWZzn78xaSaHghN8fc5TF7SsgiqYGK079bG - nC7luO1t5XqQ85nql9W2ddpYP5+AKNDAatmIcJH9Kg9auuvB3qJtRFOTmcyphLo4 - EtHjn8Q1Qh9zj9se0oAxdWYYqj86XvnUgq2VPlfx2QKBgQD8sXLr6/M8rNo2w+8f - qQ6u24+/2Xq/JwwZHU5C7Jpfl/cvabxgP8W9seD5dBI+jiUyFAM1fk/baYKmr1JE - hHAGnN9yvxKj5UA0xZXe9AFkp9sz5x3QCR11lIP8bObGOvVr7z6K9DAkh/Ey9bdM - fbdN5fupfgDr3bGHHcv7ka3xtQKBgQDs+wsUADtK3STvkiV/bI0O6lJNYKJOhcYn - yzwMfAU18kGEBUcNfiUrkhFJEoRHurC8hWqMebUmHKKZ0R+8vIGv4BejcvEXdLYt - cwsjs/vpbY0W4lgaZH/V9Qpg7GPdLEhxPj/MVdKY0rp9kB9Tpo4w8n6wlqdnj9uv - HHPau37+/wKBgBzXQ/6ZV5G9SMqnYkuCyCI8/RMwh0n58u+K4LvStWvjtFq8/rsd - jDwyaTMPhGWPY79reVJJsGOijz7nE8SuOPsIPJikJkR+je13/7sKrn4GioZKAqUT - 5UDeSpIs+8n0QL6o98J0TGpe+bCPSvR4BMvnS+n0b7Z7/x8kz3tPDUNhAoGBAJD/ - TZjwR1cYFjhrYHwly+0bXD4x6T1IRqUkidpNq9aFIqcHn6DW1SFinybpqHxG80p2 - C2pmMXtfO/IHbXbKlEMrRutgMbmbVLhcUq2Gu5TozdH5rdSAN2OPKcmB+dxi8vQv - FVQOEuwky6x2GWTSXOAAD5o2o7kO4Wi0bQKhhCO7AoGAOiexYhpgXtzURWDzlQFv - nr9HyYRhxpRg97o5InO5uIkcoSPBb7FS4k8tFscz6DBlz92lDpI1dIB6yvku2JfV - F0MacyZE7wWaeGV5sH053SZr4I5ySpvbB8S8Q8ZOpt/Zfq3kujfj7y4qUt6VPu/M - 1rAIceW5pPBxbqdlJHx3W6E= - -----END PRIVATE KEY----- - """; - - private static final String RSA_VALID_CERTIFICATE = """ - -----BEGIN CERTIFICATE----- - MIIDrTCCApWgAwIBAgIQFt3rAO4w+uwvtcPwINij2DANBgkqhkiG9w0BAQsFADBz - MQswCQYDVQQGEwJVUzERMA8GA1UECgwIQWtsaXZpdHkxFDASBgNVBAsMC0RldmVs - b3BtZW50MRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQDDAlUZXN0IENBIDEx - EjAQBgNVBAcMCVBhbG8gQWx0bzAeFw0yMTA3MjIyMjU0NTdaFw0yMjA4MjIyMzU0 - NTdaMBgxFjAUBgNVBAMMDSouZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA - A4IBDwAwggEKAoIBAQDp62LciNw3yMp90jeeGO+kdGmqZUQqRFZlckggahlxZnLf - vckSpdw18+FOvybX+T4RT5KsCwWgl6eMDnyDZYnfK0mIk5TW6gX0oNOB/uR4n9Da - uN2+owlC1144nWauH0xi7clR0OU/MHPYn+36bSIYLzOyxJYvs0fWU5j+wkl62nUo - 3yiII+h+tPhYmWCBmSDhXCD0BIoHzCYPA5+c60uws9tSuzy2l8qVa41HDOdIru79 - GVoYP8jXJoGugoQ/uJBLJd1dCh2Egfi9TOJZafR2hWkdY6wzfaC68fWhS1GAnzjC - hoVCa0P6nUNYkj7BH4MDoHNUkrurU6zNsG7gK1lLAgMBAAGjgZcwgZQwGAYDVR0R - BBEwD4INKi5leGFtcGxlLmNvbTAJBgNVHRMEAjAAMB8GA1UdIwQYMBaAFNrwPBOM - SNJjl2B+QtjfJCjK4aIAMB0GA1UdDgQWBBT2vzUtTK6vtN5UHyiCZOFTKvPXXDAO - BgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0G - CSqGSIb3DQEBCwUAA4IBAQAwHVTQgjVvxlhE80xi7mKLJrRwAC04CysWe+q3WFTN - xt5PPmT5ZCanL1aFh62UuvzNTyhcJEo/kuYo4PNEEtywMsLEXre4cWBbcFUyS2sM - z84ikMiG885ZH3ZfdWwH/N/DLL1Ro8+pIxCyxBzgAXIbuDcvhSN8E0SRTTgtOyeJ - r+xxf6axm340hzyQHUNv3U7g7H2KYZtnbf98criMcbVYHaxpRyPkDTfmzYRkl2nn - TgUnkZ3b5BI8XFq6vltAmxwcV/8IjKYd9eKazJg/I+mnMYzIpLYTD/UkMHyUMxrC - sES8isPpB+QNvHC4gVowAAkxnk216r3Ft0od41jTkrQF - -----END CERTIFICATE----- - """; - - private static final String RSA_INVALID_CERTIFICATE = """ - -----BEGIN CERTIFICATE----- - MIIDpjCCAo6gAwIBAgIIJWpr8WDPucUwDQYJKoZIhvcNAQELBQAwXjERMA8GA1UE - AxMIc2VydmVyY2ExFDASBgNVBAsTC0RldmVsb3BtZW50MREwDwYDVQQKEwhBa2xp - dml0eTETMBEGA1UECBMKQ2FsaWZvcm5pYTELMAkGA1UEBhMCVVMwHhcNMjQwNjI3 - MTA1OTQ5WhcNMjkwNjAxMTA1OTQ5WjBeMRIwEAYDVQQDEwlsb2NhbGhvc3QxFDAS - BgNVBAsTC0RldmVsb3BtZW50MRAwDgYDVQQKEwdBa2xpdnR5MRMwEQYDVQQIEwpD - YWxpZm9ybmlhMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC - AQoCggEBAMPa6QJuljN9vVeBHzb2sB+YgL7pFPI9tL24jaB3mlV4PvXwQ2XoZ7Oy - gR4I23iU9CfvvhHSiI2+9nAGHZgT74GZDaIiTxZNearQ+4aGRhAAENHXRb7YD6gp - FiIjZ5SWf2+yfcTIPPi1Sp+DLp9L2FiCgCtghaDBc5xdieC24zhq3Rp56tsaQGen - sEK4qZ+9bAevD7l59FWat7Yts5p/emu3+UNAka+n2zVz+BF0uc9he4NHgHMvd0uq - GlnTKWQ3zrQ+LUD7nOOq6db2Pb2+FTg+4+0y/hdzwFkuNL9OOmWvsSOPUIJIBpyR - gwi0+I+MWODoUPYJE1yLIlGJ5t7SWDsCAwEAAaNoMGYwHQYDVR0OBBYEFD2P04GZ - l36DmMNQmz7auMC7LStQMA4GA1UdDwEB/wQEAwIFoDAUBgNVHREEDTALgglsb2Nh - bGhvc3QwHwYDVR0jBBgwFoAU4ebi5t0zi0JyZI1SdZrrG9m6CIwwDQYJKoZIhvcN - AQELBQADggEBAFr0mzsLaa64aO10HnRpU9ppFkRiFiu3peaqrSZd/1mHxacwPTEr - c4QtaNhB1sVu1zVlzKPQYJ/yRsUD+wSwURud8syEjeieIXu3mytdQMQN/7hIE3KL - PO38SUk3pN8GU7auvuysT4/xbnZ7J+55UMCKkjcVO17NwVWXT9BbIKmHScLwCuB+ - +5LG02GLU6IWzrWcCsmsjbMiT+xntAHXzJChwx5abuBpg8hHN3Yaz7/K9E1dVzop - ZhqL8TG4TlhXtUJjd8VxAroyMi0VZSVHTZoqz2Zmkw/CT30rRT7E/I1zy2ZYUYqS - kuIWfzOfqCZSmGeqzuSE996ndM+FlQ6r0Zs= - -----END CERTIFICATE----- - """; - - private static final String ECDSA_PRIVATE_KEY = """ - -----BEGIN PRIVATE KEY----- - MIIG/AIBADANBgkqhkiG9w0BAQEFAASCBuYwggbiAgEAAoIBgQCoTi8NqWS3E2tW - Crwh1p7bfzPgKj1e7gOjk9bb6CQ7osbZqoR/wdhvEcgIRykxkjLvwYaeRAYboq6g - jIEkz6H8UwMxZvWZ4d2z3ruOATRwlzw4bITwilwY0nXeqkpHDXathNoQqFMpcXOo - veEBGNyNOjFH77Scqmc8reoQai2pKFmffWc00kcNCYM+y5rxmsV8kvGrOLYalJUn - TRVh7tpda29+XFEuYWCciHAK1k+FT3QqcvUB56vZv0350J0BaNr3KrnqDX58SsCa - ub6UlF3P+1rEs5JhrG6nNIUo9ZlFQIQNrhfZtmt86MCd8fF4jZXEsD0sa4MDBNl5 - SeH911ZqOjb3T84WHU43UHBvG4PcvxiJ86MA/+vKdDHBKXI+GWWNoXZoa4fofAIB - MCYJOIK35deL8Hwj5yEAHz6843WW896xmUJcGmHn0tAuskfBwcLHhovB1nMu1Oiy - YTIJ0xghj96fu80ts9VstYK7aAPT5cPp0U2TU/ptH1+R0KEfUdcCAwEAAQKCAYAu - XZ+T1Ws0Dkr/IKT0c4I++NuLMUfH660f9r31xg2ZSj4av+GRqo7cBluDgEsmZ17V - 8wwJdLb0DQyrmRmI0RSQhTP3e6REeNdRUpZ7x/Qw4lEKQEcdVxiJFA25wlMFIP3l - Tpiehyil3aXdwjWGzlkQJQxng29Py5f2PPki/YVHuSB7khoJELbXLhw0g/XTAm7O - Y1LldxGf3/f5JEC0Qo9wtgS4nGkW7Genp+Sp76FnmdxoR1Qc6rxKl+u82w4t0bsx - 7EAVdsqgqQ3dzr4Er/BRT9n+al4/SPHa1mE1+l5jncQZgNzIQQ42z02SdofQ+hnk - 2IVmJvhVB9AvJvaKJ6OgIuzlR3PY0giDouNfHteLERe+RUULiUIV1nLgRYEXrDiQ - ffqB/xIIc7hFK9l4g4oIPUMfhPa4sgIvz79s/ywyLOz68ZsK9N7sbX9KpkAz7rtI - mtb8dJNLGLrR1e3a1nmGMejxBcfUsgfRzNlI89hzhu3aJQGwtHn/UI7gz9E8i+UC - gcEAu0p5HaQ43DkiZJn7G/YW3uakDQ5UphWLQ6jWepnKG991HTdsI7sL/VueAroI - zFDETIstReropSkqySQp6pXeJvc+knKYnm5OEjvJ7UGpAifyF0o8EG5xTXPKqLst - wbK3btaVPRCptKZ7mLnHNW3RACYBLGmJnlLjpBpHmKQxnQEckB5ecw263ALFPQPR - 2J3mK2l+SoYG2khMEqIHzVXk1uk9ks03sA6rSNvcp9yj8q/coGP8dQul8vSf5Vlj - uGILAoHBAOYMrT7pJ1iYdKHy7l1REE/80ws2jFcwsjQ4C4zk9dX7P3xB+fjIacJF - j07eWTiHVQ3LUWKPDxrPLic+hBIs8sg2hwq23cPFeFGrOF6VhceIEr2ZXjGgKp9A - THTeAmTNZD4/pzKbRui8qmO5jMUoml4cXcY4K79FdhJzebVHUt+1MIv47iAqYZA6 - ItzJpsbrVwzhL7RygbP/MFJYdjDiv09IB7AyPhU5SAEH0of/QZLD7MmPZ/5bAiJK - QJualL+a5QKBwEGMkhEevcvNr0zYW3twyJZg0H/FSTkLhz854z7rfkH9FkcQc6eZ - uluE6it4IsYnalyDxWeYDK5pVxEouAbjRuoKVHr64pFod6iIBmckONuJUYB3Ochi - bwM1iHM/d4c4XlzLe1Xw9ARG1DEirCb19VUA+B4sHb8ssYFotTAmHzsc/XsvNc08 - u+5uhcuR/6q5sKn29P1uJQ3WidFnpiVmb34MCcHMUzYqHCaW1IZngXXZuPTlqaDp - X75FgYTKoU0R+wKBwHMkcSoFxJ3BYM8WKlwmkMWYQ4FfQgr54pfkXVOd3bXGVVY6 - J4Vvug90hW/yNjHm+pk25HsyI1tFy1H1JmF6geHX+OtR79lm4vvteP9OU3E1GDwx - oUWxZuPiaOItpIETlFLbxTG9Klae56GWY3DjC7CC/iSSRMMtXxWJGqezFTXHGI9W - fsk2rTJlBsH/ZCw36pAVvazRiz2uQl9Uy4NYWmyyHrb/zrcMvo9VfPh4uDdfPQr9 - bg2PO5gyFfhL/JuSSQKBwALFikkxrWjwwIvbazo1LPYFJD93CsPTNXIFm91DhE6y - J+GDL5lj2C4lpEthkj+rUPeoJ+7c8IN+NNotOg+ZJfSgpw1Vgp/+7IDVNhx0QIYP - CATuu7sFKGrYUkLjiIGTAOjaXCevdPfOH8hCN/MyJnFRbT4t0KlzMCgfSpr7SSMH - zyTaY/Ol9Gf4+x1TV1IaoTPyS0ELdWmLjWdDsbbbE1fyDRtTyE/9iCk6mbbyCuDy - UhQx4S7sO1syI8kFxelGag== - -----END PRIVATE KEY----- - """; - - private static final String ECDSA_VALID_CERTIFICATE = """ - -----BEGIN CERTIFICATE----- - MIIEZDCCAsygAwIBAgIIe+JXoqra/IUwDQYJKoZIhvcNAQEMBQAwXjERMA8GA1UE - AxMIc2VydmVyY2ExFDASBgNVBAsTC0RldmVsb3BtZW50MREwDwYDVQQKEwhBa2xp - dml0eTETMBEGA1UECBMKQ2FsaWZvcm5pYTELMAkGA1UEBhMCVVMwHhcNMjQwMjA1 - MjAxMzMzWhcNMjkwMTA5MjAxMzMzWjAYMRYwFAYDVQQDDA0qLmV4YW1wbGUuY29t - MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAqE4vDalktxNrVgq8Idae - 238z4Co9Xu4Do5PW2+gkO6LG2aqEf8HYbxHICEcpMZIy78GGnkQGG6KuoIyBJM+h - /FMDMWb1meHds967jgE0cJc8OGyE8IpcGNJ13qpKRw12rYTaEKhTKXFzqL3hARjc - jToxR++0nKpnPK3qEGotqShZn31nNNJHDQmDPsua8ZrFfJLxqzi2GpSVJ00VYe7a - XWtvflxRLmFgnIhwCtZPhU90KnL1Aeer2b9N+dCdAWja9yq56g1+fErAmrm+lJRd - z/taxLOSYaxupzSFKPWZRUCEDa4X2bZrfOjAnfHxeI2VxLA9LGuDAwTZeUnh/ddW - ajo290/OFh1ON1BwbxuD3L8YifOjAP/rynQxwSlyPhlljaF2aGuH6HwCATAmCTiC - t+XXi/B8I+chAB8+vON1lvPesZlCXBph59LQLrJHwcHCx4aLwdZzLtTosmEyCdMY - IY/en7vNLbPVbLWCu2gD0+XD6dFNk1P6bR9fkdChH1HXAgMBAAGjbDBqMB0GA1Ud - DgQWBBS6TIXoFDZ+ik9ZAL/1txt20PvZ6TAOBgNVHQ8BAf8EBAMCBaAwGAYDVR0R - BBEwD4INKi5leGFtcGxlLmNvbTAfBgNVHSMEGDAWgBSqJw9lbKd9+WdnCKLbDLnS - FxyoqzANBgkqhkiG9w0BAQwFAAOCAYEAdrU2sI4NMJB4Jb+8k1NTQoq6qh+VkKvq - hHzc1F13tvXmErl43OjQkfcfCPOSxDeZh5POBycJArXqnbKXl5t7w8YJnWTeuIFm - XoJ8ZHjMdSuKiU4waPrYVaY5t6q9bOcyXDGjObIiUH1UTn734aKZkVN3+Cwz4Ib0 - fKLjjfpOBXkNpSDps7T/7g0iQTfxwlQUBthVoUkpN5cQV+/xruIErWLdaKcEYN5A - 4LAnFfUGMtX9Qfr/IbWMuuZuUTzTPjumYn3ccx70rgItCG30dm8RJSyqUx8f43yI - VnuLCZ3YyV1J5vN56rdOUS+zrMnXJy404eD5aV4g46iyKESg7a8v+ABQ3QkgNnpb - gUGyiltJyjNMVdFf8UC/CfPBySFB1Hfo7g3/y8FNB7UKLJS0UDm68/mjLUwmasUr - nfjfcABz8ZwaNGqlb4qWJfA+yI/UCL1FpIBZiaEWmhZsCQwgsFk8vXpI52e3IUxt - EzpLY+k37xLdk1xkBe59n+hL/hecSiXF - -----END CERTIFICATE----- - """; - - private static final char[] PASSWORD = "generated".toCharArray(); - - @Test - public void shouldVerifyRsaValid() throws Exception - { - // GIVEN - TlsKeyPairVerifier verifier = new TlsKeyPairVerifier(); - KeyStore.PrivateKeyEntry entry = privateKeyEntry(RSA_PRIVATE_KEY, RSA_VALID_CERTIFICATE, PASSWORD); - - // WHEN - boolean valid = verifier.verify(entry); - - // THEN - assertThat(valid, equalTo(true)); - } - - @Test - public void shouldVerifyRsaInvalid() throws Exception - { - // GIVEN - TlsKeyPairVerifier verifier = new TlsKeyPairVerifier(); - KeyStore.PrivateKeyEntry entry = privateKeyEntry(RSA_PRIVATE_KEY, RSA_INVALID_CERTIFICATE, PASSWORD); - - // WHEN - boolean valid = verifier.verify(entry); - - // THEN - assertThat(valid, equalTo(false)); - } - - @Test - public void shouldVerifyEcdsaValid() throws Exception - { - // GIVEN - TlsKeyPairVerifier verifier = new TlsKeyPairVerifier(); - KeyStore.PrivateKeyEntry entry = privateKeyEntry(ECDSA_PRIVATE_KEY, ECDSA_VALID_CERTIFICATE, PASSWORD); - - // WHEN - boolean valid = verifier.verify(entry); - - // THEN - assertThat(valid, equalTo(true)); - } - - private static KeyStore.PrivateKeyEntry privateKeyEntry( - String privateKeyPem, - String certificatePem, - char[] password) throws Exception - { - PrivateKey privateKey = privateKeyFromPem(privateKeyPem); - X509Certificate certificate = certificateFromPem(certificatePem); - KeyStore keyStore = KeyStore.getInstance("PKCS12"); - keyStore.load(null, password); - X509Certificate[] certChain = {certificate}; - keyStore.setKeyEntry("localhost", privateKey, password, certChain); - return (KeyStore.PrivateKeyEntry) keyStore.getEntry("localhost", new KeyStore.PasswordProtection(password)); - } - - private static PrivateKey privateKeyFromPem( - String pem) throws Exception - { - String privateKeyPem = pem - .replace("-----BEGIN PRIVATE KEY-----", "") - .replace("-----END PRIVATE KEY-----", "") - .replaceAll("\\s", ""); - byte[] decoded = Base64.getDecoder().decode(privateKeyPem); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - return keyFactory.generatePrivate(keySpec); - } - - private static X509Certificate certificateFromPem( - String pem) throws Exception - { - String certificatePem = pem - .replace("-----BEGIN CERTIFICATE-----", "") - .replace("-----END CERTIFICATE-----", "") - .replaceAll("\\s", ""); - byte[] decoded = Base64.getDecoder().decode(certificatePem); - CertificateFactory factory = CertificateFactory.getInstance("X.509"); - return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(decoded)); - } -} diff --git a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ClientIT.java b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ClientIT.java index 2a338ec4ab..db4427dd89 100644 --- a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ClientIT.java +++ b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ClientIT.java @@ -15,9 +15,9 @@ */ package io.aklivity.zilla.runtime.binding.tls.internal.streams; -import static io.aklivity.zilla.runtime.binding.tls.internal.TlsConfigurationTest.TLS_CACERTS_STORE_NAME; -import static io.aklivity.zilla.runtime.binding.tls.internal.TlsConfigurationTest.TLS_CACERTS_STORE_PASS_NAME; import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_DRAIN_ON_CLOSE; +import static io.aklivity.zilla.runtime.engine.test.EngineRule.ENGINE_CACERTS_STORE_NAME; +import static io.aklivity.zilla.runtime.engine.test.EngineRule.ENGINE_CACERTS_STORE_PASS_NAME; import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.rules.RuleChain.outerRule; @@ -70,8 +70,8 @@ public void shouldEstablishConnection() throws Exception @Specification({ "${app}/connection.established/client", "${net}/connection.established/server" }) - @Configure(name = TLS_CACERTS_STORE_NAME, value = "src/test/democa/client/trust") - @Configure(name = TLS_CACERTS_STORE_PASS_NAME, value = "generated") + @Configure(name = ENGINE_CACERTS_STORE_NAME, value = "src/test/democa/client/trust") + @Configure(name = ENGINE_CACERTS_STORE_PASS_NAME, value = "generated") public void shouldEstablishConnectionWithTrustcacerts() throws Exception { k3po.finish(); diff --git a/runtime/binding-ws/pom.xml b/runtime/binding-ws/pom.xml index 245d8a5477..5c13fc5a40 100644 --- a/runtime/binding-ws/pom.xml +++ b/runtime/binding-ws/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/catalog-apicurio/pom.xml b/runtime/catalog-apicurio/pom.xml index b813c9848c..114b8ea764 100644 --- a/runtime/catalog-apicurio/pom.xml +++ b/runtime/catalog-apicurio/pom.xml @@ -6,7 +6,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/catalog-apicurio/src/main/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogHandler.java b/runtime/catalog-apicurio/src/main/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogHandler.java index ebbc32c72e..0f435119af 100644 --- a/runtime/catalog-apicurio/src/main/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogHandler.java +++ b/runtime/catalog-apicurio/src/main/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogHandler.java @@ -38,12 +38,14 @@ import jakarta.json.JsonReader; import jakarta.json.stream.JsonParsingException; +import org.agrona.BitUtil; import org.agrona.DirectBuffer; import org.agrona.collections.Int2ObjectCache; import org.agrona.concurrent.UnsafeBuffer; import io.aklivity.zilla.runtime.catalog.apicurio.config.ApicurioOptionsConfig; -import io.aklivity.zilla.runtime.catalog.apicurio.internal.types.ApicurioPrefixFW; +import io.aklivity.zilla.runtime.catalog.apicurio.internal.types.ApicurioDefaultIdFW; +import io.aklivity.zilla.runtime.catalog.apicurio.internal.types.ApicurioLegacyIdFW; import io.aklivity.zilla.runtime.engine.EngineContext; import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler; import io.aklivity.zilla.runtime.engine.model.function.ValueConsumer; @@ -60,9 +62,12 @@ public class ApicurioCatalogHandler implements CatalogHandler private static final long RESET_RETRY_DELAY_MS_DEFAULT = 0L; private static final long RETRY_INITIAL_DELAY_MS_DEFAULT = 1000L; - private final ApicurioPrefixFW.Builder prefixRW = new ApicurioPrefixFW.Builder() + private final ApicurioLegacyIdFW.Builder legacyIdRW = new ApicurioLegacyIdFW.Builder() .wrap(new UnsafeBuffer(new byte[5]), 0, 5); + private final ApicurioDefaultIdFW.Builder defaultIdRW = new ApicurioDefaultIdFW.Builder() + .wrap(new UnsafeBuffer(new byte[9]), 0, 9); + private final HttpClient client; private final String baseUrl; private final CRC32C crc32c; @@ -73,13 +78,14 @@ public class ApicurioCatalogHandler implements CatalogHandler private final long catalogId; private final String groupId; private final String useId; + private final IdDecoder decodeId; private final IdEncoder encodeId; - private final int idSize; + private final int sizeofId; + private final int encodePadding; private final String artifactPath; private final ConcurrentMap> cachedArtifacts; private final ConcurrentMap> cachedArtifactIds; - public ApicurioCatalogHandler( ApicurioOptionsConfig config, EngineContext context, @@ -87,6 +93,7 @@ public ApicurioCatalogHandler( { this(config, context, catalogId, new ApicurioCache()); } + public ApicurioCatalogHandler( ApicurioOptionsConfig config, EngineContext context, @@ -101,8 +108,10 @@ public ApicurioCatalogHandler( this.maxAgeMillis = config.maxAge.toMillis(); this.groupId = config.groupId; this.useId = config.useId; + this.decodeId = config.idEncoding.equals(LEGACY_ID_ENCODING) ? this::decodeLegacyId : this::decodeDefaultId; this.encodeId = config.idEncoding.equals(LEGACY_ID_ENCODING) ? this::encodeLegacyId : this::encodeDefaultId; - this.idSize = config.idEncoding.equals(LEGACY_ID_ENCODING) ? SIZE_OF_INT : SIZE_OF_LONG; + this.sizeofId = config.idEncoding.equals(LEGACY_ID_ENCODING) ? SIZE_OF_INT : SIZE_OF_LONG; + this.encodePadding = BitUtil.SIZE_OF_BYTE + sizeofId; this.artifactPath = useId.equals(CONTENT_ID) ? ARTIFACT_BY_CONTENT_ID_PATH : ARTIFACT_BY_GLOBAL_ID_PATH; this.event = new ApicurioEventContext(context); this.catalogId = catalogId; @@ -325,7 +334,7 @@ public int resolve( int schemaId = NO_SCHEMA_ID; if (data.getByte(index) == MAGIC_BYTE) { - schemaId = encodeId.encode(data, index + SIZE_OF_BYTE); + schemaId = decodeId.decode(data, index + SIZE_OF_BYTE); } return schemaId; } @@ -346,8 +355,8 @@ public int decode( if (data.getByte(index) == MAGIC_BYTE) { progress += SIZE_OF_BYTE; - schemaId = encodeId.encode(data, index + progress); - progress += idSize; + schemaId = decodeId.decode(data, index + progress); + progress += sizeofId; } if (schemaId > NO_SCHEMA_ID) @@ -368,17 +377,16 @@ public int encode( ValueConsumer next, Encoder encoder) { - ApicurioPrefixFW prefix = prefixRW.rewrap().schemaId(schemaId).build(); - next.accept(prefix.buffer(), prefix.offset(), prefix.sizeof()); + int prefixLen = encodeId.encode(schemaId, next); int valLength = encoder.accept(traceId, bindingId, schemaId, data, index, length, next); - return valLength > 0 ? prefix.sizeof() + valLength : -1; + return valLength > 0 ? prefixLen + valLength : -1; } @Override public int encodePadding( int length) { - return MAX_PADDING_LENGTH; + return encodePadding; } private URI toURI( @@ -415,13 +423,29 @@ private int resolveId( } private int encodeDefaultId( + int schemaId, ValueConsumer next) + { + ApicurioDefaultIdFW prefix = defaultIdRW.rewrap().schemaId(schemaId).build(); + next.accept(prefix.buffer(), prefix.offset(), prefix.sizeof()); + return prefix.sizeof(); + } + + private int encodeLegacyId( + int schemaId, ValueConsumer next) + { + ApicurioLegacyIdFW prefix = legacyIdRW.rewrap().schemaId(schemaId).build(); + next.accept(prefix.buffer(), prefix.offset(), prefix.sizeof()); + return prefix.sizeof(); + } + + private int decodeDefaultId( DirectBuffer data, int index) { return (int) data.getLong(index, ByteOrder.BIG_ENDIAN); } - private int encodeLegacyId( + private int decodeLegacyId( DirectBuffer data, int index) { @@ -431,6 +455,12 @@ private int encodeLegacyId( @FunctionalInterface private interface IdEncoder { - int encode(DirectBuffer data, int index); + int encode(int schemaId, ValueConsumer next); + } + + @FunctionalInterface + private interface IdDecoder + { + int decode(DirectBuffer data, int index); } } diff --git a/runtime/catalog-apicurio/src/main/zilla/internal.idl b/runtime/catalog-apicurio/src/main/zilla/internal.idl index 6e106c2a6a..b7f3a6b3aa 100644 --- a/runtime/catalog-apicurio/src/main/zilla/internal.idl +++ b/runtime/catalog-apicurio/src/main/zilla/internal.idl @@ -16,7 +16,13 @@ scope internal { option byteorder network; - struct ApicurioPrefix + struct ApicurioDefaultId + { + uint8 magic = 0; + int64 schemaId; + } + + struct ApicurioLegacyId { uint8 magic = 0; int32 schemaId; diff --git a/runtime/catalog-apicurio/src/test/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogHandlerTest.java b/runtime/catalog-apicurio/src/test/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogHandlerTest.java new file mode 100644 index 0000000000..1a50a002fb --- /dev/null +++ b/runtime/catalog-apicurio/src/test/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogHandlerTest.java @@ -0,0 +1,229 @@ +/* + * Copyright 2021-2023 Aklivity Inc + * + * Licensed under the Aklivity Community License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at + * + * https://www.aklivity.io/aklivity-community-license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package io.aklivity.zilla.runtime.catalog.apicurio.internal; + +import static org.agrona.BitUtil.SIZE_OF_BYTE; +import static org.agrona.BitUtil.SIZE_OF_INT; +import static org.agrona.BitUtil.SIZE_OF_LONG; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.time.Duration; + +import org.agrona.DirectBuffer; +import org.agrona.MutableDirectBuffer; +import org.agrona.concurrent.UnsafeBuffer; +import org.junit.Test; + +import io.aklivity.zilla.runtime.catalog.apicurio.config.ApicurioOptionsConfig; +import io.aklivity.zilla.runtime.engine.EngineContext; +import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler; +import io.aklivity.zilla.runtime.engine.model.function.ValueConsumer; + +public class ApicurioCatalogHandlerTest +{ + private static final int SIZE_OF_DEFAULT_PREFIX = SIZE_OF_BYTE + SIZE_OF_LONG; + private static final int SIZE_OF_LEGACY_PREFIX = SIZE_OF_BYTE + SIZE_OF_INT; + + private EngineContext context = mock(EngineContext.class); + + @Test + public void shouldVerifyDefaultEncodePadding() + { + ApicurioOptionsConfig config = ApicurioOptionsConfig.builder() + .url("http://localhost:8080") + .groupId("groupId") + .maxAge(Duration.ofSeconds(1)) + .build(); + + ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); + + int actual = catalog.encodePadding(0); + + assertEquals(SIZE_OF_DEFAULT_PREFIX, actual); + } + + @Test + public void shouldVerifyLegacyEncodePadding() + { + ApicurioOptionsConfig config = ApicurioOptionsConfig.builder() + .url("http://localhost:8080") + .groupId("groupId") + .maxAge(Duration.ofSeconds(1)) + .idEncoding("legacy") + .build(); + + ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); + + int actual = catalog.encodePadding(0); + + assertEquals(SIZE_OF_LEGACY_PREFIX, actual); + } + + @Test + public void shouldEncodeDefaultSchemaId() + { + ApicurioOptionsConfig config = ApicurioOptionsConfig.builder() + .url("http://localhost:8080") + .groupId("groupId") + .maxAge(Duration.ofSeconds(1)) + .build(); + + ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); + + DirectBuffer data = new UnsafeBuffer(); + + byte[] bytes = { + 0x06, 0x69, 0x64, 0x30, 0x10, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65 }; + + data.wrap(bytes, 0, bytes.length); + + int actual = catalog.encode(0L, 0L, 1, data, 0, data.capacity(), ValueConsumer.NOP, CatalogHandler.Encoder.IDENTITY); + + assertEquals(SIZE_OF_DEFAULT_PREFIX + bytes.length, actual); + } + + @Test + public void shouldEncodeLegacySchemaId() + { + ApicurioOptionsConfig config = ApicurioOptionsConfig.builder() + .url("http://localhost:8080") + .groupId("groupId") + .maxAge(Duration.ofSeconds(1)) + .idEncoding("legacy") + .build(); + + ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); + + DirectBuffer data = new UnsafeBuffer(); + + byte[] bytes = { + 0x06, 0x69, 0x64, 0x30, 0x10, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65 }; + + data.wrap(bytes, 0, bytes.length); + + int actual = catalog.encode(0L, 0L, 1, data, 0, data.capacity(), ValueConsumer.NOP, CatalogHandler.Encoder.IDENTITY); + + assertEquals(SIZE_OF_LEGACY_PREFIX + bytes.length, actual); + } + + @Test + public void shouldDecodeDefaultSchemaId() + { + ApicurioOptionsConfig config = ApicurioOptionsConfig.builder() + .url("http://localhost:8080") + .groupId("groupId") + .maxAge(Duration.ofSeconds(1)) + .build(); + + ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); + + DirectBuffer data = new UnsafeBuffer(); + + byte[] bytes = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x06, 0x69, 0x64, 0x30, 0x10, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65 }; + + data.wrap(bytes, 0, bytes.length); + + int actual = catalog.decode(0L, 0L, data, 0, data.capacity(), ValueConsumer.NOP, CatalogHandler.Decoder.IDENTITY); + + assertEquals(data.capacity() - SIZE_OF_DEFAULT_PREFIX, actual); + } + + @Test + public void shouldDecodeLegacySchemaId() + { + ApicurioOptionsConfig config = ApicurioOptionsConfig.builder() + .url("http://localhost:8080") + .groupId("groupId") + .maxAge(Duration.ofSeconds(1)) + .idEncoding("legacy") + .build(); + + ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); + + DirectBuffer data = new UnsafeBuffer(); + + byte[] bytes = { + 0x00, 0x00, 0x00, 0x00, 0x09, + 0x06, 0x69, 0x64, 0x30, 0x10, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65 }; + + data.wrap(bytes, 0, bytes.length); + + int actual = catalog.decode(0L, 0L, data, 0, data.capacity(), ValueConsumer.NOP, CatalogHandler.Decoder.IDENTITY); + + assertEquals(data.capacity() - SIZE_OF_LEGACY_PREFIX, actual); + } + + @Test + public void shouldResolveDefaultSchemaId() + { + ApicurioOptionsConfig config = ApicurioOptionsConfig.builder() + .url("http://localhost:8080") + .groupId("groupId") + .maxAge(Duration.ofSeconds(1)) + .build(); + + ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); + + MutableDirectBuffer data = new UnsafeBuffer(new byte[SIZE_OF_DEFAULT_PREFIX + 13]); + + data.putByte(0, (byte) 0); + + byte[] bytes = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x06, 0x69, 0x64, 0x30, 0x10, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65 }; + + data.wrap(bytes, 0, bytes.length); + + int actual = catalog.resolve(data, 0, data.capacity()); + + assertEquals(9, actual); + } + + @Test + public void shouldResolveLegacySchemaId() + { + ApicurioOptionsConfig config = ApicurioOptionsConfig.builder() + .url("http://localhost:8080") + .groupId("groupId") + .maxAge(Duration.ofSeconds(1)) + .idEncoding("legacy") + .build(); + + ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); + + MutableDirectBuffer data = new UnsafeBuffer(new byte[SIZE_OF_LEGACY_PREFIX + 13]); + + data.putByte(0, (byte) 0); + + byte[] bytes = { + 0x00, 0x00, 0x00, 0x00, 0x09, + 0x06, 0x69, 0x64, 0x30, 0x10, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65 }; + + data.wrap(bytes, 0, bytes.length); + + int actual = catalog.resolve(data, 0, data.capacity()); + + assertEquals(9, actual); + } +} diff --git a/runtime/catalog-apicurio/src/test/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogIT.java b/runtime/catalog-apicurio/src/test/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogIT.java index ca55dc20c0..010561c152 100644 --- a/runtime/catalog-apicurio/src/test/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogIT.java +++ b/runtime/catalog-apicurio/src/test/java/io/aklivity/zilla/runtime/catalog/apicurio/internal/ApicurioCatalogIT.java @@ -15,15 +15,8 @@ package io.aklivity.zilla.runtime.catalog.apicurio.internal; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.junit.Assert.assertEquals; import static org.junit.rules.RuleChain.outerRule; -import static org.mockito.Mockito.mock; -import java.time.Duration; - -import org.agrona.DirectBuffer; -import org.agrona.concurrent.UnsafeBuffer; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.DisableOnDebug; @@ -32,10 +25,6 @@ import io.aklivity.k3po.runtime.junit.annotation.Specification; import io.aklivity.k3po.runtime.junit.rules.K3poRule; -import io.aklivity.zilla.runtime.catalog.apicurio.config.ApicurioOptionsConfig; -import io.aklivity.zilla.runtime.engine.EngineContext; -import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler; -import io.aklivity.zilla.runtime.engine.model.function.ValueConsumer; import io.aklivity.zilla.runtime.engine.test.EngineRule; import io.aklivity.zilla.runtime.engine.test.annotation.Configuration; @@ -58,19 +47,6 @@ public class ApicurioCatalogIT @Rule public final TestRule chain = outerRule(engine).around(k3po).around(timeout); - private ApicurioOptionsConfig config; - private EngineContext context = mock(EngineContext.class); - - @Before - public void setup() - { - config = ApicurioOptionsConfig.builder() - .url("http://localhost:8080") - .groupId("groupId") - .maxAge(Duration.ofSeconds(1)) - .build(); - } - @Test @Configuration("resolve/artifact/global/id/zilla.yaml") @Specification({ @@ -158,60 +134,4 @@ public void shouldResolveArtifactIdViaSubjectAndVersionFailed() throws Exception { k3po.finish(); } - - @Test - public void shouldVerifyMaxPadding() - { - ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); - - assertEquals(9, catalog.encodePadding(0)); - } - - @Test - public void shouldVerifyEncodedData() - { - ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); - - DirectBuffer data = new UnsafeBuffer(); - - byte[] bytes = {0x06, 0x69, 0x64, - 0x30, 0x10, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65}; - data.wrap(bytes, 0, bytes.length); - - assertEquals(18, catalog.encode(0L, 0L, 1, data, 0, data.capacity(), - ValueConsumer.NOP, CatalogHandler.Encoder.IDENTITY)); - } - - @Test - public void shouldResolveSchemaIdAndProcessData() - { - - ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); - - DirectBuffer data = new UnsafeBuffer(); - - byte[] bytes = {0x00, 0x00, 0x00, 0x00, 0x09, 0x06, 0x69, 0x64, - 0x30, 0x10, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65}; - data.wrap(bytes, 0, bytes.length); - - int valLength = catalog.decode(0L, 0L, data, 0, data.capacity(), ValueConsumer.NOP, CatalogHandler.Decoder.IDENTITY); - - assertEquals(data.capacity() - 9, valLength); - } - - @Test - public void shouldResolveSchemaIdFromData() - { - ApicurioCatalogHandler catalog = new ApicurioCatalogHandler(config, context, 0L); - - DirectBuffer data = new UnsafeBuffer(); - - byte[] bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x06, 0x69, 0x64, - 0x30, 0x10, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65}; - data.wrap(bytes, 0, bytes.length); - - int schemaId = catalog.resolve(data, 0, data.capacity()); - - assertEquals(9, schemaId); - } } diff --git a/runtime/catalog-filesystem/pom.xml b/runtime/catalog-filesystem/pom.xml index 0ca6dfc101..3ce3da669f 100644 --- a/runtime/catalog-filesystem/pom.xml +++ b/runtime/catalog-filesystem/pom.xml @@ -6,7 +6,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/catalog-inline/pom.xml b/runtime/catalog-inline/pom.xml index af975878f0..ce34f6c244 100644 --- a/runtime/catalog-inline/pom.xml +++ b/runtime/catalog-inline/pom.xml @@ -6,7 +6,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/catalog-karapace/pom.xml b/runtime/catalog-karapace/pom.xml index fdfa165235..c4b1b876ea 100644 --- a/runtime/catalog-karapace/pom.xml +++ b/runtime/catalog-karapace/pom.xml @@ -6,7 +6,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/catalog-schema-registry/pom.xml b/runtime/catalog-schema-registry/pom.xml index a994e4bc10..435ecf4a7c 100644 --- a/runtime/catalog-schema-registry/pom.xml +++ b/runtime/catalog-schema-registry/pom.xml @@ -6,7 +6,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/command-metrics/pom.xml b/runtime/command-metrics/pom.xml index 21a790cbc3..2f4ffd2212 100644 --- a/runtime/command-metrics/pom.xml +++ b/runtime/command-metrics/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/command-start/pom.xml b/runtime/command-start/pom.xml index f32caf7000..060363c0fc 100644 --- a/runtime/command-start/pom.xml +++ b/runtime/command-start/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/command-stop/pom.xml b/runtime/command-stop/pom.xml index 9236106538..02e5d640f0 100644 --- a/runtime/command-stop/pom.xml +++ b/runtime/command-stop/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/command-version/pom.xml b/runtime/command-version/pom.xml index cab2437c2f..559d0e69bd 100644 --- a/runtime/command-version/pom.xml +++ b/runtime/command-version/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/command/pom.xml b/runtime/command/pom.xml index f02e70ef1a..b38f662fac 100644 --- a/runtime/command/pom.xml +++ b/runtime/command/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/common/pom.xml b/runtime/common/pom.xml index 122a8d193a..794dc1f806 100644 --- a/runtime/common/pom.xml +++ b/runtime/common/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/engine/pom.xml b/runtime/engine/pom.xml index b50c84b478..264c0bc6a1 100644 --- a/runtime/engine/pom.xml +++ b/runtime/engine/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineConfiguration.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineConfiguration.java index c843495e29..7fcaeb3a22 100644 --- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineConfiguration.java +++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineConfiguration.java @@ -30,6 +30,7 @@ import java.net.UnknownHostException; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.KeyStore; import java.util.Properties; import java.util.function.Function; @@ -76,6 +77,9 @@ public class EngineConfiguration extends Configuration public static final BooleanPropertyDef ENGINE_VERBOSE_SCHEMA_PLAIN; public static final BooleanPropertyDef ENGINE_VERBOSE_COMPOSITES; public static final IntPropertyDef ENGINE_WORKERS; + public static final PropertyDef ENGINE_CACERTS_STORE_TYPE; + public static final PropertyDef ENGINE_CACERTS_STORE; + public static final PropertyDef ENGINE_CACERTS_STORE_PASS; private static final ConfigurationDef ENGINE_CONFIG; @@ -120,6 +124,9 @@ public class EngineConfiguration extends Configuration ENGINE_VERBOSE_SCHEMA = config.property("verbose.schema", false); ENGINE_VERBOSE_SCHEMA_PLAIN = config.property("verbose.schema.plain", false); ENGINE_WORKERS = config.property("workers", Runtime.getRuntime().availableProcessors()); + ENGINE_CACERTS_STORE_TYPE = config.property("cacerts.store.type", EngineConfiguration::cacertsStoreTypeDefault); + ENGINE_CACERTS_STORE = config.property("cacerts.store", EngineConfiguration::cacertsStoreDefault); + ENGINE_CACERTS_STORE_PASS = config.property("cacerts.store.pass"); ENGINE_CONFIG = config; } @@ -299,6 +306,21 @@ public int workers() return ENGINE_WORKERS.getAsInt(this); } + public String cacertsStoreType() + { + return ENGINE_CACERTS_STORE_TYPE.get(this); + } + + public String cacertsStore() + { + return ENGINE_CACERTS_STORE.get(this); + } + + public String cacertsStorePass() + { + return ENGINE_CACERTS_STORE_PASS.get(this); + } + public Function hostResolver() { return ENGINE_HOST_RESOLVER.get(this)::resolve; @@ -448,4 +470,16 @@ private static URI defaultConfigURI( URL url = ENGINE_CONFIG_URL.get(config); return decodeConfigURI(config, url.toString()); } + + private static String cacertsStoreTypeDefault( + Configuration config) + { + return System.getProperty("javax.net.ssl.trustStoreType", KeyStore.getDefaultType()); + } + + private static String cacertsStoreDefault( + Configuration config) + { + return System.getProperty("javax.net.ssl.trustStore"); + } } diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineWorker.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineWorker.java index 77df554429..41182d331b 100644 --- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineWorker.java +++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineWorker.java @@ -393,7 +393,15 @@ public EngineWorker( for (Vault vault : vaults) { String type = vault.name(); - vaultsByType.put(type, vault.supply(this)); + Set aliases = vault.aliases(); + + VaultContext context = vault.supply(this); + + vaultsByType.put(type, context); + for (String alias : aliases) + { + vaultsByType.put(alias, context); + } } Map catalogsByType = new LinkedHashMap<>(); diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/security/Trusted.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/security/Trusted.java new file mode 100644 index 0000000000..f92ffd435c --- /dev/null +++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/security/Trusted.java @@ -0,0 +1,85 @@ +/* + * Copyright 2021-2023 Aklivity Inc. + * + * Aklivity licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.aklivity.zilla.runtime.engine.security; + +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; +import java.security.KeyStore; + +import io.aklivity.zilla.runtime.engine.Configuration; +import io.aklivity.zilla.runtime.engine.EngineConfiguration; + +public final class Trusted +{ + private Trusted() + { + } + + public static KeyStore cacerts( + Configuration config) + { + return config instanceof EngineConfiguration engineConfig + ? cacerts(engineConfig) + : cacerts(new EngineConfiguration(config)); + } + + private static KeyStore cacerts( + EngineConfiguration config) + { + String storeType = config.cacertsStoreType(); + String storePath = config.cacertsStore(); + String storePass = config.cacertsStorePass(); + + KeyStore cacerts = null; + + if (storePath == null || !Files.exists(Paths.get(storePath))) + { + String home = System.getProperty("java.home"); + + storePath = String.format("%s/lib/security/jssecacerts", home); + + if (!Files.exists(Paths.get(storePath))) + { + storePath = String.format("%s/lib/security/cacerts", home); + + if (!Files.exists(Paths.get(storePath))) + { + storePath = null; + } + } + } + + if (storePath != null) + { + try + { + KeyStore store = KeyStore.getInstance(storeType); + store.load(new FileInputStream(storePath), storePass != null ? storePass.toCharArray() : null); + + cacerts = store; + } + catch (GeneralSecurityException | IOException ex) + { + // unable to load + } + } + + return cacerts; + } +} diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/vault/Vault.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/vault/Vault.java index 4a5fa29425..7eb2d8520d 100644 --- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/vault/Vault.java +++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/vault/Vault.java @@ -18,8 +18,9 @@ import java.net.URL; import io.aklivity.zilla.runtime.engine.EngineContext; +import io.aklivity.zilla.runtime.engine.factory.Aliasable; -public interface Vault +public interface Vault extends Aliasable { String name(); diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/vault/VaultHandler.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/vault/VaultHandler.java index 6c67d6c856..90b2c68d69 100644 --- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/vault/VaultHandler.java +++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/vault/VaultHandler.java @@ -16,15 +16,20 @@ package io.aklivity.zilla.runtime.engine.vault; import java.security.KeyStore; +import java.util.List; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; public interface VaultHandler { - KeyStore.PrivateKeyEntry key( - String ref); + KeyManagerFactory initKeys( + List keyRefs); - KeyStore.TrustedCertificateEntry certificate( - String ref); + KeyManagerFactory initSigners( + List signerRefs); - KeyStore.PrivateKeyEntry[] keys( - String signerRef); + TrustManagerFactory initTrust( + List certRefs, + KeyStore cacerts); } diff --git a/runtime/engine/src/main/moditect/module-info.java b/runtime/engine/src/main/moditect/module-info.java index 92a07f0854..1526e8d0e2 100644 --- a/runtime/engine/src/main/moditect/module-info.java +++ b/runtime/engine/src/main/moditect/module-info.java @@ -32,6 +32,7 @@ exports io.aklivity.zilla.runtime.engine.metrics.reader; exports io.aklivity.zilla.runtime.engine.reader; exports io.aklivity.zilla.runtime.engine.resolver; + exports io.aklivity.zilla.runtime.engine.security; exports io.aklivity.zilla.runtime.engine.util.function; exports io.aklivity.zilla.runtime.engine.vault; diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/EngineConfigurationTest.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/EngineConfigurationTest.java index c32db89391..7e6270907d 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/EngineConfigurationTest.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/EngineConfigurationTest.java @@ -17,9 +17,15 @@ import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_BUFFER_POOL_CAPACITY; import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_BUFFER_SLOT_CAPACITY; +import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_CACERTS_STORE; +import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_CACERTS_STORE_PASS; +import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_CACERTS_STORE_TYPE; import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_CONFIG_URL; import static io.aklivity.zilla.runtime.engine.test.EngineRule.ENGINE_BUFFER_POOL_CAPACITY_NAME; import static io.aklivity.zilla.runtime.engine.test.EngineRule.ENGINE_BUFFER_SLOT_CAPACITY_NAME; +import static io.aklivity.zilla.runtime.engine.test.EngineRule.ENGINE_CACERTS_STORE_NAME; +import static io.aklivity.zilla.runtime.engine.test.EngineRule.ENGINE_CACERTS_STORE_PASS_NAME; +import static io.aklivity.zilla.runtime.engine.test.EngineRule.ENGINE_CACERTS_STORE_TYPE_NAME; import static io.aklivity.zilla.runtime.engine.test.EngineRule.ENGINE_CONFIG_URL_NAME; import static org.junit.Assert.assertEquals; @@ -33,5 +39,8 @@ public void shouldVerifyConstants() throws Exception assertEquals(ENGINE_BUFFER_POOL_CAPACITY.name(), ENGINE_BUFFER_POOL_CAPACITY_NAME); assertEquals(ENGINE_BUFFER_SLOT_CAPACITY.name(), ENGINE_BUFFER_SLOT_CAPACITY_NAME); assertEquals(ENGINE_CONFIG_URL.name(), ENGINE_CONFIG_URL_NAME); + assertEquals(ENGINE_CACERTS_STORE_TYPE.name(), ENGINE_CACERTS_STORE_TYPE_NAME); + assertEquals(ENGINE_CACERTS_STORE.name(), ENGINE_CACERTS_STORE_NAME); + assertEquals(ENGINE_CACERTS_STORE_PASS.name(), ENGINE_CACERTS_STORE_PASS_NAME); } } diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/config/NamespaceConfigAdapterTest.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/config/NamespaceConfigAdapterTest.java index bb9d04151e..2131e07aaa 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/config/NamespaceConfigAdapterTest.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/config/NamespaceConfigAdapterTest.java @@ -49,6 +49,147 @@ public class NamespaceConfigAdapterTest { + private static final String LOCALHOST_KEY = """ + -----BEGIN PRIVATE KEY----- + MIIJRQIBADANBgkqhkiG9w0BAQEFAASCCS8wggkrAgEAAoICAQDPk6zIt8JoQLQQ + AIYYws3lJAq6tBjPFTuuqgvly/EelozPzW4ycbpXXrpGSe3EU7tBBcGuv81gO3UX + VlYGQQroY1kXB1khZM8YTBcCZMq0ByunmKRF6nGxhHPDu7qmQhreRDioodsxiN0I + PxCjgxBKTFniF3hFVG8btPB6WMr39oyHGon0RlMqV92ia8c+XFnTHWyqVc10KhSA + WNpeF7Boic1QF7oi5EWVz2bJbI1tOSeUz8C1OlUhb9r8/zFvacJSIdCwhOtuHHJu + 1pSdIiOYzMtJfXWkueN2hc46tZQ3ZoyD27u8GMkk1dA1tPH9ouZlS13UoxcinOuE + ffMiONrT2miAmeqGQwbyNENNcdyMec4+fWJyft01+zNf5w5ybZgpYy5N8H5tVjwi + cOq9Mx+atBxVimaRmj9wh0PofqLgpaxrXHk8ToiMAkoveIsdjFq/JXrV2RvVPaU4 + YeivwZiA9DTZ1USRPU3YA/zYTf+Dm/cBxEK9wMfygQoP8zaO3RWNFe4Ulpw883r5 + O4fyhxvVVIngUcoVXi2wfBanW3ErnvYZVJ9RuZHiFnB0jzBhMuj0yedgYnuopMzY + EjIfXtf5ep5k0pMPLQYCQ9Wp9ge9txbWy2V0wZJUFBX7yMFs1/gFG/hxxD4w40Uu + xcIDG+26LrY9HfOA7tEB+GA/LRZjkQIDAQABAoICAQDG+KMS8zHihMMU46umaHS8 + REQUmzV8qrm+vzkQWOETlPP87MnIiMM5pI+heJP1MN25gi8ZtrjCmbuvVw62h/pQ + r4piTKTfIaZxf94+aSb0UjtCN0qfyg6ZPoFJCdXsMElY7MPywNM/NBXLJchpM+SV + k4JE+oJK0ph+Un6AiERmU2p4xrOd9xsY54iHfBBMcnGXsAjNbdm2k+9657DJqKNs + UUsAjv3ZHD6nT1sTkH4wSCzstAfgr72Sg4nCIUvdo96ko81Kpt6VeacnH4Ds7iB5 + AzWJiD0QXS7wGWqJVCxyvlXKvwHBV3DXYixmjr+3hEKcrhWPEZXHk+sd4S0BjMYT + up7mj2GmVSTwL/XS7cCVk4QS4901P2xhnINrw40W40JWinFJ3mW2Z4oySTNsWy0N + hugHlw+O0fRFPlVwh9uu8fpLIJQAbO0XwnJ2y7G1dkvFzTEtAxHyVanfwvepwAHl + +pszn/LsvAcLO9ncWUvt2pGm4Zz3sAHDYHoTEUUFvJfF33m49Vdgl9SeHVcAIbXc + XOnaw8NLoxyR4Q+jtvlr1yFF8Kt3zrA02Bj9W2TIyWJdbwJLjfTK7X4l9Bzin1Ec + 17r4XCEsWSKQ9E19AmSriNoGLczhfDCr26BQDVLCwmnKmF86CWrL53PZ9iEXEEVA + yruQItpmIRsG4Fu5FKkNAQKCAQEA7Iom5vVMt0sibUYozumEQJ/FdG1vyIn5a3tj + ROqGExFy9fwAQi734a45VuooUw7ot9kaGaGrqy6l2a0EyxJNUnF90cuvfX/ZrFwk + /w9fWc0TSOFlEVCraSghmZ9TsGAg9NyhGQa1HNrq4XnR9LSWftyOWr6GGUJeufdn + qs/gpBBDtMVIAbusbtxuEAMtIfbuc3vvhP0HdTmeXAnUcgQCC+kPZTh/iE0YhCdZ + WKxRWoj5HhSMrWvmL/29G3/qN8eMzz0aZLjCweCi8lji69QIVyf90y0MAQ0e20EC + n+HX7gzdAvpS+K1I+lMYh9PivcYjiO3fVPMoHUCd6EiKiEy1GQKCAQEA4KeG3/Z9 + PzSgNWq0HZi62CM/ixFNxgxsPKFxK4zntOAIQIihPR8CpT3Z5UeD4SbP7f5Jep49 + 7y7zc5CaIb0+bNVSdoSIp/d6/0iNgXwhJEkP3JIpWbhlT/K1OF8V2ItvOFfBkMYl + WmHH+V1i00CQAthczmrdYMWCr38S+Pfbcz1ywNyLH1Unh4xo1USXADgpISfLapDH + AlUexIyJE3X8XurR0h7BIiAc8oyRfPVEtyASz/aDxLVrG9HpSWS8fsMcQWUKHGBa + KrK0sFi7Tc9OPCnLU6dnCT6cLM0qqGGLqqM8Cmmcz+HdhHAAt5XBn53HhERvM1og + VtlNosVEl5u5OQKCAQEAnx0roA8ARQgop2Mbjlws15/iHjiDil2txyxgEXrFJ8yE + DY4vylV373rYHWw0JfMQfqNu2DEVnngpnmyxnby5AK1RWq/uY7h9/2CYjm6T0H+P + 6mWcK/Kc64bQW1t+21U+thg30fLeIAPvHi9pGXflCH9qzwX8hL9No0EWniNp1FMQ + iGhw0KGjE4v6CZFpacCGlG6ZJ1diDevtZ7JBE1U43zQuZAOGXnSl+jfR9UEtFH6x + PRfLrdi4Ji5EaFw6fL0iLkHHIFvcvrhSRD2gn8yos6A2MTjLK2XdDNYFYvFz5DEI + 9rjW2WsPfTwqcywICWpgevqwUZ+jq1HNJvStI5Sd+QKCAQEAnAHaeNcMXQMnqlCi + KddxET1RGDr4/mqME4KtO2gLVCErudzn07EgPi34je8e1xED3irzTfJr4hiBuaQW + VQ29Nwjgzir1V2dWA8eXdO8FeNQ/7pWVn5ecy2spi68EVa9mmgLfCbGAKQa0Pygp + w7gXCdLEiBfQCi6+tS6St1AwFhP7B5FgD28sF0ZbWpbaIa3eagbfjO5jNOx1hFpv + qpMJocSB1t/CkPcqAwm40sTkZiMgzUhMcyLk8ZnQ3kXVXFYT3hnTbqc+ll4pejj0 + QXGPy9neOAaNV+8htz72u52ZxvK6dCSpX/dixGCfLt4Ras2/ystXSZrx0D3xWvKQ + 0pOyiQKCAQEAtGU0KDx5aC+zpf1Jd6xd9jPoKY9OBLIuwp1BL7Oio1d7JKrxleOt + zjtZrxZXFDdFDUeOCPy4xWv/zblbVIRhp93ruQX/j5bDZvWo85aozTf80t2+aZgr + 5msAz3/UBQ5GY0ASJreJlbuSfPn5s9fLBbHNgFg29cmqjxPKU8vUiHXNxcBbRhpU + Mp/Kplij+O6hKJeqECq5610CgqLg24vPLQKDsXtC2+ZAHvDJzShN8nu1FQnsqmsj + xuxpFoXU+KgeFwOIHD2SkB7w2kmvHQ2TUnvqbcWxcA6F2o0U9uEAAWYE7iq6V1hD + HiTCqXKPrP1QCU1/TXWVjEgnVnlruNTahA== + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIFYDCCA0gCCQDYZ1VzcCw3pjANBgkqhkiG9w0BAQsFADBxMQswCQYDVQQGEwJV + UzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMREwDwYD + VQQKDAhBa2xpdml0eTEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEDAOBgNVBAMMB1Rl + c3QgQ0EwHhcNMjExMjIxMjMwNDE0WhcNMzExMjE5MjMwNDE0WjBzMQswCQYDVQQG + EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMREw + DwYDVQQKDAhBa2xpdml0eTEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEjAQBgNVBAMM + CWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM+TrMi3 + wmhAtBAAhhjCzeUkCrq0GM8VO66qC+XL8R6WjM/NbjJxuldeukZJ7cRTu0EFwa6/ + zWA7dRdWVgZBCuhjWRcHWSFkzxhMFwJkyrQHK6eYpEXqcbGEc8O7uqZCGt5EOKih + 2zGI3Qg/EKODEEpMWeIXeEVUbxu08HpYyvf2jIcaifRGUypX3aJrxz5cWdMdbKpV + zXQqFIBY2l4XsGiJzVAXuiLkRZXPZslsjW05J5TPwLU6VSFv2vz/MW9pwlIh0LCE + 624ccm7WlJ0iI5jMy0l9daS543aFzjq1lDdmjIPbu7wYySTV0DW08f2i5mVLXdSj + FyKc64R98yI42tPaaICZ6oZDBvI0Q01x3Ix5zj59YnJ+3TX7M1/nDnJtmCljLk3w + fm1WPCJw6r0zH5q0HFWKZpGaP3CHQ+h+ouClrGtceTxOiIwCSi94ix2MWr8letXZ + G9U9pThh6K/BmID0NNnVRJE9TdgD/NhN/4Ob9wHEQr3Ax/KBCg/zNo7dFY0V7hSW + nDzzevk7h/KHG9VUieBRyhVeLbB8FqdbcSue9hlUn1G5keIWcHSPMGEy6PTJ52Bi + e6ikzNgSMh9e1/l6nmTSkw8tBgJD1an2B723FtbLZXTBklQUFfvIwWzX+AUb+HHE + PjDjRS7FwgMb7boutj0d84Du0QH4YD8tFmORAgMBAAEwDQYJKoZIhvcNAQELBQAD + ggIBAAjyCVGqLUl1EGpRmAAcwtFi2uy7isW+RoyQFOycY5hQBi83KxQ9jnl2VmfO + A3kb1AKlPhCyNMlaW+qTxiwdWtEx3lf6Efm83ePsbwialMGb0ybQRRdvyEOkw5LO + Q5TOUI7R5tijZQMb6qxPjOJwkgQRl6iOqIDAZmO1ttnqZgxtWCWpajLtCpWO2nDk + fLq5UsEFv5heyheUjtOu9pGRzNNAHFMgtOqsAmH8wOTqjxAf3YtMPSanM+fW738T + akd1mFhtSp2YjVDMUggix9IrFcBJTpDZBHQJdeBPVjoslfGtVaTcpFBSzcqboCwL + 8eJwoFYqBzekV0ZjSY2Vo0z9d6TkNDptrwZYDk9MgmN1qV3coBBCTRYxRUhA/kqF + slO3nb+RlcUVwQCZY9twzO845kRsrwaT/xpcmuMCA7xSvKAPVz8nDOEAaZF4CISv + mRa2Td6UWajJ/RB0G4BkTO+fBa68sWyIFOANAenRP2laMCoLqAS2ApORHVaZ3d3x + bF7Mf+BG70ukLzGwK/6XPe79xEr8F3X9eBJ0sbTqXrgvNmpKN/qIixdDqa6UQDUr + 7g2E6OCYhMgxXmoWAMshYRTBEVlsG6EGn0v6m5IzWAua+Kg5Jur8j8+JEUArsvt8 + MdoPFL6oo+FNgQrkHwHkiONYd+iuunJTJEeXFQEzpoxNvrc1 + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIFXjCCA0YCCQCuorYrG5wG+DANBgkqhkiG9w0BAQsFADBxMQswCQYDVQQGEwJV + UzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMREwDwYD + VQQKDAhBa2xpdml0eTEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEDAOBgNVBAMMB1Rl + c3QgQ0EwHhcNMjExMjIxMjMwNDExWhcNMzExMjE5MjMwNDExWjBxMQswCQYDVQQG + EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMREw + DwYDVQQKDAhBa2xpdml0eTEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEDAOBgNVBAMM + B1Rlc3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGPVgVO/zd + ebwGWujKymJmztWZ5LIaZC+zY1SwKUBUA3+vrtO79ndi6WePiV0a2e7wov/ajFLp + mor2RfGSMD8Yb9e98QSqnfy9Q5+ABmxFulgSJNwDjnxugZuk/6MILKMg7AsgqaxK + wROSSLcom8b+gkbwXgHm57RKiitXlRM9ujdKibeHwfu7JTk6A7LwRbCVurTRqckw + Q0/mA4mNuZ2AMGW+YL36TwTLfTAa4AVHEbI3U5+TyY3DoV7OoHI4Ec1/7B0CGzqK + smKM3dKmXpRIc5NBZt+eKqphAhp0CD1eAnutWtepahjWyY1fAYk9hZ+ayU52dAMf + +TbkPdMn5jfHhqs95VdfQjsKZPyNTYjhjHN9tAph1wKUG4XRATAvxhA2gpYgN9de + 9ztWPboVzGosauQxPrXklO8CF7hsft0RlCCP9ojVLUkZ42vI/M1S3lD8pCDtPe46 + 2zQ9S3F1R7goF3AqWm4EQqu237+zL45pCbbWyyHeXHeDrv3DNXHcWXoFicNmCBl6 + nPPsVn9qgdhmJf5QcUKLkJEEtk94Uedv5qEqiJQYSPAIZHKnv4L5Li69kghTbUv/ + Xquz2JdY5daj5eRurgZVjutkmMIaR4rJdhifBonlcKxoeSZoVbnoGzS5KcF9saz8 + 9qYU9LtF98CUMY7U4RPlVbA8D4YwDICgcwIDAQABMA0GCSqGSIb3DQEBCwUAA4IC + AQDEzoEbCsHpae5M1I+vezg7w5NAItMU4WU9IccTylSB/gfIT+hWwIv9KiqTWjxw + Y5Aj6XJ1mATHAMSQnNZCnP2Hw39/Nc3HcKmek2na2zK/TBSEFXudJmox8SK32r26 + nLstNlcYf7ixqJ5T7SOE2GJOcEUWpvTSbvQD0NvG81BVnSyUfX3FgkQLwwlyBoSE + 7FwFz+ybrbisUHHqzPVnSblEDbKv6T9ai3FjbBegzPVSd9RmtB/DzxhdSk+kL1oD + VSEPweSHEqamEnq2RIgLb7rYhmfohl0fGF5W6I3LvLqqe0KLRRID9V/jwBUGyICG + W3jGu+68jOIUqXA4+gfOwXNktd4F7So48ySbghgrY0Umr4KSs6CTHhvSZ4ZG8QO/ + ZyC+DjXsU3mihIBP/Q43YU7dYxFSdlCw79YnXvdWu7K7lZ1bIcbdH+RShcbvPcwg + iM2qAvCgZBA8xHMDQeev8QdQjxtN+uBfee0mkvbzPbIh/0prywPHjAie/bXVBPVt + VK6Gej2egPCIA5ThvGpmXh8kPd5Aqy1J++cmrzfYfPPsbmPGTLI0HFMhUuzIhFbd + TzAV/Qj83r722s6f0v3KEEhfi3EZu3bRSGIyxVtebtOLGvEb2PjJrktyVJgivVFX + uHHpz76QFOcLy1F962Hfj51NnIROOySyl12JkhPRTlMoiQ== + -----END CERTIFICATE----- + """; + + private static final String SERVERCA_TRUST = """ + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- + """; + @Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); @@ -240,7 +381,8 @@ public void shouldWriteNamespaceWithVault() .name("default") .type("test") .options(TestVaultOptionsConfig::builder) - .mode("test") + .key("localhost", LOCALHOST_KEY) + .trust("serverca", SERVERCA_TRUST) .build() .build() .build(); @@ -249,7 +391,10 @@ public void shouldWriteNamespaceWithVault() assertThat(text, not(nullValue())); assertThat(text, equalTo("{\"name\":\"test\",\"vaults\":{\"default\":{\"type\":\"test\"," + - "\"options\":{\"mode\":\"test\"}}}}")); + "\"options\":{" + + "\"key\":{\"alias\":\"localhost\",\"entry\":\"%s\"},".formatted(LOCALHOST_KEY.replaceAll("\n", "\\\\n")) + + "\"trust\":{\"alias\":\"serverca\",\"entry\":\"%s\"}".formatted(SERVERCA_TRUST.replaceAll("\n", "\\\\n")) + + "}}}}")); } @Test diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/metrics/reader/MetricsReaderTest.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/metrics/reader/MetricsReaderTest.java index e8dbc87e04..dab43a6720 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/metrics/reader/MetricsReaderTest.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/metrics/reader/MetricsReaderTest.java @@ -15,8 +15,8 @@ */ package io.aklivity.zilla.runtime.engine.metrics.reader; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -46,6 +46,7 @@ public class MetricsReaderTest }; @Test + @SuppressWarnings("unchecked") public void shouldCollectMetrics() { // GIVEN @@ -78,6 +79,7 @@ public void shouldCollectMetrics() } @Test + @SuppressWarnings("unchecked") public void shouldReturnEmptyList() { // GIVEN diff --git a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsTrustTest.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/security/TrustedTest.java similarity index 56% rename from runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsTrustTest.java rename to runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/security/TrustedTest.java index 63df3825ec..36cba89808 100644 --- a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/config/TlsTrustTest.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/security/TrustedTest.java @@ -13,7 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ -package io.aklivity.zilla.runtime.binding.tls.internal.config; +package io.aklivity.zilla.runtime.engine.security; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.emptyArray; @@ -21,25 +21,50 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; +import java.security.KeyStore; import java.security.KeyStore.TrustedCertificateEntry; import java.security.cert.X509Certificate; +import java.util.Collections; import org.junit.Test; -import io.aklivity.zilla.runtime.binding.tls.internal.TlsConfiguration; import io.aklivity.zilla.runtime.engine.Configuration; +import io.aklivity.zilla.runtime.engine.EngineConfiguration; -public class TlsTrustTest +public class TrustedTest { @Test - public void shouldConfigureTrustViaCacerts() + public void shouldConfigureTrustViaCacerts() throws Exception { - TlsConfiguration config = new TlsConfiguration(new Configuration()); - TrustedCertificateEntry[] entries = TlsTrust.cacerts(config); + EngineConfiguration config = new EngineConfiguration(new Configuration()); + KeyStore cacerts = Trusted.cacerts(config); + + assertThat(cacerts, not(nullValue())); + + TrustedCertificateEntry[] entries = Collections.list(cacerts.aliases()).stream() + .map(a -> lookup(cacerts, a)) + .toArray(TrustedCertificateEntry[]::new); - assertThat(entries, not(nullValue())); assertThat(entries, not(emptyArray())); assertThat(entries[0], not(nullValue())); assertThat(entries[0].getTrustedCertificate(), instanceOf(X509Certificate.class)); } + + private static TrustedCertificateEntry lookup( + KeyStore store, + String alias) + { + TrustedCertificateEntry cert = null; + + try + { + cert = (TrustedCertificateEntry) store.getEntry(alias, null); + } + catch (Exception ex) + { + // ignore + } + + return cert; + } } diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/EngineRule.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/EngineRule.java index 28d3f803f0..93c4267ae4 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/EngineRule.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/EngineRule.java @@ -66,6 +66,9 @@ public final class EngineRule implements TestRule public static final String ENGINE_BUFFER_POOL_CAPACITY_NAME = "zilla.engine.buffer.pool.capacity"; public static final String ENGINE_BUFFER_SLOT_CAPACITY_NAME = "zilla.engine.buffer.slot.capacity"; public static final String ENGINE_CONFIG_URL_NAME = "zilla.engine.config.url"; + public static final String ENGINE_CACERTS_STORE_TYPE_NAME = "zilla.engine.cacerts.store.type"; + public static final String ENGINE_CACERTS_STORE_NAME = "zilla.engine.cacerts.store"; + public static final String ENGINE_CACERTS_STORE_PASS_NAME = "zilla.engine.cacerts.store.pass"; private static final long EXTERNAL_AFFINITY_MASK = 1L << (Long.SIZE - 1); private static final Pattern DATA_FILENAME_PATTERN = Pattern.compile("data\\d+"); diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/DuplexIT.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/DuplexIT.java index 7ead77756d..177e49b0de 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/DuplexIT.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/DuplexIT.java @@ -15,25 +15,15 @@ */ package io.aklivity.zilla.runtime.engine.test.internal; -import static java.util.Arrays.asList; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.hamcrest.Matchers.anyOf; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.hasProperty; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.isA; import static org.junit.rules.RuleChain.outerRule; -import org.junit.ComparisonFailure; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.DisableOnDebug; -import org.junit.rules.ExpectedException; import org.junit.rules.TestRule; import org.junit.rules.Timeout; -import org.junit.runners.model.TestTimedOutException; import io.aklivity.k3po.runtime.junit.annotation.Specification; import io.aklivity.k3po.runtime.junit.rules.K3poRule; @@ -45,10 +35,8 @@ public class DuplexIT private final TestRule timeout = new DisableOnDebug(new Timeout(5, SECONDS)); - private final ExpectedException thrown = ExpectedException.none(); - @Rule - public final TestRule chain = outerRule(thrown).around(k3po).around(timeout); + public final TestRule chain = outerRule(k3po).around(timeout); @Test @Specification({ @@ -237,8 +225,6 @@ public void shouldReceiveClientSentDataWithExtension() throws Exception }) public void shouldRejectClientSentDataMissingExtension() throws Exception { - thrown.expect(hasProperty("failures", contains(asList(instanceOf(ComparisonFailure.class), - instanceOf(TestTimedOutException.class))))); k3po.finish(); } @@ -310,8 +296,6 @@ public void shouldReceiveServerSentDataWithExtension() throws Exception }) public void shouldRejectServerSentDataWithMissingExtension() throws Exception { - thrown.expect(anyOf(isA(ComparisonFailure.class), - hasProperty("failures", hasItem(isA(ComparisonFailure.class))))); k3po.finish(); } @@ -614,8 +598,6 @@ public void shouldReceiveServerFlushedNullDataWithExtensionUsingExpression() thr }) public void shouldReportFailureFromReadNullDataWhenNullDataIsNotWritten() throws Exception { - thrown.expect(anyOf(isA(ComparisonFailure.class), - hasProperty("failures", hasItem(isA(ComparisonFailure.class))))); k3po.finish(); } @@ -778,5 +760,4 @@ public void shouldReceiveServerSentWriteAbortWithExt() throws Exception { k3po.finish(); } - } diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBindingFactory.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBindingFactory.java index d6095c2bbf..bda05ef71d 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBindingFactory.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBindingFactory.java @@ -17,6 +17,7 @@ import static io.aklivity.zilla.runtime.engine.test.internal.binding.config.TestBindingOptionsConfigAdapter.DEFAULT_ASSERTION_SCHEMA; +import java.security.KeyStore; import java.util.LinkedList; import java.util.List; import java.util.Objects; @@ -40,6 +41,7 @@ import io.aklivity.zilla.runtime.engine.test.internal.binding.config.TestBindingOptionsConfig; import io.aklivity.zilla.runtime.engine.test.internal.binding.config.TestBindingOptionsConfig.CatalogAssertion; import io.aklivity.zilla.runtime.engine.test.internal.binding.config.TestBindingOptionsConfig.Event; +import io.aklivity.zilla.runtime.engine.test.internal.binding.config.TestBindingOptionsConfig.VaultAssertion; import io.aklivity.zilla.runtime.engine.test.internal.event.TestEventContext; import io.aklivity.zilla.runtime.engine.test.internal.k3po.ext.types.OctetsFW; import io.aklivity.zilla.runtime.engine.test.internal.k3po.ext.types.stream.AbortFW; @@ -50,6 +52,7 @@ import io.aklivity.zilla.runtime.engine.test.internal.k3po.ext.types.stream.FlushFW; import io.aklivity.zilla.runtime.engine.test.internal.k3po.ext.types.stream.ResetFW; import io.aklivity.zilla.runtime.engine.test.internal.k3po.ext.types.stream.WindowFW; +import io.aklivity.zilla.runtime.engine.vault.VaultHandler; final class TestBindingFactory implements BindingHandler { @@ -89,6 +92,8 @@ final class TestBindingFactory implements BindingHandler private String credentials; private List events; private int eventIndex; + private VaultHandler vault; + private VaultAssertion vaultAssertion; TestBindingFactory( EngineContext context) @@ -143,6 +148,12 @@ public void attach( } this.events = options.events; + + if (binding.vault != null) + { + this.vault = context.supplyVault(binding.vaultId); + this.vaultAssertion = options.vaultAssertion; + } } } @@ -267,6 +278,28 @@ private void onInitialBegin( target.doInitialBegin(traceId); + if (vault != null && vaultAssertion != null) + { + String key = vaultAssertion.key; + if (key != null) + { + vault.initKeys(List.of(key)); + } + + String signer = vaultAssertion.signer; + if (signer != null) + { + vault.initSigners(List.of(signer)); + } + + String trust = vaultAssertion.trust; + if (trust != null) + { + KeyStore cacerts = null; + vault.initTrust(List.of(trust), cacerts); + } + } + if (catalogs != null) { CatalogHandler handler = catalogs.get(0); @@ -324,10 +357,12 @@ else if (assertion.schema != null && !assertion.schema.equals(schema)) } } } + if (guard != null) { guard.reauthorize(traceId, routedId, 0, credentials); } + while (events != null && eventIndex < events.size()) { Event e = events.get(eventIndex); diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfig.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfig.java index 6d29ec7be3..7a138648bb 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfig.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfig.java @@ -30,6 +30,7 @@ public final class TestBindingOptionsConfig extends OptionsConfig public final List cataloged; public final List events; public final List catalogAssertions; + public final VaultAssertion vaultAssertion; public static TestBindingOptionsConfigBuilder builder() { @@ -48,7 +49,8 @@ public static TestBindingOptionsConfigBuilder builder( TestAuthorizationConfig authorization, List cataloged, List events, - List catalogAssertions) + List catalogAssertions, + VaultAssertion vaultAssertion) { super(value != null ? List.of(value) : List.of(), List.of()); this.value = value; @@ -57,6 +59,7 @@ public static TestBindingOptionsConfigBuilder builder( this.cataloged = cataloged; this.events = events; this.catalogAssertions = catalogAssertions; + this.vaultAssertion = vaultAssertion; } public static final class Event @@ -73,6 +76,24 @@ public Event( } } + public static final class VaultAssertion + { + public final String key; + public final String signer; + public final String trust; + + public VaultAssertion( + String key, + String signer, + String trust) + { + this.key = key; + this.signer = signer; + this.trust = trust; + } + } + + public static final class CatalogAssertions { public final String name; diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigAdapter.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigAdapter.java index af9bd385e2..70c4a1b6d8 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigAdapter.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigAdapter.java @@ -31,6 +31,7 @@ import io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi; import io.aklivity.zilla.runtime.engine.config.SchemaConfig; import io.aklivity.zilla.runtime.engine.config.SchemaConfigAdapter; +import io.aklivity.zilla.runtime.engine.test.internal.binding.config.TestBindingOptionsConfig.VaultAssertion; public final class TestBindingOptionsConfigAdapter implements OptionsConfigAdapterSpi { @@ -48,6 +49,10 @@ public final class TestBindingOptionsConfigAdapter implements OptionsConfigAdapt private static final String ID_NAME = "id"; private static final String SCHEMA_NAME = "schema"; private static final String DELAY_NAME = "delay"; + private static final String VAULT_NAME = "vault"; + private static final String VAULT_KEY_NAME = "key"; + private static final String VAULT_SIGNER_NAME = "signer"; + private static final String VAULT_TRUST_NAME = "trust"; private final ModelConfigAdapter model = new ModelConfigAdapter(); @@ -98,24 +103,41 @@ public JsonObject adaptToJson( object.add(CATALOG_NAME, catalogs); } - if (testOptions.catalogAssertions != null) + if (testOptions.catalogAssertions != null || + testOptions.vaultAssertion != null) { JsonObjectBuilder assertions = Json.createObjectBuilder(); - JsonObjectBuilder catalogAssertions = Json.createObjectBuilder(); - for (TestBindingOptionsConfig.CatalogAssertions c : testOptions.catalogAssertions) + + if (testOptions.catalogAssertions != null) { - JsonArrayBuilder array = Json.createArrayBuilder(); - for (TestBindingOptionsConfig.CatalogAssertion a: c.assertions) + JsonObjectBuilder catalogAssertions = Json.createObjectBuilder(); + for (TestBindingOptionsConfig.CatalogAssertions c : testOptions.catalogAssertions) { - JsonObjectBuilder assertion = Json.createObjectBuilder(); - assertion.add(ID_NAME, a.id); - assertion.add(SCHEMA_NAME, a.schema); - assertion.add(DELAY_NAME, a.delay); - array.add(assertion); + JsonArrayBuilder array = Json.createArrayBuilder(); + for (TestBindingOptionsConfig.CatalogAssertion a: c.assertions) + { + JsonObjectBuilder assertion = Json.createObjectBuilder(); + assertion.add(ID_NAME, a.id); + assertion.add(SCHEMA_NAME, a.schema); + assertion.add(DELAY_NAME, a.delay); + array.add(assertion); + } + catalogAssertions.add(c.name, array); } - catalogAssertions.add(c.name, array); + assertions.add(CATALOG_NAME, catalogAssertions); } - assertions.add(CATALOG_NAME, catalogAssertions); + + if (testOptions.vaultAssertion != null) + { + VaultAssertion v = testOptions.vaultAssertion; + JsonObjectBuilder assertion = Json.createObjectBuilder() + .add(VAULT_KEY_NAME, v.key) + .add(VAULT_SIGNER_NAME, v.signer) + .add(VAULT_TRUST_NAME, v.trust); + + assertions.add(VAULT_NAME, assertion); + } + object.add(ASSERTIONS_NAME, assertions); } @@ -184,6 +206,7 @@ public OptionsConfig adaptFromJson( if (object.containsKey(ASSERTIONS_NAME)) { JsonObject assertionsJson = object.getJsonObject(ASSERTIONS_NAME); + if (assertionsJson.containsKey(CATALOG_NAME)) { JsonObject catalogsJson = assertionsJson.getJsonObject(CATALOG_NAME); @@ -203,6 +226,15 @@ public OptionsConfig adaptFromJson( testOptions.catalogAssertions(catalogName, catalogAssertions); } } + + if (assertionsJson.containsKey(VAULT_NAME)) + { + JsonObject vaultJson = assertionsJson.getJsonObject(VAULT_NAME); + testOptions.vaultAssertion(new TestBindingOptionsConfig.VaultAssertion( + vaultJson.containsKey(VAULT_KEY_NAME) ? vaultJson.getString(VAULT_KEY_NAME) : null, + vaultJson.containsKey(VAULT_SIGNER_NAME) ? vaultJson.getString(VAULT_SIGNER_NAME) : null, + vaultJson.containsKey(VAULT_TRUST_NAME) ? vaultJson.getString(VAULT_TRUST_NAME) : null)); + } } if (object.containsKey(AUTHORIZATION_NAME)) diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigBuilder.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigBuilder.java index 56c048b4ae..a21a898af7 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigBuilder.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigBuilder.java @@ -23,6 +23,7 @@ import io.aklivity.zilla.runtime.engine.config.ConfigBuilder; import io.aklivity.zilla.runtime.engine.config.ModelConfig; import io.aklivity.zilla.runtime.engine.config.OptionsConfig; +import io.aklivity.zilla.runtime.engine.test.internal.binding.config.TestBindingOptionsConfig.VaultAssertion; public final class TestBindingOptionsConfigBuilder extends ConfigBuilder> { @@ -34,6 +35,7 @@ public final class TestBindingOptionsConfigBuilder extends ConfigBuilder catalogs; private List events; private List catalogAssertions; + private VaultAssertion vaultAssertion; TestBindingOptionsConfigBuilder( Function mapper) @@ -101,9 +103,17 @@ public TestBindingOptionsConfigBuilder catalogAssertions( return this; } + public TestBindingOptionsConfigBuilder vaultAssertion( + TestBindingOptionsConfig.VaultAssertion assertion) + { + this.vaultAssertion = assertion; + return this; + } + @Override public T build() { - return mapper.apply(new TestBindingOptionsConfig(value, mode, authorization, catalogs, events, catalogAssertions)); + return mapper.apply(new TestBindingOptionsConfig(value, mode, authorization, catalogs, events, + catalogAssertions, vaultAssertion)); } } diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/TestVaultHandler.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/TestVaultHandler.java index b04ec5739b..8e684927f9 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/TestVaultHandler.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/TestVaultHandler.java @@ -15,37 +15,173 @@ */ package io.aklivity.zilla.runtime.engine.test.internal.vault; -import java.security.KeyStore.PrivateKeyEntry; +import static java.nio.charset.StandardCharsets.US_ASCII; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.security.KeyFactory; +import java.security.KeyStore; import java.security.KeyStore.TrustedCertificateEntry; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; + +import org.agrona.LangUtil; import io.aklivity.zilla.runtime.engine.config.VaultConfig; +import io.aklivity.zilla.runtime.engine.test.internal.vault.config.TestVaultEntryConfig; +import io.aklivity.zilla.runtime.engine.test.internal.vault.config.TestVaultOptionsConfig; import io.aklivity.zilla.runtime.engine.vault.VaultHandler; public final class TestVaultHandler implements VaultHandler { + private static final Pattern PATTERN_KEY_ENTRY = + Pattern.compile( + "(?-----BEGIN PRIVATE KEY-----\n[^-]+-----END PRIVATE KEY-----\n)" + + "(?(?:-----BEGIN CERTIFICATE-----\n[^-]+-----END CERTIFICATE-----\n)+)"); + + private final TestVaultEntryConfig key; + private final TestVaultEntryConfig signer; + private final TestVaultEntryConfig trust; + public TestVaultHandler( VaultConfig vault) { + TestVaultOptionsConfig options = (TestVaultOptionsConfig) vault.options; + this.key = options != null ? options.key : null; + this.signer = options != null ? options.signer : null; + this.trust = options != null ? options.trust : null; } @Override - public PrivateKeyEntry key( - String name) + public KeyManagerFactory initKeys( + List aliases) { - return null; + KeyManagerFactory factory = null; + + if (aliases != null && key != null && aliases.contains(key.alias)) + { + final Matcher matchKey = PATTERN_KEY_ENTRY.matcher(key.entry); + if (matchKey.matches()) + { + String encodedKey = matchKey.group("key"); + String encodedChain = matchKey.group("chain"); + + try + { + CertificateFactory x509 = CertificateFactory.getInstance("X509"); + + InputStream exportedBytes = new ByteArrayInputStream(encodedChain.getBytes(US_ASCII)); + + Certificate[] chain = x509.generateCertificates(exportedBytes).toArray(Certificate[]::new); + + String base64 = encodedKey + .replace("-----BEGIN PRIVATE KEY-----", "") + .replaceAll(System.lineSeparator(), "") + .replace("-----END PRIVATE KEY-----", ""); + byte[] encoded = Base64.getMimeDecoder().decode(base64); + + KeySpec keySpec = new PKCS8EncodedKeySpec(encoded); + KeyFactory rsa = KeyFactory.getInstance("RSA"); + PrivateKey rsaKey = rsa.generatePrivate(keySpec); + + KeyStore.PrivateKeyEntry entry = new KeyStore.PrivateKeyEntry(rsaKey, chain); + + KeyStore store = KeyStore.getInstance("PKCS12"); + KeyStore.PasswordProtection protection = new KeyStore.PasswordProtection("test".toCharArray()); + store.load(null, protection.getPassword()); + + store.setEntry(key.alias, entry, protection); + + factory = KeyManagerFactory.getInstance("PKIX"); + factory.init(store, protection.getPassword()); + } + catch (Exception ex) + { + LangUtil.rethrowUnchecked(ex); + } + } + } + + return factory; } @Override - public TrustedCertificateEntry certificate( - String name) + public KeyManagerFactory initSigners( + List aliases) { - return null; + KeyManagerFactory factory = null; + + if (aliases != null && signer != null && aliases.contains(signer.alias)) + { + if (key != null && key.entry.contains(signer.entry)) + { + factory = initKeys(List.of(key.alias)); + } + } + + return factory; } @Override - public PrivateKeyEntry[] keys( - String name) + public TrustManagerFactory initTrust( + List certAliases, + KeyStore cacerts) { - return null; + TrustManagerFactory factory = null; + + if (certAliases != null && trust != null && certAliases.contains(trust.alias) || + cacerts != null) + { + try + { + KeyStore store = KeyStore.getInstance("PKCS12"); + store.load(null, null); + + if (certAliases != null && trust != null && certAliases.contains(trust.alias)) + { + CertificateFactory x509 = CertificateFactory.getInstance("X509"); + + InputStream certificateBytes = new ByteArrayInputStream(trust.entry.getBytes(US_ASCII)); + Certificate certificate = x509.generateCertificate(certificateBytes); + + KeyStore.TrustedCertificateEntry entry = new KeyStore.TrustedCertificateEntry(certificate); + + store.setEntry(trust.alias, entry, null); + } + + if (cacerts != null) + { + List aliases = Collections.list(cacerts.aliases()); + for (String alias : aliases) + { + if (cacerts.isCertificateEntry(alias) && + cacerts.getEntry(alias, null) instanceof TrustedCertificateEntry cacert) + { + store.setEntry(alias, cacert, null); + } + } + } + + factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + factory.init(store); + } + catch (Exception ex) + { + LangUtil.rethrowUnchecked(ex); + } + } + + return factory; } } diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultEntryConfig.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultEntryConfig.java new file mode 100644 index 0000000000..e9a808fde4 --- /dev/null +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultEntryConfig.java @@ -0,0 +1,45 @@ +/* + * Copyright 2021-2023 Aklivity Inc. + * + * Aklivity licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.aklivity.zilla.runtime.engine.test.internal.vault.config; + +import java.util.function.Function; + +import io.aklivity.zilla.runtime.engine.config.OptionsConfig; + +public final class TestVaultEntryConfig extends OptionsConfig +{ + public final String alias; + public final String entry; + + public static TestVaultOptionsConfigBuilder builder() + { + return new TestVaultOptionsConfigBuilder<>(TestVaultEntryConfig.class::cast); + } + + public static TestVaultOptionsConfigBuilder builder( + Function mapper) + { + return new TestVaultOptionsConfigBuilder<>(mapper); + } + + TestVaultEntryConfig( + String alias, + String entry) + { + this.alias = alias; + this.entry = entry; + } +} diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultEntryConfigAdapter.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultEntryConfigAdapter.java new file mode 100644 index 0000000000..bc080ac003 --- /dev/null +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultEntryConfigAdapter.java @@ -0,0 +1,54 @@ +/* + * Copyright 2021-2023 Aklivity Inc. + * + * Aklivity licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.aklivity.zilla.runtime.engine.test.internal.vault.config; + +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonObjectBuilder; +import jakarta.json.bind.adapter.JsonbAdapter; + +public final class TestVaultEntryConfigAdapter implements JsonbAdapter +{ + private static final String ALIAS_NAME = "alias"; + private static final String ENTRY_NAME = "entry"; + + @Override + public JsonObject adaptToJson( + TestVaultEntryConfig config) + { + JsonObjectBuilder object = Json.createObjectBuilder(); + object.add(ALIAS_NAME, config.alias); + object.add(ENTRY_NAME, config.entry); + return object.build(); + } + + @Override + public TestVaultEntryConfig adaptFromJson( + JsonObject object) + { + TestVaultEntryConfig config = null; + + if (object != null) + { + String alias = object.getString(ALIAS_NAME); + String entry = object.getString(ENTRY_NAME); + + config = new TestVaultEntryConfig(alias, entry); + } + + return config; + } +} diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfig.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfig.java index a763bb3b0c..e76a8cc79c 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfig.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfig.java @@ -21,7 +21,9 @@ public final class TestVaultOptionsConfig extends OptionsConfig { - public final String mode; + public final TestVaultEntryConfig key; + public final TestVaultEntryConfig signer; + public final TestVaultEntryConfig trust; public static TestVaultOptionsConfigBuilder builder() { @@ -35,8 +37,12 @@ public static TestVaultOptionsConfigBuilder builder( } TestVaultOptionsConfig( - String mode) + TestVaultEntryConfig key, + TestVaultEntryConfig signer, + TestVaultEntryConfig trust) { - this.mode = mode; + this.key = key; + this.signer = signer; + this.trust = trust; } } diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfigAdapter.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfigAdapter.java index 46eac521ba..0604c2956b 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfigAdapter.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfigAdapter.java @@ -24,7 +24,11 @@ public final class TestVaultOptionsConfigAdapter implements OptionsConfigAdapterSpi { - private static final String MODE_NAME = "mode"; + private static final String KEY_NAME = "key"; + private static final String SIGNER_NAME = "signer"; + private static final String TRUST_NAME = "trust"; + + private final TestVaultEntryConfigAdapter entry = new TestVaultEntryConfigAdapter(); @Override public Kind kind() @@ -40,13 +44,26 @@ public String type() @Override public JsonObject adaptToJson( - OptionsConfig options) + OptionsConfig adaptable) { - TestVaultOptionsConfig testOptions = (TestVaultOptionsConfig) options; + TestVaultOptionsConfig options = (TestVaultOptionsConfig) adaptable; JsonObjectBuilder object = Json.createObjectBuilder(); - object.add(MODE_NAME, testOptions.mode); + if (options.key != null) + { + object.add(KEY_NAME, entry.adaptToJson(options.key)); + } + + if (options.signer != null) + { + object.add(SIGNER_NAME, entry.adaptToJson(options.signer)); + } + + if (options.trust != null) + { + object.add(TRUST_NAME, entry.adaptToJson(options.trust)); + } return object.build(); } @@ -55,16 +72,32 @@ public JsonObject adaptToJson( public OptionsConfig adaptFromJson( JsonObject object) { - TestVaultOptionsConfigBuilder testOptions = TestVaultOptionsConfig.builder(); + TestVaultOptionsConfigBuilder options = TestVaultOptionsConfig.builder(); if (object != null) { - if (object.containsKey(MODE_NAME)) + if (object.containsKey(KEY_NAME)) + { + JsonObject key = object.getJsonObject(KEY_NAME); + TestVaultEntryConfig config = entry.adaptFromJson(key); + options.key(config.alias, config.entry); + } + + if (object.containsKey(SIGNER_NAME)) + { + JsonObject signer = object.getJsonObject(SIGNER_NAME); + TestVaultEntryConfig config = entry.adaptFromJson(signer); + options.signer(config.alias, config.entry); + } + + if (object.containsKey(TRUST_NAME)) { - testOptions.mode(object.getString(MODE_NAME)); + JsonObject trust = object.getJsonObject(TRUST_NAME); + TestVaultEntryConfig config = entry.adaptFromJson(trust); + options.trust(config.alias, config.entry); } } - return testOptions.build(); + return options.build(); } } diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfigBuilder.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfigBuilder.java index 35a2545b8e..c18d05ead3 100644 --- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfigBuilder.java +++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/vault/config/TestVaultOptionsConfigBuilder.java @@ -24,7 +24,9 @@ public final class TestVaultOptionsConfigBuilder extends ConfigBuilder mapper; - private String mode; + private TestVaultEntryConfig key; + private TestVaultEntryConfig signer; + private TestVaultEntryConfig trust; TestVaultOptionsConfigBuilder( Function mapper) @@ -39,16 +41,33 @@ protected Class> thisType() return (Class>) getClass(); } - public TestVaultOptionsConfigBuilder mode( - String mode) + public TestVaultOptionsConfigBuilder key( + String alias, + String entry) { - this.mode = mode; + key = new TestVaultEntryConfig(alias, entry); + return this; + } + + public TestVaultOptionsConfigBuilder signer( + String alias, + String entry) + { + signer = new TestVaultEntryConfig(alias, entry); + return this; + } + + public TestVaultOptionsConfigBuilder trust( + String alias, + String entry) + { + trust = new TestVaultEntryConfig(alias, entry); return this; } @Override public T build() { - return mapper.apply(new TestVaultOptionsConfig(mode)); + return mapper.apply(new TestVaultOptionsConfig(key, signer, trust)); } } diff --git a/runtime/exporter-otlp/pom.xml b/runtime/exporter-otlp/pom.xml index 50b3e73eda..e5c35e9732 100644 --- a/runtime/exporter-otlp/pom.xml +++ b/runtime/exporter-otlp/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/exporter-prometheus/pom.xml b/runtime/exporter-prometheus/pom.xml index 7feb03c1a9..d65b74dfb5 100644 --- a/runtime/exporter-prometheus/pom.xml +++ b/runtime/exporter-prometheus/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/exporter-prometheus/src/test/java/io/aklivity/zilla/runtime/exporter/prometheus/internal/printer/PrometheusMetricsPrinterTest.java b/runtime/exporter-prometheus/src/test/java/io/aklivity/zilla/runtime/exporter/prometheus/internal/printer/PrometheusMetricsPrinterTest.java index a15f4cfd4d..8114d6013b 100644 --- a/runtime/exporter-prometheus/src/test/java/io/aklivity/zilla/runtime/exporter/prometheus/internal/printer/PrometheusMetricsPrinterTest.java +++ b/runtime/exporter-prometheus/src/test/java/io/aklivity/zilla/runtime/exporter/prometheus/internal/printer/PrometheusMetricsPrinterTest.java @@ -14,8 +14,8 @@ */ package io.aklivity.zilla.runtime.exporter.prometheus.internal.printer; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/runtime/exporter-stdout/pom.xml b/runtime/exporter-stdout/pom.xml index c6945613c2..1b0e7ae07b 100644 --- a/runtime/exporter-stdout/pom.xml +++ b/runtime/exporter-stdout/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/filesystem-http/pom.xml b/runtime/filesystem-http/pom.xml index 1846fd7803..71fa587ce0 100644 --- a/runtime/filesystem-http/pom.xml +++ b/runtime/filesystem-http/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/filesystem-http/src/main/java/io/aklivity/zilla/runtime/filesystem/http/internal/HttpFileSystemProvider.java b/runtime/filesystem-http/src/main/java/io/aklivity/zilla/runtime/filesystem/http/internal/HttpFileSystemProvider.java index 14587c81f9..7f1038003e 100644 --- a/runtime/filesystem-http/src/main/java/io/aklivity/zilla/runtime/filesystem/http/internal/HttpFileSystemProvider.java +++ b/runtime/filesystem-http/src/main/java/io/aklivity/zilla/runtime/filesystem/http/internal/HttpFileSystemProvider.java @@ -52,7 +52,6 @@ public String getScheme() } @Override - @SuppressWarnings("resource") public FileSystem newFileSystem( URI uri, Map env) diff --git a/runtime/guard-jwt/pom.xml b/runtime/guard-jwt/pom.xml index 9ba34aad94..37a3849abf 100644 --- a/runtime/guard-jwt/pom.xml +++ b/runtime/guard-jwt/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/metrics-grpc/pom.xml b/runtime/metrics-grpc/pom.xml index 9f7dca27b4..17ff8f87e9 100644 --- a/runtime/metrics-grpc/pom.xml +++ b/runtime/metrics-grpc/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/metrics-http/pom.xml b/runtime/metrics-http/pom.xml index d6021f6d40..32ad5ec421 100644 --- a/runtime/metrics-http/pom.xml +++ b/runtime/metrics-http/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/metrics-stream/pom.xml b/runtime/metrics-stream/pom.xml index 5b1d535481..6592581d19 100644 --- a/runtime/metrics-stream/pom.xml +++ b/runtime/metrics-stream/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/model-avro/pom.xml b/runtime/model-avro/pom.xml index f85dec12bb..29f6c8c484 100644 --- a/runtime/model-avro/pom.xml +++ b/runtime/model-avro/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/model-avro/src/main/java/io/aklivity/zilla/runtime/model/avro/internal/AvroModelHandler.java b/runtime/model-avro/src/main/java/io/aklivity/zilla/runtime/model/avro/internal/AvroModelHandler.java index 9f171c8e8b..d0dcca7602 100644 --- a/runtime/model-avro/src/main/java/io/aklivity/zilla/runtime/model/avro/internal/AvroModelHandler.java +++ b/runtime/model-avro/src/main/java/io/aklivity/zilla/runtime/model/avro/internal/AvroModelHandler.java @@ -153,6 +153,8 @@ protected final boolean validate( progress = index; extractFields(buffer, index + length, schema); break; + default: + break; } } catch (IOException | AvroRuntimeException ex) @@ -395,6 +397,8 @@ private void extract( } progress += fixedSize; break; + default: + break; } } diff --git a/runtime/model-avro/src/main/java/io/aklivity/zilla/runtime/model/avro/internal/AvroWriteConverterHandler.java b/runtime/model-avro/src/main/java/io/aklivity/zilla/runtime/model/avro/internal/AvroWriteConverterHandler.java index d0aabfc388..68617a1ecb 100644 --- a/runtime/model-avro/src/main/java/io/aklivity/zilla/runtime/model/avro/internal/AvroWriteConverterHandler.java +++ b/runtime/model-avro/src/main/java/io/aklivity/zilla/runtime/model/avro/internal/AvroWriteConverterHandler.java @@ -113,6 +113,8 @@ record = reader.read(record, decoderFactory.jsonDecoder(schema, in)); } } break; + default: + break; } } catch (IOException | AvroRuntimeException ex) diff --git a/runtime/model-core/pom.xml b/runtime/model-core/pom.xml index 9173ea166b..0085b7d53a 100644 --- a/runtime/model-core/pom.xml +++ b/runtime/model-core/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/model-json/pom.xml b/runtime/model-json/pom.xml index 0714c4c483..54a6ec2f2c 100644 --- a/runtime/model-json/pom.xml +++ b/runtime/model-json/pom.xml @@ -6,7 +6,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/model-json/src/main/java/io/aklivity/zilla/runtime/model/json/internal/JsonModelHandler.java b/runtime/model-json/src/main/java/io/aklivity/zilla/runtime/model/json/internal/JsonModelHandler.java index 95dd285404..88119dde9c 100644 --- a/runtime/model-json/src/main/java/io/aklivity/zilla/runtime/model/json/internal/JsonModelHandler.java +++ b/runtime/model-json/src/main/java/io/aklivity/zilla/runtime/model/json/internal/JsonModelHandler.java @@ -132,6 +132,8 @@ protected final boolean validate( valueBytes = null; } break; + default: + break; } } } diff --git a/runtime/model-protobuf/pom.xml b/runtime/model-protobuf/pom.xml index aa08194efa..a04cdf181c 100644 --- a/runtime/model-protobuf/pom.xml +++ b/runtime/model-protobuf/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/model-protobuf/src/main/java/io/aklivity/zilla/runtime/model/protobuf/internal/ProtobufReadConverterHandler.java b/runtime/model-protobuf/src/main/java/io/aklivity/zilla/runtime/model/protobuf/internal/ProtobufReadConverterHandler.java index 3bdd7e336e..65de751711 100644 --- a/runtime/model-protobuf/src/main/java/io/aklivity/zilla/runtime/model/protobuf/internal/ProtobufReadConverterHandler.java +++ b/runtime/model-protobuf/src/main/java/io/aklivity/zilla/runtime/model/protobuf/internal/ProtobufReadConverterHandler.java @@ -336,6 +336,8 @@ private void extract( field.value.wrap(text, 0, length); } break; + default: + break; } } diff --git a/runtime/pom.xml b/runtime/pom.xml index e841fc140a..5078a53d5d 100644 --- a/runtime/pom.xml +++ b/runtime/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla zilla - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/resolver-env/pom.xml b/runtime/resolver-env/pom.xml index 1d2058e062..3226117e88 100644 --- a/runtime/resolver-env/pom.xml +++ b/runtime/resolver-env/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml diff --git a/runtime/vault-filesystem/pom.xml b/runtime/vault-filesystem/pom.xml index 632cd11525..d93a25ff3d 100644 --- a/runtime/vault-filesystem/pom.xml +++ b/runtime/vault-filesystem/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla runtime - 0.9.92 + 0.9.93 ../pom.xml @@ -24,7 +24,7 @@ - 0.89 + 0.84 0 diff --git a/runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultHandler.java b/runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultHandler.java index 80fc4d3fbc..eb5a4fdaf4 100644 --- a/runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultHandler.java +++ b/runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultHandler.java @@ -18,6 +18,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.KeyStore.Entry; import java.security.KeyStore.PrivateKeyEntry; @@ -27,10 +28,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Optional; +import java.util.function.BiFunction; import java.util.function.Function; -import java.util.function.Predicate; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; import javax.security.auth.x500.X500Principal; import org.agrona.LangUtil; @@ -41,211 +45,276 @@ public class FileSystemVaultHandler implements VaultHandler { - private static final String TYPE_DEFAULT = "pkcs12"; + private static final String STORE_TYPE_DEFAULT = "pkcs12"; - private final Function lookupKey; - private final Function lookupTrust; - private final Function lookupSigner; - private final Function, KeyStore.PrivateKeyEntry[]> lookupKeys; + private final Function, KeyManagerFactory> supplyKeys; + private final Function, KeyManagerFactory> supplySigners; + private final BiFunction, KeyStore, TrustManagerFactory> supplyTrust; public FileSystemVaultHandler( FileSystemOptionsConfig options, Function resolvePath) { - lookupKey = supplyLookupPrivateKeyEntry(resolvePath, options.keys); - lookupTrust = supplyLookupTrustedCertificateEntry(resolvePath, options.trust); - lookupSigner = supplyLookupTrustedCertificateEntry(resolvePath, options.signers); - lookupKeys = supplyLookupPrivateKeyEntries(resolvePath, options.keys); + FileSystemStoreInfo keys = supplyStoreInfo(resolvePath, options.keys); + supplyKeys = keys != null + ? keys::newKeysFactory + : aliases -> null; + + FileSystemStoreInfo signers = supplyStoreInfo(resolvePath, options.signers); + supplySigners = signers != null && keys != null + ? aliases -> newSignersFactory(aliases, signers, keys) + : aliases -> null; + + FileSystemStoreInfo trust = supplyStoreInfo(resolvePath, options.trust); + supplyTrust = (aliases, cacerts) -> newTrustFactory(trust, aliases, cacerts); } @Override - public KeyStore.PrivateKeyEntry key( - String alias) + public KeyManagerFactory initKeys( + List aliases) { - return lookupKey.apply(alias); + return supplyKeys.apply(aliases); } @Override - public KeyStore.TrustedCertificateEntry certificate( - String alias) + public TrustManagerFactory initTrust( + List aliases, + KeyStore cacerts) { - return lookupTrust.apply(alias); + return supplyTrust.apply(aliases, cacerts); } @Override - public PrivateKeyEntry[] keys( - String signer) + public KeyManagerFactory initSigners( + List aliases) { - KeyStore.PrivateKeyEntry[] keys = null; + return supplySigners.apply(aliases); + } + + private static FileSystemStoreInfo supplyStoreInfo( + Function resolvePath, + FileSystemStoreConfig config) + { + FileSystemStoreInfo info = null; - TrustedCertificateEntry trusted = lookupSigner.apply(signer); - if (trusted != null) + if (config != null) { - Certificate certificate = trusted.getTrustedCertificate(); - if (certificate instanceof X509Certificate) + try + { + Path storePath = resolvePath.apply(config.store); + try (InputStream input = Files.newInputStream(storePath)) + { + String type = Optional.ofNullable(config.type).orElse(STORE_TYPE_DEFAULT); + char[] password = Optional.ofNullable(config.password).map(String::toCharArray).orElse(null); + + KeyStore store = KeyStore.getInstance(type); + store.load(input, password); + + info = new FileSystemStoreInfo(store, password); + } + } + catch (Exception ex) { - X509Certificate x509 = (X509Certificate) certificate; - X500Principal issuer = x509.getSubjectX500Principal(); - keys = lookupKeys.apply(issuer::equals); + LangUtil.rethrowUnchecked(ex); } } - return keys; + return info; } - private static Function supplyLookupPrivateKeyEntry( - Function resolvePath, - FileSystemStoreConfig aliases) + private KeyManagerFactory newSignersFactory( + List aliases, + FileSystemStoreInfo signers, + FileSystemStoreInfo keys) { - return supplyLookupAlias(resolvePath, aliases, FileSystemVaultHandler::lookupPrivateKeyEntry); - } + KeyManagerFactory factory = null; - private static Function supplyLookupTrustedCertificateEntry( - Function resolvePath, - FileSystemStoreConfig aliases) - { - return supplyLookupAlias(resolvePath, aliases, FileSystemVaultHandler::lookupTrustedCertificateEntry); + if (aliases != null) + { + factory = keys.newKeysFactory(aliases.stream() + .map(signers::certificate) + .filter(Objects::nonNull) + .map(TrustedCertificateEntry::getTrustedCertificate) + .filter(X509Certificate.class::isInstance) + .map(X509Certificate.class::cast) + .map(X509Certificate::getSubjectX500Principal) + .map(keys::issuedKeys) + .filter(Objects::nonNull) + .flatMap(List::stream) + .toList()); + } + + return factory; } - private Function, KeyStore.PrivateKeyEntry[]> supplyLookupPrivateKeyEntries( - Function resolvePath, - FileSystemStoreConfig entries) + private TrustManagerFactory newTrustFactory( + FileSystemStoreInfo store, + List aliases, + KeyStore cacerts) { - Function, KeyStore.PrivateKeyEntry[]> lookupKeys = p -> null; + TrustManagerFactory factory = null; - if (entries != null) + try { - try + if (aliases != null || cacerts != null) { - Path storePath = resolvePath.apply(entries.store); - try (InputStream input = Files.newInputStream(storePath)) - { - String type = Optional.ofNullable(entries.type).orElse(TYPE_DEFAULT); - char[] password = Optional.ofNullable(entries.password).map(String::toCharArray).orElse(null); - - KeyStore store = KeyStore.getInstance(type); - store.load(input, password); - KeyStore.PasswordProtection protection = new KeyStore.PasswordProtection(password); - - List aliases = Collections.list(store.aliases()); + KeyStore trust = KeyStore.getInstance(STORE_TYPE_DEFAULT); + trust.load(null, null); - lookupKeys = matchSigner -> + if (aliases != null && store != null) + { + for (String alias : aliases) { - List keys = null; - - for (String alias : aliases) + TrustedCertificateEntry cert = store.certificate(alias); + if (cert != null) { - PrivateKeyEntry key = lookupPrivateKeyEntry(alias, store, protection); - Certificate certificate = key.getCertificate(); - if (key != null && - certificate instanceof X509Certificate && - matchSigner.test(((X509Certificate) certificate).getIssuerX500Principal())) - { - if (keys == null) - { - keys = new ArrayList<>(); - } - - keys.add(key); - } + trust.setEntry(alias, cert, null); } + } + } - return keys != null ? keys.toArray(KeyStore.PrivateKeyEntry[]::new) : null; - }; + if (cacerts != null) + { + for (String alias : aliases) + { + TrustedCertificateEntry cacert = FileSystemStoreInfo.certificate(cacerts, alias); + if (cacert != null) + { + trust.setEntry(alias, cacert, null); + } + } } + + factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + factory.init(trust); } - catch (Exception ex) - { - LangUtil.rethrowUnchecked(ex); - } + } + catch (Exception ex) + { + LangUtil.rethrowUnchecked(ex); } - return lookupKeys; + return factory; } - private static Function supplyLookupAlias( - Function resolvePath, - FileSystemStoreConfig aliases, - Lookup lookup) + private static final class FileSystemStoreInfo { - Function lookupAlias = a -> null; + private final KeyStore store; + private final KeyStore.PasswordProtection protection; - if (aliases != null) + private FileSystemStoreInfo( + KeyStore store, + char[] password) + { + this.store = store; + this.protection = password != null ? new KeyStore.PasswordProtection(password) : null; + } + + private KeyManagerFactory newKeysFactory( + List aliases) { + KeyManagerFactory factory = null; + try { - Path storePath = resolvePath.apply(aliases.store); - try (InputStream input = Files.newInputStream(storePath)) + if (aliases != null) { - String type = Optional.ofNullable(aliases.type).orElse(TYPE_DEFAULT); - char[] password = Optional.ofNullable(aliases.password).map(String::toCharArray).orElse(null); + KeyStore keys = KeyStore.getInstance(STORE_TYPE_DEFAULT); + keys.load(null, protection.getPassword()); - KeyStore store = KeyStore.getInstance(type); - store.load(input, password); - KeyStore.PasswordProtection protection = new KeyStore.PasswordProtection(password); + for (String alias : aliases) + { + PrivateKeyEntry key = key(alias); + if (key != null) + { + keys.setEntry(alias, key, protection); + } + } - lookupAlias = alias -> lookup.apply(alias, store, protection); + factory = KeyManagerFactory.getInstance("PKIX"); + factory.init(keys, protection.getPassword()); } } catch (Exception ex) { LangUtil.rethrowUnchecked(ex); } + + return factory; } - return lookupAlias; - } + private PrivateKeyEntry key( + String alias) + { + return entry(store, protection, alias, PrivateKeyEntry.class); + } - private static KeyStore.Entry lookupEntry( - String alias, - KeyStore store, - KeyStore.PasswordProtection protection) - { - KeyStore.Entry entry = null; + private TrustedCertificateEntry certificate( + String alias) + { + return entry(store, null, alias, TrustedCertificateEntry.class); + } - try + private static TrustedCertificateEntry certificate( + KeyStore store, + String alias) { - entry = store.getEntry(alias, protection); + return entry(store, null, alias, TrustedCertificateEntry.class); } - catch (Exception ex) + + private static T entry( + KeyStore store, + KeyStore.PasswordProtection protection, + String alias, + Class type) { + T typed = null; + try { - entry = store.getEntry(alias, null); + Entry entry = store.getEntry(alias, protection); + if (type.isInstance(entry)) + { + typed = type.cast(entry); + } } - catch (Exception e) + catch (GeneralSecurityException ex) { - e.addSuppressed(ex); - LangUtil.rethrowUnchecked(e); } - } - - return entry; - } - private static KeyStore.PrivateKeyEntry lookupPrivateKeyEntry( - String alias, - KeyStore store, - KeyStore.PasswordProtection protection) - { - Entry entry = lookupEntry(alias, store, protection); + return typed; + } - return entry instanceof KeyStore.PrivateKeyEntry ? (KeyStore.PrivateKeyEntry) entry : null; - } + private List issuedKeys( + X500Principal issuer) + { + List keys = null; - private static KeyStore.TrustedCertificateEntry lookupTrustedCertificateEntry( - String alias, - KeyStore store, - KeyStore.PasswordProtection protection) - { - Entry entry = lookupEntry(alias, store, protection); + try + { + for (String alias : Collections.list(store.aliases())) + { + PrivateKeyEntry key = key(alias); + Certificate certificate = key.getCertificate(); + if (key != null && + certificate instanceof X509Certificate && + issuer.equals(((X509Certificate) certificate).getIssuerX500Principal())) + { + if (keys == null) + { + keys = new ArrayList<>(); + } - return entry instanceof KeyStore.TrustedCertificateEntry ? (KeyStore.TrustedCertificateEntry) entry : null; - } + keys.add(alias); + } + } + } + catch (Exception ex) + { + // ignore + } - @FunctionalInterface - private interface Lookup - { - T apply(String alias, KeyStore store, KeyStore.PasswordProtection protection); + return keys; + } } } diff --git a/runtime/vault-filesystem/src/test/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultTest.java b/runtime/vault-filesystem/src/test/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultTest.java index 2f16fdcc88..e89864d3fe 100644 --- a/runtime/vault-filesystem/src/test/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultTest.java +++ b/runtime/vault-filesystem/src/test/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultTest.java @@ -16,15 +16,16 @@ package io.aklivity.zilla.runtime.vault.filesystem.internal; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import java.net.URI; import java.net.URL; import java.nio.file.Path; -import java.security.KeyStore.PrivateKeyEntry; -import java.security.KeyStore.TrustedCertificateEntry; +import java.util.List; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; import org.junit.Test; @@ -48,13 +49,13 @@ public void shouldResolveServer() throws Exception .build() .build(); - FileSystemVaultHandler vault = new FileSystemVaultHandler(options, FileSystemVaultTest::getResourcePath); + FileSystemVaultHandler vault = new FileSystemVaultHandler(options, FileSystemVaultTest::resourcePath); - PrivateKeyEntry key = vault.key("localhost"); - TrustedCertificateEntry certificate = vault.certificate("clientca"); + KeyManagerFactory keys = vault.initKeys(List.of("localhost")); + TrustManagerFactory trust = vault.initTrust(List.of("clientca"), null); - assertThat(key, not(nullValue())); - assertThat(certificate, not(nullValue())); + assertThat(keys, not(nullValue())); + assertThat(trust, not(nullValue())); } @Test @@ -73,18 +74,14 @@ public void shouldResolveClient() throws Exception .build() .build(); - FileSystemVaultHandler vault = new FileSystemVaultHandler(options, FileSystemVaultTest::getResourcePath); + FileSystemVaultHandler vault = new FileSystemVaultHandler(options, FileSystemVaultTest::resourcePath); - PrivateKeyEntry key = vault.key("client1"); - PrivateKeyEntry[] signedKeys = vault.keys("clientca"); + KeyManagerFactory keys = vault.initSigners(List.of("clientca")); - assertThat(key, not(nullValue())); - assertThat(signedKeys, not(nullValue())); - assertThat(signedKeys.length, equalTo(1)); - assertThat(signedKeys[0], not(nullValue())); + assertThat(keys, not(nullValue())); } - public static Path getResourcePath( + public static Path resourcePath( String resource) { URL url = FileSystemVaultTest.class.getResource(resource); diff --git a/specs/binding-asyncapi.spec/pom.xml b/specs/binding-asyncapi.spec/pom.xml index 3d6213ffb2..4ff3a9a121 100644 --- a/specs/binding-asyncapi.spec/pom.xml +++ b/specs/binding-asyncapi.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-echo.spec/pom.xml b/specs/binding-echo.spec/pom.xml index 41d6663cf7..6efff6d540 100644 --- a/specs/binding-echo.spec/pom.xml +++ b/specs/binding-echo.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-fan.spec/pom.xml b/specs/binding-fan.spec/pom.xml index 78c5b1b136..a5b864d5a7 100644 --- a/specs/binding-fan.spec/pom.xml +++ b/specs/binding-fan.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-filesystem.spec/pom.xml b/specs/binding-filesystem.spec/pom.xml index 5f5ee30721..7e012b68d1 100644 --- a/specs/binding-filesystem.spec/pom.xml +++ b/specs/binding-filesystem.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-grpc-kafka.spec/pom.xml b/specs/binding-grpc-kafka.spec/pom.xml index 09c11d0481..c0f9720932 100644 --- a/specs/binding-grpc-kafka.spec/pom.xml +++ b/specs/binding-grpc-kafka.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-grpc.spec/pom.xml b/specs/binding-grpc.spec/pom.xml index b195722ef7..75bd27c01e 100644 --- a/specs/binding-grpc.spec/pom.xml +++ b/specs/binding-grpc.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-http-filesystem.spec/pom.xml b/specs/binding-http-filesystem.spec/pom.xml index 040853af7f..60722aac6f 100644 --- a/specs/binding-http-filesystem.spec/pom.xml +++ b/specs/binding-http-filesystem.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-http-kafka.spec/pom.xml b/specs/binding-http-kafka.spec/pom.xml index 128970de4f..c47e1fb4b8 100644 --- a/specs/binding-http-kafka.spec/pom.xml +++ b/specs/binding-http-kafka.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-http.spec/pom.xml b/specs/binding-http.spec/pom.xml index 649499cfbc..539c5e4660 100644 --- a/specs/binding-http.spec/pom.xml +++ b/specs/binding-http.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.realm.yaml b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.with.route.header.overrides.yaml similarity index 54% rename from specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.realm.yaml rename to specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.with.route.header.overrides.yaml index 94ec4c8ba4..a51de67917 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.realm.yaml +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.with.route.header.overrides.yaml @@ -16,34 +16,24 @@ --- name: test -vaults: - server: - type: filesystem - options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated - trust: - store: stores/server/trust - type: pkcs12 - password: generated -realms: - - name: clients - type: tls bindings: net0: - type: tls + type: http kind: server - vault: server options: - keys: - - localhost - trust: - - clientca - realm: clients + versions: + - http/1.1 + overrides: + :authority: otherhost:8181 routes: - exit: app0 - allow: - realm: clients - identity: client#1 + when: + - headers: + :authority: localhost:8080 + :path: /v1/{id} + with: + headers: + overrides: + :authority: localhost:8081 + :path: /api/${params.id} + custom: value diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.with.route.header.overrides.yaml b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.with.route.header.overrides.yaml new file mode 100644 index 0000000000..f6784c63c2 --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.with.route.header.overrides.yaml @@ -0,0 +1,38 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +--- +name: test +bindings: + net0: + type: http + kind: server + options: + versions: + - h2 + overrides: + :authority: otherhost:8181 + :path: /api/path + routes: + - exit: app0 + when: + - headers: + :authority: localhost:8080 + with: + headers: + overrides: + :authority: localhost:8081 + custom: value diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/schema/http.schema.patch.json b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/schema/http.schema.patch.json index 62f6124fe5..3976bd34a3 100644 --- a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/schema/http.schema.patch.json +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/schema/http.schema.patch.json @@ -369,7 +369,31 @@ "additionalProperties": false } }, - "with": false + "with": + { + "properties": + { + "headers": + { + "title": "Headers", + "type": "object", + "properties": + { + "overrides": + { + "title": "Overrides", + "type": "object", + "additionalProperties" : + { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } } } } diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/connection.management/request.with.route.header.overrides/client.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/connection.management/request.with.route.header.overrides/client.rpt new file mode 100644 index 0000000000..f3cd822fa1 --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/connection.management/request.with.route.header.overrides/client.rpt @@ -0,0 +1,39 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + +write zilla:begin.ext ${http:beginEx() + .typeId(zilla:id("http")) + .header(":scheme", "http") + .header(":method", "GET") + .header(":path", "/api/path") + .header(":authority", "localhost:8081") + .header("custom", "value") + .build()} +connected + +write close + +read zilla:begin.ext ${http:beginEx() + .typeId(zilla:id("http")) + .header(":status", "200") + .header("content-length", "0") + .build()} + +read closed diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/connection.management/request.with.route.header.overrides/server.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/connection.management/request.with.route.header.overrides/server.rpt new file mode 100644 index 0000000000..75d69f34b8 --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/connection.management/request.with.route.header.overrides/server.rpt @@ -0,0 +1,41 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +accept "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" +accepted + +read zilla:begin.ext ${http:beginEx() + .typeId(zilla:id("http")) + .header(":scheme", "http") + .header(":method", "GET") + .header(":path", "/api/path") + .header(":authority", "localhost:8081") + .header("custom", "value") + .build()} +connected + +read closed + +write zilla:begin.ext ${http:beginEx() + .typeId(zilla:id("http")) + .header(":status", "200") + .header("content-length", "0") + .build()} +write flush + +write close diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/client.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/client.rpt new file mode 100644 index 0000000000..02f2bd6704 --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/client.rpt @@ -0,0 +1,38 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + + +write zilla:begin.ext ${http:beginEx() + .typeId(zilla:id("http")) + .header(":method", "GET") + .header(":scheme", "http") + .header(":path", "/api/path") + .header(":authority", "localhost:8081") + .header("custom", "value") + .build()} +connected + +read zilla:begin.ext ${http:beginEx() + .typeId(zilla:id("http")) + .header(":status", "200") + .header("content-length", "0") + .build()} + +read closed diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/server.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/server.rpt new file mode 100644 index 0000000000..a0c65d666c --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/server.rpt @@ -0,0 +1,39 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +accept "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" +accepted + +read zilla:begin.ext ${http:beginEx() + .typeId(zilla:id("http")) + .header(":method", "GET") + .header(":scheme", "http") + .header(":path", "/api/path") + .header(":authority", "localhost:8081") + .header("custom", "value") + .build()} +connected + +write zilla:begin.ext ${http:beginEx() + .typeId(zilla:id("http")) + .header(":status", "200") + .header("content-length", "0") + .build()} +write flush + +write close diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/connection.management/request.with.route.header.overrides/client.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/connection.management/request.with.route.header.overrides/client.rpt new file mode 100644 index 0000000000..6cd20a195d --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/connection.management/request.with.route.header.overrides/client.rpt @@ -0,0 +1,28 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +connect "zilla://streams/net0" + option zilla:window 8192 + option zilla:transmission "duplex" +connected + +write "GET /v1/path HTTP/1.1" "\r\n" +write "Host: localhost:8080" "\r\n" +write "\r\n" + +read "HTTP/1.1 200 OK\r\n" +read "Content-Length: 0\r\n" +read "\r\n" diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/connection.management/request.with.route.header.overrides/server.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/connection.management/request.with.route.header.overrides/server.rpt new file mode 100644 index 0000000000..3cf8c37041 --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/connection.management/request.with.route.header.overrides/server.rpt @@ -0,0 +1,29 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +accept "zilla://streams/net0" + option zilla:window 8192 + option zilla:transmission "duplex" +accepted +connected + +read "GET /v1/path HTTP/1.1" "\r\n" +read "Host: localhost:8080" "\r\n" +read "\r\n" + +write "HTTP/1.1 200 OK\r\n" +write "Content-Length: 0\r\n" +write "\r\n" diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/client.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/client.rpt new file mode 100644 index 0000000000..5811f2391e --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/client.rpt @@ -0,0 +1,73 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +connect "zilla://streams/net0" + option zilla:window 8192 + option zilla:transmission "duplex" +connected + +# client connection preface +write "PRI * HTTP/2.0\r\n" + "\r\n" + "SM\r\n" + "\r\n" +write flush + +# server connection preface - SETTINGS frame +read [0x00 0x00 0x12] # length = 18 + [0x04] # HTTP2 SETTINGS frame + [0x00] # flags = 0x00 + [0x00 0x00 0x00 0x00] # stream_id = 0 + [0x00 0x03 0x00 0x00 0x00 0x64] # SETTINGS_MAX_CONCURRENT_STREAMS(0x03) = 100 + [0x00 0x04 0x00 0x00 0x00 0x00] # SETTINGS_INITIAL_WINDOW_SIZE(0x04) = 0 + [0x00 0x06 0x00 0x00 0x20 0x00] # SETTINGS_MAX_HEADER_LIST_SIZE(0x06) = 8192 + +write [0x00 0x00 0x00] # length = 0 + [0x04] # HTTP2 SETTINGS frame + [0x01] # ACK + [0x00 0x00 0x00 0x00] # stream_id = 0 +write flush + +write [0x00 0x00 0x0c] # length = 12 + [0x04] # HTTP2 SETTINGS frame + [0x00] # flags = 0x00 + [0x00 0x00 0x00 0x00] # stream_id = 0 + [0x00 0x03 0x00 0x00 0x00 0x64] # SETTINGS_MAX_CONCURRENT_STREAMS(0x03) = 100 + [0x00 0x04 0x00 0x00 0xff 0xff] # SETTINGS_INITIAL_WINDOW_SIZE(0x04) = 65535 +write flush + +write [0x00 0x00 0x13] # length = 19 + [0x01] # HEADERS frame + [0x05] # END_HEADERS | END_STREAM + [0x00 0x00 0x00 0x01] # stream_id = 1 + [0x82] # :method: GET + [0x86] # :scheme: http + [0x84] # :path: / + [0x01] [0x0e] "localhost:8080" # :authority: localhost:8080 +write flush + +read [0x00 0x00 0x00] # length = 0 + [0x04] # HTTP2 SETTINGS frame + [0x01] # ACK + [0x00 0x00 0x00 0x00] # stream_id = 0 + +read [0x00 0x00 0x05] # length + [0x01] # HTTP2 HEADERS frame + [0x05] # END_HEADERS + [0x00 0x00 0x00 0x01] # stream_id=1 + [0x88] # :status: 200 + [0x0f 0x0d] [0x01] "0" # content-length + diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/server.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/server.rpt new file mode 100644 index 0000000000..50f92937f9 --- /dev/null +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/connection.management/http.get.exchange.with.route.header.overrides/server.rpt @@ -0,0 +1,72 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +accept "zilla://streams/net0" + option zilla:window 8192 + option zilla:transmission "duplex" +accepted +connected + +# server connection preface - SETTINGS frame +write [0x00 0x00 0x12] # length = 18 + [0x04] # HTTP2 SETTINGS frame + [0x00] # flags = 0x00 + [0x00 0x00 0x00 0x00] # stream_id = 0 + [0x00 0x03 0x00 0x00 0x00 0x64] # SETTINGS_MAX_CONCURRENT_STREAMS(0x03) = 100 + [0x00 0x04 0x00 0x00 0x00 0x00] # SETTINGS_INITIAL_WINDOW_SIZE(0x03) = 0 + [0x00 0x06 0x00 0x00 0x20 0x00] # SETTINGS_MAX_HEADER_LIST_SIZE(0x06) = 8192 +write flush + +# client connection preface +read "PRI * HTTP/2.0\r\n" + "\r\n" + "SM\r\n" + "\r\n" + +read [0x00 0x00 0x0c] # length = 12 + [0x04] # HTTP2 SETTINGS frame + [0x00] # flags = 0x00 + [0x00 0x00 0x00 0x00] # stream_id = 0 + [0x00 0x03 0x00 0x00 0x00 0x64] # SETTINGS_MAX_CONCURRENT_STREAMS(0x03) = 100 + [0x00 0x04 0x00 0x00 0xff 0xff] # SETTINGS_INITIAL_WINDOW_SIZE(0x04) = 65535 + +write [0x00 0x00 0x00] # length = 0 + [0x04] # HTTP2 SETTINGS frame + [0x01] # ACK + [0x00 0x00 0x00 0x00] # stream_id = 0 +write flush + +read [0x00 0x00 0x13] # length = 19 + [0x01] # HEADERS frame + [0x05] # END_HEADERS | END_STREAM + [0x00 0x00 0x00 0x01] # stream_id = 1 + [0x82] # :method: GET + [0x86] # :scheme: http + [0x84] # :path: / + [0x01] [0x0e] "localhost:8080" # :authority: localhost:8080 + +read [0x00 0x00 0x00] # length = 0 + [0x04] # HTTP2 SETTINGS frame + [0x01] # ACK + [0x00 0x00 0x00 0x00] # stream_id = 0 + +write [0x00 0x00 0x05] # length + [0x01] # HTTP2 HEADERS frame + [0x05] # END_HEADERS + [0x00 0x00 0x00 0x01] # stream_id=1 + [0x88] # :status: 200 + [0x0f 0x0d] [0x01] "0" # content-length +write flush diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/starting/upgrade.h2c.with.no.settings/client.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/starting/upgrade.h2c.with.no.settings/client.rpt index 0fd4d64948..d6cb5c9b1b 100644 --- a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/starting/upgrade.h2c.with.no.settings/client.rpt +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/starting/upgrade.h2c.with.no.settings/client.rpt @@ -22,14 +22,16 @@ connected write "POST / HTTP/1.1\r\n" "Host: localhost:8080\r\n" "Connection: Upgrade, HTTP2-Settings\r\n" - "Upgrade: h2c\r\n" "Content-Type: text/plain;charset=UTF-8\r\n" "Content-Length: 12\r\n" + "Upgrade: h2c\r\n" "\r\n" write "Hello, world" read "HTTP/1.1 200 OK\r\n" + "Server: CERN/3.0 libwww/2.17\r\n" + "Date: Wed, 01 Feb 2017 19:12:46 GMT\r\n" "Content-Type: text/plain;charset=UTF-8\r\n" "Content-Length: 17\r\n" "\r\n" diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/starting/upgrade.h2c.with.no.settings/server.rpt b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/starting/upgrade.h2c.with.no.settings/server.rpt index 8b65fd60ee..e44eaf020e 100644 --- a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/starting/upgrade.h2c.with.no.settings/server.rpt +++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/starting/upgrade.h2c.with.no.settings/server.rpt @@ -23,14 +23,16 @@ connected read "POST / HTTP/1.1\r\n" "Host: localhost:8080\r\n" "Connection: Upgrade, HTTP2-Settings\r\n" - "Upgrade: h2c\r\n" "Content-Type: text/plain;charset=UTF-8\r\n" "Content-Length: 12\r\n" + "Upgrade: h2c\r\n" "\r\n" read "Hello, world" write "HTTP/1.1 200 OK\r\n" + "Server: CERN/3.0 libwww/2.17\r\n" + "Date: Wed, 01 Feb 2017 19:12:46 GMT\r\n" "Content-Type: text/plain;charset=UTF-8\r\n" "Content-Length: 17\r\n" "\r\n" diff --git a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/config/SchemaTest.java b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/config/SchemaTest.java index 5299abbd37..7c96b584c8 100644 --- a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/config/SchemaTest.java +++ b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/config/SchemaTest.java @@ -83,6 +83,14 @@ public void shouldValidateHttp11ServerOverride() assertThat(config, not(nullValue())); } + @Test + public void shouldValidateHttp11ServerWithRouteHeaderOverrides() + { + JsonObject config = schema.validate("v1.1/server.with.route.header.overrides.yaml"); + + assertThat(config, not(nullValue())); + } + @Test public void shouldValidateHttp11ServerAccessControlCrossOrigin() { @@ -211,6 +219,14 @@ public void shouldValidateHttp2ServerOverride() assertThat(config, not(nullValue())); } + @Test + public void shouldValidateHttp2ServerWithRouteHeaderOverrides() + { + JsonObject config = schema.validate("v2/server.with.route.header.overrides.yaml"); + + assertThat(config, not(nullValue())); + } + @Test public void shouldValidateHttp2ServerAccessControlCrossOrigin() { diff --git a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/ConnectionManagementIT.java b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/ConnectionManagementIT.java index 719b1c6abc..562e5f8999 100644 --- a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/ConnectionManagementIT.java +++ b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/ConnectionManagementIT.java @@ -303,6 +303,15 @@ public void shouldProxyRequestWithHeaderOverride() throws Exception k3po.finish(); } + @Test + @Specification({ + "${app}/request.with.route.header.overrides/client", + "${app}/request.with.route.header.overrides/server" }) + public void shouldProxyRequestWithRouteHeaderOverrides() throws Exception + { + k3po.finish(); + } + @Test @Specification({ "${app}/request.authority.with.no.port/client", diff --git a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/ConnectionManagementIT.java b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/ConnectionManagementIT.java index cdf576e48a..0f8335a63b 100644 --- a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/ConnectionManagementIT.java +++ b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/application/rfc7540/ConnectionManagementIT.java @@ -59,6 +59,16 @@ public void shouldSendRequestWithHeaderOverride() throws Exception k3po.finish(); } + @Test + @Specification({ + "${app}/http.get.exchange.with.route.header.overrides/client", + "${app}/http.get.exchange.with.route.header.overrides/server" + }) + public void shouldSendRequestWithRouteHeaderOverrides() throws Exception + { + k3po.finish(); + } + @Test @Specification({ "${app}/http.post.exchange/client", diff --git a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/ConnectionManagementIT.java b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/ConnectionManagementIT.java index b6ddc185b6..fbc8c34049 100644 --- a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/ConnectionManagementIT.java +++ b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/ConnectionManagementIT.java @@ -65,6 +65,15 @@ public void shouldSendRequestWithHeaderOverride() throws Exception k3po.finish(); } + @Test + @Specification({ + "${net}/request.with.route.header.overrides/client", + "${net}/request.with.route.header.overrides/server" }) + public void shouldSendRequestWithRouteHeaderOverrides() throws Exception + { + k3po.finish(); + } + @Test @Specification({ "${net}response.with.connection.close/client", diff --git a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/ConnectionManagementIT.java b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/ConnectionManagementIT.java index 0e644a842a..a21a5e3967 100644 --- a/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/ConnectionManagementIT.java +++ b/specs/binding-http.spec/src/test/java/io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/ConnectionManagementIT.java @@ -70,6 +70,17 @@ public void shouldSendRequestWithHeaderOverride() throws Exception k3po.finish(); } + @Ignore + @Test + @Specification({ + "${net}/http.get.exchange.with.route.header.overrides/client", + "${net}/http.get.exchange.with.route.header.overrides/server" + }) + public void shouldSendRequestWithRouteHeaderOverrides() throws Exception + { + k3po.finish(); + } + @Test @Specification({ "${net}/http.unknown.authority/client", diff --git a/specs/binding-kafka-grpc.spec/pom.xml b/specs/binding-kafka-grpc.spec/pom.xml index f82ba50e5e..244544f375 100644 --- a/specs/binding-kafka-grpc.spec/pom.xml +++ b/specs/binding-kafka-grpc.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-kafka.spec/pom.xml b/specs/binding-kafka.spec/pom.xml index dfa3737154..0ff26f7688 100644 --- a/specs/binding-kafka.spec/pom.xml +++ b/specs/binding-kafka.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-kafka.spec/src/main/java/io/aklivity/zilla/specs/binding/kafka/internal/KafkaFunctions.java b/specs/binding-kafka.spec/src/main/java/io/aklivity/zilla/specs/binding/kafka/internal/KafkaFunctions.java index 3b63f9ed53..f719992155 100644 --- a/specs/binding-kafka.spec/src/main/java/io/aklivity/zilla/specs/binding/kafka/internal/KafkaFunctions.java +++ b/specs/binding-kafka.spec/src/main/java/io/aklivity/zilla/specs/binding/kafka/internal/KafkaFunctions.java @@ -36,7 +36,6 @@ import io.aklivity.zilla.specs.binding.kafka.internal.types.KafkaAckMode; import io.aklivity.zilla.specs.binding.kafka.internal.types.KafkaCapabilities; import io.aklivity.zilla.specs.binding.kafka.internal.types.KafkaConditionFW; -import io.aklivity.zilla.specs.binding.kafka.internal.types.KafkaConfigFW; import io.aklivity.zilla.specs.binding.kafka.internal.types.KafkaDeltaFW; import io.aklivity.zilla.specs.binding.kafka.internal.types.KafkaDeltaType; import io.aklivity.zilla.specs.binding.kafka.internal.types.KafkaDeltaTypeFW; @@ -655,7 +654,7 @@ public static final class KafkaMemberAssignmentsBuilder private final MutableDirectBuffer writeBuffer = new UnsafeBuffer(new byte[1024 * 8]); private final Array32FW.Builder memberAssignmentsRW = - new Array32FW.Builder(new MemberAssignmentFW.Builder(), new MemberAssignmentFW()); + new Array32FW.Builder<>(new MemberAssignmentFW.Builder(), new MemberAssignmentFW()); public KafkaMemberAssignmentsBuilder() { @@ -683,7 +682,7 @@ class KafkaMemberBuilder private final MemberAssignmentFW.Builder assignmentRW = new MemberAssignmentFW.Builder(); private final MutableDirectBuffer topicAssignmentBuffer = new UnsafeBuffer(new byte[1024 * 8]); private final Array32FW.Builder topicAssignmentsRW = - new Array32FW.Builder(new TopicAssignmentFW.Builder(), new TopicAssignmentFW()); + new Array32FW.Builder<>(new TopicAssignmentFW.Builder(), new TopicAssignmentFW()); KafkaMemberBuilder( String memberId) @@ -791,7 +790,7 @@ public static final class KafkaTopicAssignmentsBuilder private final MutableDirectBuffer writeBuffer = new UnsafeBuffer(new byte[1024 * 8]); private final Array32FW.Builder topicAssignments = - new Array32FW.Builder(new TopicAssignmentFW.Builder(), new TopicAssignmentFW()); + new Array32FW.Builder<>(new TopicAssignmentFW.Builder(), new TopicAssignmentFW()); public KafkaTopicAssignmentsBuilder() { @@ -2460,6 +2459,13 @@ public KafkaProduceDataExBuilder sequence( return this; } + public KafkaProduceDataExBuilder crc32c( + long crc32c) + { + produceDataExRW.crc32c(crc32c); + return this; + } + public KafkaProduceDataExBuilder ackMode( String ackMode) { @@ -3586,6 +3592,7 @@ public final class KafkaProduceDataExMatcherBuilder private Long timestamp; private Long producerId; private Short producerEpoch; + private Integer crc32c; private Integer sequence; private KafkaAckMode ackMode; private KafkaKeyFW.Builder keyRW; @@ -3609,6 +3616,13 @@ public KafkaProduceDataExMatcherBuilder timestamp( return this; } + public KafkaProduceDataExMatcherBuilder crc32c( + int crc32c) + { + this.crc32c = crc32c; + return this; + } + public KafkaProduceDataExMatcherBuilder producerId( long producerId) { @@ -3701,7 +3715,10 @@ private boolean match( final KafkaProduceDataExFW produceDataEx = dataEx.produce(); return matchDeferred(produceDataEx) && matchTimestamp(produceDataEx) && + matchProducerId(produceDataEx) && + matchProducerEpoch(produceDataEx) && matchSequence(produceDataEx) && + matchCrc32c(produceDataEx) && matchAckMode(produceDataEx) && matchKey(produceDataEx) && matchHeaders(produceDataEx); @@ -3731,6 +3748,12 @@ private boolean matchProducerEpoch( return producerEpoch == null || producerEpoch == produceDataEx.producerEpoch(); } + private boolean matchCrc32c( + final KafkaProduceDataExFW produceDataEx) + { + return crc32c == null || crc32c == produceDataEx.crc32c(); + } + private boolean matchSequence( final KafkaProduceDataExFW produceDataEx) { @@ -3785,14 +3808,11 @@ public final class KafkaMergedFetchDataExMatcherBuilder { private Integer deferred; private Long timestamp; - private Long producerId; - private Short producerEpoch; private Long filters; private KafkaOffsetFW.Builder partitionRW; private Array32FW.Builder progressRW; private KafkaDeltaFW.Builder deltaRW; private KafkaKeyFW.Builder keyRW; - private KafkaKeyFW.Builder hashKeyRW; private Array32FW.Builder headersRW; private KafkaMergedFetchDataExMatcherBuilder() @@ -3813,20 +3833,6 @@ public KafkaMergedFetchDataExMatcherBuilder timestamp( return this; } - public KafkaMergedFetchDataExMatcherBuilder producerId( - long producerId) - { - this.producerId = producerId; - return this; - } - - public KafkaMergedFetchDataExMatcherBuilder producerEpoch( - short producerEpoch) - { - this.producerEpoch = producerEpoch; - return this; - } - public KafkaMergedFetchDataExMatcherBuilder filters( long filters) { @@ -4135,7 +4141,6 @@ public final class KafkaMergedProduceDataExMatcherBuilder private Long timestamp; private Long producerId; private Short producerEpoch; - private Long filters; private KafkaOffsetFW.Builder partitionRW; private Array32FW.Builder progressRW; private KafkaDeltaFW.Builder deltaRW; @@ -4175,13 +4180,6 @@ public KafkaMergedProduceDataExMatcherBuilder producerEpoch( return this; } - public KafkaMergedProduceDataExMatcherBuilder filters( - long filters) - { - this.filters = filters; - return this; - } - public KafkaMergedProduceDataExMatcherBuilder partition( int partitionId, long offset) @@ -5540,7 +5538,6 @@ private boolean matchEvaluation( public final class KafkaProduceBeginExMatcherBuilder { private String8FW transaction; - private Long producerId; private String16FW topic; private KafkaOffsetFW.Builder partitionRW; @@ -5555,13 +5552,6 @@ public KafkaProduceBeginExMatcherBuilder transaction( return this; } - public KafkaProduceBeginExMatcherBuilder producerId( - long producerId) - { - this.producerId = producerId; - return this; - } - public KafkaProduceBeginExMatcherBuilder topic( String topic) { @@ -5833,7 +5823,6 @@ public final class KafkaMergedBeginExMatcherBuilder private KafkaEvaluation evaluation; private KafkaAckMode ackMode; private Array32FW.Builder filtersRW; - private Array32FW.Builder configsFW; private KafkaMergedBeginExMatcherBuilder() { diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.empty.crc/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.empty.crc/client.rpt new file mode 100644 index 0000000000..14775554de --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.empty.crc/client.rpt @@ -0,0 +1,84 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property deltaMillis 0L + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +connected + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +read zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .meta() + .partition(0, 177) + .build() + .build()} + +read notify ROUTED_BROKER_CLIENT + +connect await ROUTED_BROKER_CLIENT + "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + option zilla:affinity 0xb1 + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +connected + + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + + +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .timestamp(1724846895864) + .ackMode("LEADER_ONLY") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write zilla:data.empty +write flush diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.empty.crc/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.empty.crc/server.rpt new file mode 100644 index 0000000000..3f653d0d05 --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.empty.crc/server.rpt @@ -0,0 +1,80 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "half-duplex" + +accepted + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +connected + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} +write flush + +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .meta() + .partition(0, 177) + .build() + .build()} +write flush + +accepted + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +connected + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .timestamp(1724846895864) + .ackMode("LEADER_ONLY") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read zilla:data.empty + diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.header/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.header/client.rpt index 56698e1436..2bb639d4c8 100644 --- a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.header/client.rpt +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.header/client.rpt @@ -73,7 +73,7 @@ read zilla:begin.ext ${kafka:beginEx() write zilla:data.ext ${kafka:dataEx() .typeId(zilla:id("kafka")) .produce() - .timestamp(newTimestamp) + .timestamp(1716424650323) .header("header1", "value1") .build() .build()} diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.null.crc/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.null.crc/client.rpt new file mode 100644 index 0000000000..ef9750d660 --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.null.crc/client.rpt @@ -0,0 +1,83 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property deltaMillis 0L + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +connected + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +read zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .meta() + .partition(0, 177) + .build() + .build()} + +read notify ROUTED_BROKER_CLIENT + +connect await ROUTED_BROKER_CLIENT + "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + option zilla:affinity 0xb1 + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +connected + + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + + +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .timestamp(1724846895864) + .ackMode("LEADER_ONLY") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write flush diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.null.crc/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.null.crc/server.rpt new file mode 100644 index 0000000000..9f9d614f8a --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.null.crc/server.rpt @@ -0,0 +1,80 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "half-duplex" + +accepted + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +connected + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} +write flush + +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .meta() + .partition(0, 177) + .build() + .build()} +write flush + +accepted + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +connected + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .timestamp(1724846895864) + .ackMode("LEADER_ONLY") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read zilla:data.null + diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.100k/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.100k/client.rpt index cd5237ac4a..36eb3ab34c 100644 --- a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.100k/client.rpt +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.100k/client.rpt @@ -74,7 +74,7 @@ write zilla:data.ext ${kafka:dataEx() .typeId(zilla:id("kafka")) .produce() .deferred(102400 - 8192 + 512 + 512) - .timestamp(newTimestamp) + .timestamp(1716424650323) .build() .build()} write zilla:data.ext ${kafka:dataEx() diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.repeated.fragmented/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.repeated.fragmented/client.rpt new file mode 100644 index 0000000000..1cd72dba27 --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.repeated.fragmented/client.rpt @@ -0,0 +1,117 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property deltaMillis 0L +property newTimestamp ${kafka:timestamp() + deltaMillis} + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +connected + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +read zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .meta() + .partition(0, 177) + .build() + .build()} + +read notify ROUTED_BROKER_CLIENT + +connect await ROUTED_BROKER_CLIENT + "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + option zilla:affinity 0xb1 + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(0) + .build() + .build()} + +connected + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(0) + .build() + .build()} + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(6) + .timestamp(newTimestamp) + .sequence(0) + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .timestamp(newTimestamp) + .sequence(0) + .build() + .build()} +write " world" +write flush + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(6) + .timestamp(newTimestamp) + .sequence(1) + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .timestamp(newTimestamp) + .sequence(1) + .build() + .build()} +write " world" +write flush diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.repeated.fragmented/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.repeated.fragmented/server.rpt new file mode 100644 index 0000000000..51950be58e --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/message.value.repeated.fragmented/server.rpt @@ -0,0 +1,82 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "half-duplex" + +accepted + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +connected + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} +write flush + +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .meta() + .partition(0, 177) + .build() + .build()} +write flush + +accepted + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(0) + .build() + .build()} + +connected + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(0) + .build() + .build()} + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .build() + .build()} +read "Hello, world" + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .build() + .build()} +read "Hello, world" diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/messages.fragmented.crc/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/messages.fragmented.crc/client.rpt new file mode 100644 index 0000000000..94c2ee5b9e --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/messages.fragmented.crc/client.rpt @@ -0,0 +1,273 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property deltaMillis 0L + +connect "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +connected + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +read zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .meta() + .partition(0, 177) + .build() + .build()} + +read notify ROUTED_BROKER_CLIENT + +connect await ROUTED_BROKER_CLIENT + "zilla://streams/app0" + option zilla:window 8192 + option zilla:transmission "half-duplex" + option zilla:affinity 0xb1 + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +connected + + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .crc32c(1297420392) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +write " World!" +write flush + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .crc32c(1297420392) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +write " World!" +write flush + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .crc32c(1297420392) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +write " World!" +write flush + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .crc32c(1297420392) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +write " World!" +write flush + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .crc32c(1297420392) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +write " World!" +write flush + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .crc32c(1297420392) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +write " World!" +write flush + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .crc32c(1297420392) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +write " World!" +write flush + + +write option zilla:flags "init" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .crc32c(1297420392) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +write "Hello," +write flush + +write option zilla:flags "fin" +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +write " World!" +write flush diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/messages.fragmented.crc/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/messages.fragmented.crc/server.rpt new file mode 100644 index 0000000000..d0b35da7b5 --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/application/produce/messages.fragmented.crc/server.rpt @@ -0,0 +1,228 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property serverAddress "zilla://streams/app0" + +accept ${serverAddress} + option zilla:window 8192 + option zilla:transmission "half-duplex" + +accepted + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} + +connected + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .meta() + .topic("test") + .build() + .build()} +write flush + +write zilla:data.ext ${kafka:dataEx() + .typeId(zilla:id("kafka")) + .meta() + .partition(0, 177) + .build() + .build()} +write flush + +accepted + +read zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +connected + +write zilla:begin.ext ${kafka:beginEx() + .typeId(zilla:id("kafka")) + .produce() + .topic("test") + .partition(2) + .build() + .build()} + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read "Hello," + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +read " World!" + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read "Hello," + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +read " World!" + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read "Hello," + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +read " World!" + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read "Hello," + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +read " World!" + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read "Hello," + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +read " World!" + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read "Hello," + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +read " World!" + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read "Hello," + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +read " World!" + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .deferred(7) + .ackMode("NONE") + .key("key1") + .header("header1", "value1") + .build() + .build()} +read "Hello," + +read zilla:data.ext ${kafka:matchDataEx() + .typeId(zilla:id("kafka")) + .produce() + .ackMode("IN_SYNC_REPLICAS") + .header("header1", "value1") + .build() + .build()} +read " World!" \ No newline at end of file diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.empty.crc/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.empty.crc/client.rpt new file mode 100644 index 0000000000..95914de62e --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.empty.crc/client.rpt @@ -0,0 +1,132 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property networkConnectWindow 8192 + +property newRequestId ${kafka:newRequestId()} +property produceWaitMax 500 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 26 # size + 3s # metadata + 5s # v5 + ${newRequestId} + 5s "zilla" # client id + 1 # topics + 4s "test" # "test" topic + [0x00] # allow_auto_topic_creation + +read 97 # size + ${newRequestId} + [0..4] + 1 # brokers + 0xb1 # broker id + 19s "broker1.example.com" # host name + 9092 # port + -1s # no rack + 9s "cluster 1" # cluster id + 1 # controller id + 1 # topics + 0s # no error + 4s "test" # "test" topic + [0x00] # not internal + 1 # partitions + 0s # no error + 0 # partition + 0xb1 # leader + 0 # no replicas + -1 # no in-sync replicas + 0 # offline replicas + +read notify ROUTED_BROKER_SERVER + +connect await ROUTED_BROKER_SERVER + "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +write zilla:begin.ext ${proxy:beginEx() + .typeId(zilla:id("proxy")) + .addressInet() + .protocol("stream") + .source("0.0.0.0") + .destination("broker1.example.com") + .sourcePort(0) + .destinationPort(9092) + .build() + .info() + .authority("broker1.example.com") + .build() + .build()} + +connected + +write 132 # size + 0s # produce + 3s # v3 + ${newRequestId} + 5s "zilla" # client id + -1s # transactional id + 0s # acks + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 # partition + 87 # record set size + 0L # first offset + 75 # length + -1 + [0x02] + 1548293632 + 0s + 0 # last offset delta + 1724846895864L # first timestamp + 1724846895864L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(25)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + [0x00] + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 44 + ${newRequestId} + 1 # topics + 4s "test" + 1 # partitions + 2 # partition + 0s # no error + 20L # base offset + [0..8] # log append time + [0..4] # throttle ms diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.empty.crc/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.empty.crc/server.rpt new file mode 100644 index 0000000000..b0c17dc1d9 --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.empty.crc/server.rpt @@ -0,0 +1,125 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 26 # size + 3s # metadata + 5s # v5 + (int:requestId) + 5s "zilla" # client id + 1 # topics + 4s "test" # "test" topic + [0x00] # allow_auto_topic_creation + +write 97 # size + ${requestId} + 0 + 1 # brokers + 0xb1 # broker id + 19s "broker1.example.com" # host name + 9092 # port + -1s # no rack + 9s "cluster 1" # cluster id + 1 # controller id + 1 # topics + 0s # no error + 4s "test" # "test" topic + [0x00] # not internal + 1 # partitions + 0s # no error + 0 # partition + 0xb1 # leader + 0 # no replicas + -1 # no in-sync replicas + 0 # offline replicas + +accepted + +read zilla:begin.ext ${proxy:matchBeginEx() + .typeId(zilla:id("proxy")) + .addressInet() + .protocol("stream") + .source("0.0.0.0") + .destination("broker1.example.com") + .sourcePort(0) + .destinationPort(9092) + .build() + .info() + .authority("broker1.example.com") + .build() + .build()} + +connected + +read 132 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 87 # record set size + 0L # first offset + 75 # length + -1 + [0x02] + 1548293632 + 0s + 0 # last offset delta + 1724846895864L # first timestamp + 1724846895864L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(25)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + [0x00] + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes # value bytes + +write 44 + ${requestId} + 1 # topics + 4s "test" + 1 # partitions + 2 # partition 0 + 0s # no error + 20L # base offset + 0L # log append time + 0 # throttle diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.header/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.header/client.rpt index 15f0f6a9f0..7e2183fa2e 100644 --- a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.header/client.rpt +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.header/client.rpt @@ -98,11 +98,11 @@ write 140 # size 83 # length -1 [0x02] - 0x4e8723aa + -1568090010 0s 0 # last offset delta - ${newTimestamp} # first timestamp - ${newTimestamp} # last timestamp + 1716424650323L # first timestamp + 1716424650323L # last timestamp -1L -1s -1 diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.header/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.header/server.rpt index 3738b7d640..ff11a9a208 100644 --- a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.header/server.rpt +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.header/server.rpt @@ -94,11 +94,11 @@ read 140 83 # length -1 [0x02] - [0..4] + -1568090010 0s 0 # last offset delta - (long:timestamp) # first timestamp - ${timestamp} # last timestamp + 1716424650323L # first timestamp + 1716424650323L # last timestamp -1L -1s -1 diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.null.crc/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.null.crc/client.rpt new file mode 100644 index 0000000000..4c2b9673b7 --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.null.crc/client.rpt @@ -0,0 +1,132 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property networkConnectWindow 8192 + +property newRequestId ${kafka:newRequestId()} +property produceWaitMax 500 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 26 # size + 3s # metadata + 5s # v5 + ${newRequestId} + 5s "zilla" # client id + 1 # topics + 4s "test" # "test" topic + [0x00] # allow_auto_topic_creation + +read 97 # size + ${newRequestId} + [0..4] + 1 # brokers + 0xb1 # broker id + 19s "broker1.example.com" # host name + 9092 # port + -1s # no rack + 9s "cluster 1" # cluster id + 1 # controller id + 1 # topics + 0s # no error + 4s "test" # "test" topic + [0x00] # not internal + 1 # partitions + 0s # no error + 0 # partition + 0xb1 # leader + 0 # no replicas + -1 # no in-sync replicas + 0 # offline replicas + +read notify ROUTED_BROKER_SERVER + +connect await ROUTED_BROKER_SERVER + "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +write zilla:begin.ext ${proxy:beginEx() + .typeId(zilla:id("proxy")) + .addressInet() + .protocol("stream") + .source("0.0.0.0") + .destination("broker1.example.com") + .sourcePort(0) + .destinationPort(9092) + .build() + .info() + .authority("broker1.example.com") + .build() + .build()} + +connected + +write 132 # size + 0s # produce + 3s # v3 + ${newRequestId} + 5s "zilla" # client id + -1s # transactional id + 0s # acks + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 # partition + 87 # record set size + 0L # first offset + 75 # length + -1 + [0x02] + 61721183 + 0s + 0 # last offset delta + 1724846895864L # first timestamp + 1724846895864L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(25)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + [0x01] + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 44 + ${newRequestId} + 1 # topics + 4s "test" + 1 # partitions + 2 # partition + 0s # no error + 20L # base offset + [0..8] # log append time + [0..4] # throttle ms diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.null.crc/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.null.crc/server.rpt new file mode 100644 index 0000000000..3e2a328e61 --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.null.crc/server.rpt @@ -0,0 +1,125 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 26 # size + 3s # metadata + 5s # v5 + (int:requestId) + 5s "zilla" # client id + 1 # topics + 4s "test" # "test" topic + [0x00] # allow_auto_topic_creation + +write 97 # size + ${requestId} + 0 + 1 # brokers + 0xb1 # broker id + 19s "broker1.example.com" # host name + 9092 # port + -1s # no rack + 9s "cluster 1" # cluster id + 1 # controller id + 1 # topics + 0s # no error + 4s "test" # "test" topic + [0x00] # not internal + 1 # partitions + 0s # no error + 0 # partition + 0xb1 # leader + 0 # no replicas + -1 # no in-sync replicas + 0 # offline replicas + +accepted + +read zilla:begin.ext ${proxy:matchBeginEx() + .typeId(zilla:id("proxy")) + .addressInet() + .protocol("stream") + .source("0.0.0.0") + .destination("broker1.example.com") + .sourcePort(0) + .destinationPort(9092) + .build() + .info() + .authority("broker1.example.com") + .build() + .build()} + +connected + +read 132 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 87 # record set size + 0L # first offset + 75 # length + -1 + [0x02] + 61721183 + 0s + 0 # last offset delta + 1724846895864L # first timestamp + 1724846895864L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(25)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + [0x01] + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +write 44 + ${requestId} + 1 # topics + 4s "test" + 1 # partitions + 2 # partition 0 + 0s # no error + 20L # base offset + 0L # log append time + 0 # throttle diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.value.100k/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.value.100k/client.rpt index 02ceee163b..bf165dbe13 100644 --- a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.value.100k/client.rpt +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.value.100k/client.rpt @@ -98,11 +98,11 @@ write 102517 # size 102460 # length -1 [0x02] - 0x4e8723aa + 1383945041 0s 0 # last offset delta - ${newTimestamp} # first timestamp - ${newTimestamp} # last timestamp + 1716424650323L # first timestamp + 1716424650323L # last timestamp -1L -1s -1 diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.value.100k/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.value.100k/server.rpt index 87b17099da..09d75d64dd 100644 --- a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.value.100k/server.rpt +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/message.value.100k/server.rpt @@ -95,11 +95,11 @@ read 102517 102460 # length -1 [0x02] - [0..4] + 1383945041 0s 0 # last offset delta - (long:timestamp) # first timestamp - ${timestamp} # last timestamp + 1716424650323L # first timestamp + 1716424650323L # last timestamp -1L -1s -1 diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/messages.fragmented.crc/client.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/messages.fragmented.crc/client.rpt new file mode 100644 index 0000000000..99b9edcd7f --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/messages.fragmented.crc/client.rpt @@ -0,0 +1,402 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property networkConnectWindow 8192 + +property newRequestId ${kafka:newRequestId()} +property produceWaitMax 500 + +connect "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +connected + +write 26 # size + 3s # metadata + 5s # v5 + ${newRequestId} + 5s "zilla" # client id + 1 # topics + 4s "test" # "test" topic + [0x00] # allow_auto_topic_creation + +read 97 # size + ${newRequestId} + [0..4] + 1 # brokers + 0xb1 # broker id + 19s "broker1.example.com" # host name + 9092 # port + -1s # no rack + 9s "cluster 1" # cluster id + 1 # controller id + 1 # topics + 0s # no error + 4s "test" # "test" topic + [0x00] # not internal + 1 # partitions + 0s # no error + 0 # partition + 0xb1 # leader + 0 # no replicas + -1 # no in-sync replicas + 0 # offline replicas + +read notify ROUTED_BROKER_SERVER + +connect await ROUTED_BROKER_SERVER + "zilla://streams/net0" + option zilla:window ${networkConnectWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +write zilla:begin.ext ${proxy:beginEx() + .typeId(zilla:id("proxy")) + .addressInet() + .protocol("stream") + .source("0.0.0.0") + .destination("broker1.example.com") + .sourcePort(0) + .destinationPort(9092) + .build() + .info() + .authority("broker1.example.com") + .build() + .build()} + +connected + +write 145 + 0s + 3s + ${newRequestId} + 5s "zilla" # client id + -1s + 0s + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + 1716424650323L # first timestamp + 1716424650323L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +write 145 + 0s + 3s + ${newRequestId} + 5s "zilla" # client id + -1s + 0s + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + 1716424650323L # first timestamp + 1716424650323L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +write 145 + 0s + 3s + ${newRequestId} + 5s "zilla" # client id + -1s + 0s + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + 1716424650323L # first timestamp + 1716424650323L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +write 145 + 0s + 3s + ${newRequestId} + 5s "zilla" # client id + -1s + 0s + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + 1716424650323L # first timestamp + 1716424650323L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +write 145 + 0s + 3s + ${newRequestId} + 5s "zilla" # client id + -1s + 0s + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + 1716424650323L # first timestamp + 1716424650323L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +write 145 + 0s + 3s + ${newRequestId} + 5s "zilla" # client id + -1s + 0s + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + 1716424650323L # first timestamp + 1716424650323L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +write 145 + 0s + 3s + ${newRequestId} + 5s "zilla" # client id + -1s + 0s + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + 1716424650323L # first timestamp + 1716424650323L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +write 145 + 0s + 3s + ${newRequestId} + 5s "zilla" # client id + -1s + 0s + ${produceWaitMax} + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + 1716424650323L # first timestamp + 1716424650323L # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/messages.fragmented.crc/server.rpt b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/messages.fragmented.crc/server.rpt new file mode 100644 index 0000000000..cb30acd937 --- /dev/null +++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/streams/network/produce.v3/messages.fragmented.crc/server.rpt @@ -0,0 +1,395 @@ +# +# Copyright 2021-2023 Aklivity Inc. +# +# Aklivity licenses this file to you under the Apache License, +# version 2.0 (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +property networkAcceptWindow 8192 + +accept "zilla://streams/net0" + option zilla:window ${networkAcceptWindow} + option zilla:transmission "duplex" + option zilla:byteorder "network" + +accepted + +connected + +read 26 # size + 3s # metadata + 5s # v5 + (int:requestId) + 5s "zilla" # client id + 1 # topics + 4s "test" # "test" topic + [0x00] # allow_auto_topic_creation + +write 97 # size + ${requestId} + 0 + 1 # brokers + 0xb1 # broker id + 19s "broker1.example.com" # host name + 9092 # port + -1s # no rack + 9s "cluster 1" # cluster id + 1 # controller id + 1 # topics + 0s # no error + 4s "test" # "test" topic + [0x00] # not internal + 1 # partitions + 0s # no error + 0 # partition + 0xb1 # leader + 0 # no replicas + -1 # no in-sync replicas + 0 # offline replicas + +accepted + +read zilla:begin.ext ${proxy:matchBeginEx() + .typeId(zilla:id("proxy")) + .addressInet() + .protocol("stream") + .source("0.0.0.0") + .destination("broker1.example.com") + .sourcePort(0) + .destinationPort(9092) + .build() + .info() + .authority("broker1.example.com") + .build() + .build()} + +connected + +read 145 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + (long:timestamp) # first timestamp + ${timestamp} # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 145 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + (long:timestamp) # first timestamp + ${timestamp} # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 145 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + (long:timestamp) # first timestamp + ${timestamp} # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 145 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + (long:timestamp) # first timestamp + ${timestamp} # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 145 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + (long:timestamp) # first timestamp + ${timestamp} # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 145 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + (long:timestamp) # first timestamp + ${timestamp} # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 145 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + (long:timestamp) # first timestamp + ${timestamp} # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes + +read 145 + 0s + 3s + (int:requestId) + 5s "zilla" # client id + -1s + [0..2] + [0..4] + 1 + 4s "test" + 1 + 2 + 100 # record set size + 0L # first offset + 88 # length + -1 + [0x02] + 1012046046 + 8s + 0 # last offset delta + (long:timestamp) # first timestamp + ${timestamp} # last timestamp + -1L + -1s + -1 + 1 # records + ${kafka:varint(38)} + [0x00] + ${kafka:varint(0)} + ${kafka:varint(0)} + ${kafka:varint(4)} # key + "key1" + ${kafka:varint(13)} + "Hello, World!" + ${kafka:varint(1)} # headers + ${kafka:varint(7)} # key size + "header1" # key bytes + ${kafka:varint(6)} # value size + "value1" # value bytes diff --git a/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/internal/KafkaFunctionsTest.java b/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/internal/KafkaFunctionsTest.java index 90b6675b93..f55fb3f26f 100644 --- a/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/internal/KafkaFunctionsTest.java +++ b/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/internal/KafkaFunctionsTest.java @@ -1223,9 +1223,6 @@ public void shouldMatchMergedFetchDataExtensionWithLatestOffset() throws Excepti .partition(0, 0L, 1L) .progress(0, 1L, 1L) .timestamp(12345678L) - .producerId(8L) - .producerEpoch((short) 2) - .timestamp(12345678L) .key("match") .header("name", "value") .build() @@ -2790,29 +2787,6 @@ public void shouldMatchProduceBeginExtensionTransaction() throws Exception assertNotNull(matcher.match(byteBuf)); } - @Test - public void shouldMatchProduceBeginExtensionProducerId() throws Exception - { - BytesMatcher matcher = KafkaFunctions.matchBeginEx() - .produce() - .producerId(1L) - .build() - .build(); - - ByteBuffer byteBuf = ByteBuffer.allocate(1024); - - new KafkaBeginExFW.Builder() - .wrap(new UnsafeBuffer(byteBuf), 0, byteBuf.capacity()) - .typeId(0x01) - .produce(f -> f - .transaction("transaction") - .topic("test") - .partition(p -> p.partitionId(0).partitionOffset(0L))) - .build(); - - assertNotNull(matcher.match(byteBuf)); - } - @Test public void shouldMatchProduceBeginExtensionTopic() throws Exception { @@ -3685,6 +3659,8 @@ public void shouldMatchProduceDataExtensionTimestamp() throws Exception new KafkaDataExFW.Builder().wrap(new UnsafeBuffer(byteBuf), 0, byteBuf.capacity()) .typeId(0x01) .produce(p -> p.timestamp(12345678L) + .producerId(8L) + .producerEpoch((short) 1) .sequence(0) .key(k -> k.length(5) .value(v -> v.set("match".getBytes(UTF_8)))) diff --git a/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/streams/application/ProduceIT.java b/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/streams/application/ProduceIT.java index 7a29a25aa0..90c3a5103c 100644 --- a/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/streams/application/ProduceIT.java +++ b/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/streams/application/ProduceIT.java @@ -146,6 +146,33 @@ public void shouldSendMessageValue() throws Exception k3po.finish(); } + @Test + @Specification({ + "${app}/messages.fragmented.crc/client", + "${app}/messages.fragmented.crc/server"}) + public void shouldSendFragmentedMessagesWithCrc() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${app}/message.empty.crc/client", + "${app}/message.empty.crc/server"}) + public void shouldSendMessageEmptyWithCrc() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${app}/message.null.crc/client", + "${app}/message.null.crc/server"}) + public void shouldSendMessageNullWithCrc() throws Exception + { + k3po.finish(); + } + @Test @Specification({ "${app}/message.producer.id/client", @@ -257,6 +284,15 @@ public void shouldSendMessageValueRepeated() throws Exception k3po.finish(); } + @Test + @Specification({ + "${app}/message.value.repeated.fragmented/client", + "${app}/message.value.repeated.fragmented/server"}) + public void shouldSendMessageValueRepeatedWhenFragmented() throws Exception + { + k3po.finish(); + } + @Test @Specification({ "${app}/message.values.sequential/client", diff --git a/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/streams/network/ProduceIT.java b/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/streams/network/ProduceIT.java index 112cdd4a07..6b0589c2ee 100644 --- a/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/streams/network/ProduceIT.java +++ b/specs/binding-kafka.spec/src/test/java/io/aklivity/zilla/specs/binding/kafka/streams/network/ProduceIT.java @@ -119,6 +119,33 @@ public void shouldSendMessageValue() throws Exception k3po.finish(); } + @Test + @Specification({ + "${net}/messages.fragmented.crc/client", + "${net}/messages.fragmented.crc/server"}) + public void shouldSendFragmentedMessagesWithCrc() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${net}/message.empty.crc/client", + "${net}/message.empty.crc/server"}) + public void shouldSendMessageEmptyWithCrc() throws Exception + { + k3po.finish(); + } + + @Test + @Specification({ + "${net}/message.null.crc/client", + "${net}/message.null.crc/server"}) + public void shouldSendMessageNullWithCrc() throws Exception + { + k3po.finish(); + } + @Test @Specification({ "${net}/message.producer.id/client", diff --git a/specs/binding-mqtt-kafka.spec/pom.xml b/specs/binding-mqtt-kafka.spec/pom.xml index e24320d21d..e064f12793 100644 --- a/specs/binding-mqtt-kafka.spec/pom.xml +++ b/specs/binding-mqtt-kafka.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-mqtt.spec/pom.xml b/specs/binding-mqtt.spec/pom.xml index d95395046e..161d11ab7d 100644 --- a/specs/binding-mqtt.spec/pom.xml +++ b/specs/binding-mqtt.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-openapi-asyncapi.spec/pom.xml b/specs/binding-openapi-asyncapi.spec/pom.xml index 4895525fdb..7e7301a5a4 100644 --- a/specs/binding-openapi-asyncapi.spec/pom.xml +++ b/specs/binding-openapi-asyncapi.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-openapi.spec/pom.xml b/specs/binding-openapi.spec/pom.xml index 034bff4c8b..fd7414c0f5 100644 --- a/specs/binding-openapi.spec/pom.xml +++ b/specs/binding-openapi.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-proxy.spec/pom.xml b/specs/binding-proxy.spec/pom.xml index f1b122d95f..23be10b63f 100644 --- a/specs/binding-proxy.spec/pom.xml +++ b/specs/binding-proxy.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-sse-kafka.spec/pom.xml b/specs/binding-sse-kafka.spec/pom.xml index 8a727b7284..63fe7fe020 100644 --- a/specs/binding-sse-kafka.spec/pom.xml +++ b/specs/binding-sse-kafka.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-sse.spec/pom.xml b/specs/binding-sse.spec/pom.xml index 640e4f26c4..591f1c2736 100644 --- a/specs/binding-sse.spec/pom.xml +++ b/specs/binding-sse.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-tcp.spec/pom.xml b/specs/binding-tcp.spec/pom.xml index 228e793acb..826644606d 100644 --- a/specs/binding-tcp.spec/pom.xml +++ b/specs/binding-tcp.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/binding-tls.spec/pom.xml b/specs/binding-tls.spec/pom.xml index 7cff954f29..81e8ea5e8a 100644 --- a/specs/binding-tls.spec/pom.xml +++ b/specs/binding-tls.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml @@ -102,6 +102,7 @@ **/signers **/*.csr **/*.crt + **/*.pem diff --git a/specs/binding-tls.spec/src/main/resources/META-INF/zilla/tls.idl b/specs/binding-tls.spec/src/main/resources/META-INF/zilla/tls.idl index 0f08dac473..baa53655f6 100644 --- a/specs/binding-tls.spec/src/main/resources/META-INF/zilla/tls.idl +++ b/specs/binding-tls.spec/src/main/resources/META-INF/zilla/tls.idl @@ -23,20 +23,7 @@ scope tls TLS_PROTOCOL_REJECTED (2), TLS_KEY_REJECTED (3), TLS_PEER_NOT_VERIFIED (4), - TLS_HANDSHAKE_FAILED (5), - TLS_KEY_VERIFICATION_FAILED (6) - } - - enum TlsKeyFailureType (uint8) - { - TLS_KEY_MISSING (1), - TLS_KEY_INVALID (2) - } - - struct TlsKeyVerificationFailedEx extends core::stream::Extension - { - TlsKeyFailureType failureType; - string8 keyName; + TLS_HANDSHAKE_FAILED (5) } union TlsEventEx switch (TlsEventType) @@ -46,7 +33,6 @@ scope tls case TLS_KEY_REJECTED: core::stream::Extension tlsKeyRejected; case TLS_PEER_NOT_VERIFIED: core::stream::Extension tlsPeerNotVerified; case TLS_HANDSHAKE_FAILED: core::stream::Extension tlsHandshakeFailed; - case TLS_KEY_VERIFICATION_FAILED: TlsKeyVerificationFailedEx tlsKeyVerificationFailed; } } } diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/bridge.tls1.2.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/bridge.tls1.2.yaml index 2ba1cbe646..ca4f7df465 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/bridge.tls1.2.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/bridge.tls1.2.yaml @@ -18,16 +18,106 @@ name: test vaults: bridge: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- trust: - store: stores/client/trust - type: pkcs12 - password: generated + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/bridge.tls1.3.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/bridge.tls1.3.yaml index 64dd7dded0..393b614b80 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/bridge.tls1.3.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/bridge.tls1.3.yaml @@ -17,17 +17,107 @@ --- name: test vaults: - bridge: - type: filesystem - options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated - trust: - store: stores/client/trust - type: pkcs12 - password: generated + bridge: + type: test + options: + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- + trust: + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.alpn.default.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.alpn.default.yaml index 8992afeab2..7a1f56f310 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.alpn.default.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.alpn.default.yaml @@ -18,12 +18,32 @@ name: test vaults: client: - type: filesystem + type: test options: - trust: - store: stores/client/trust - type: pkcs12 - password: generated + trust: + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.alpn.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.alpn.yaml index b2adf119eb..bb8b80d637 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.alpn.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.alpn.yaml @@ -18,12 +18,32 @@ name: test vaults: client: - type: filesystem + type: test options: - trust: - store: stores/client/trust - type: pkcs12 - password: generated + trust: + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.event.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.event.yaml index 1049afc790..1f12bde1da 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.event.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.event.yaml @@ -28,12 +28,32 @@ telemetry: message: The client and server could not negotiate the desired level of security. vaults: client: - type: filesystem + type: test options: - trust: - store: stores/client/trust - type: pkcs12 - password: generated + trust: + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.mutual.signer.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.mutual.signer.yaml index 698b8b6794..3bd2a577f4 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.mutual.signer.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.mutual.signer.yaml @@ -18,20 +18,128 @@ name: test vaults: client: - type: filesystem + type: test options: trust: - store: stores/client/trust - type: pkcs12 - password: generated - signers: - store: stores/server/trust - type: pkcs12 - password: generated - keys: - store: stores/client/keys - type: pkcs12 - password: generated + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- + signer: + alias: clientca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIECLJx+DANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTRaFw0zMTEyMTIwMDM1NTRaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAsiCAp3sTYiCVjNI3srcuHPa3p7BzGmxqMHeCqOU/ATABYTl9JTFEdqPfUGgS + ubiDQ/DRf0pLmzsJL36eZq3mP7qvbuBE00rqWp4GfYYI8m+3yvVO0a/igLh0kRPV + y9zMXLwIrzMupyAvex5g0xbJ7REu0QONf/Ff8obcowLi0ophH5N05Fx4qU+9nosZ + tuEcS8A7DDMbt9liBVeGNYPenUoH2o9eRZ0YjzoGUNXOLsAW+gT/fn3ZkR8EgUiE + LUjpIpOGWOQo3ro74wvkffs6WjMckoWY+kKfJ9nzL6orIZ9F5lNHwmSfgVaK5hcg + J00jZ4SA7pOvu3MtKcuf0zjzrQIDAQABozIwMDAdBgNVHQ4EFgQU5obnoO20A2wT + KYH+uCuF4ZW6cCswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + QnKttaZqVCoui8jQlI8uG6T4Wdg5ElYvO05Kz6dpKCBAxxcDXu4B7B+65bqABVXw + KBu70+oXW9TQHE1psBzKeUeMKk8BMV+q8gCFWHNu5tpgp51xqwQGFFOJTm1HiV+S + /WcnrnZe7XIa/bXbdYHz0uQV9fjMCqw354YGRRd1WWkHZYWrp9YucscpTKdGFQJD + uM+poi57NOANSTgTyyZg3cerZTJjBL92XWDfMv93ZVjUE76B6bXvMJLG3Gh9nYEC + epvLX8PSLdbal8ZBcosduxy1dSiQzy7Hj5wsOuj8neoVRaCHmAXouiJDDpQcnasC + p0XXN2RYSD7FW7RNb4xcNQ== + -----END CERTIFICATE----- + key: + alias: client1 + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrn6NhWOvX69jT + 5Xv/MqGEMLtCtMbR3W+ev4f4QXGx3smk3nilx2qdcKGCs/vQsvIbcvRHACpMLgeX + K3z/4UDULKa0sAJBl7/YdffhvqguozJMsi09aNHHuC5pZjeu1BFEcxfhfMamyHcK + 1P4no9nhjrQLW3u4j+7d2AiuoMvvP6BznTr6Q95YHl6l5FxNCk9pevO1bDI6b0qR + 7/NYvpF7fM01yVEyUnvPsOJBChOn5PXvZbkAQZ4laaYcu8c55YmVxsrrstHdoiXc + 7322Vocom8S1JXuoVEhxBtO49bmrm5J7Si1JhAcTXS89r4uJr0g/tVg/5JmuAF3k + vve7WsZjAgMBAAECggEARW+B93m1eZdnE1vuTfKbHFNm//cJ1ZDEfzK4fT1lFXSw + mm6T22aSAP63qZzODcLIZ0icAjnT4xxgX83tdc0ZoH4sOEBZuVX+/UHFN2UewDew + uwz/dq/459fhly0O7EHKdqomCEmmSYYje5Nu/HSzSymkOFAb/zDkkIa+BIDz4Whv + tM8h0SOPCMcW78E2fEfLC5sEATK0B0yJ2QHCJAJ1E1DuiNZGQKn0Jk56QQxdmpsM + a8hOY216RcCq0bhh5+WRCd/fKgmMj9ExgG7JL+JshW69UArIPYfR5NmlLEUL93Ua + rj2yK1U27YI+m0Vhsn+caOZIxAflmBLUG1iny2ANoQKBgQDf5CxqFvvj9naqVy1v + 6GgUFbb0MLsdvbtqbmQq30gtSJqe+5ct2kIHRoWmb/ZxgW+SCp4qFFSWVPysMOtK + qHQHX8N4vwqHDXcgnX5rvaEWlSRziJe8VSyfUPtvDWYua7FbXMV0rvyPerAAzOff + 9sykNcrXE8MsQn/9u9tXTW7aEwKBgQDEPIkXjyUGjZVwo0BjQnZY1qMqX9n07Nk/ + kA+3T23Jvd2sVRYtM8d0y0KmrBUueZmxQpbbdWnD5jeoA8kdJVybO3WOux5O39Sn + e6CsLtaDeNrI0d+0hxGdSCLavavUn0QhUyJS7W6kUhP+1jvghcBstg5xglK/kuij + JNEsvnHscQKBgGHKVr/r1A+o6gHS3AzCFRuYtHWKB2ChK4f8OZIkPnFRAgAo4cps + R2TIH74nrxu6rlG6g4TbpmqXKlnHcC4Gz88cu9M0llOQxRSg1cQXapHjiK1R3vyq + szfO9lN2Jchmz2uZZMFnYPcGXnOrDChdstqSiEtS3W+qiB76e35xWtazAoGBAJku + f/1p+gcRgnP4m4xgFy3l7lxnkiYEtNlPRVVcpWDz2xRpHvSOFMZw3Ehqz+YFehnK + 1yPclYEcNpnqypT70zxBv9R48IG1a7SJZrTBoyXhszdLzQqI3REffEWwBW/mGzLA + SGzfdpzCjWVCKl9rSPgTbVbh2mI89WhUlwwMZbWhAoGANs9+Ahxk/PEh8qJF5Oie + M6Yn+tt4Zc/XiNG1bllLX0aYHmN7TsLqvd4Bz6w44SsK1X2AUjRqutzO9/e8lIHL + YjOdLlotdORDWQc6vGC23TQmiszGoszdtQQDhCkocVi3jV0r8ocUDtOPkijnfl39 + pynEfemPcP7gg/7Gh7mD998= + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDQDCCAiigAwIBAgIEQSJ/bDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM2 + MDBaFw0yNjExMTgwMDM2MDBaMBIxEDAOBgNVBAMTB2NsaWVudDEwggEiMA0GCSqG + SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrn6NhWOvX69jT5Xv/MqGEMLtCtMbR3W+e + v4f4QXGx3smk3nilx2qdcKGCs/vQsvIbcvRHACpMLgeXK3z/4UDULKa0sAJBl7/Y + dffhvqguozJMsi09aNHHuC5pZjeu1BFEcxfhfMamyHcK1P4no9nhjrQLW3u4j+7d + 2AiuoMvvP6BznTr6Q95YHl6l5FxNCk9pevO1bDI6b0qR7/NYvpF7fM01yVEyUnvP + sOJBChOn5PXvZbkAQZ4laaYcu8c55YmVxsrrstHdoiXc7322Vocom8S1JXuoVEhx + BtO49bmrm5J7Si1JhAcTXS89r4uJr0g/tVg/5JmuAF3kvve7WsZjAgMBAAGjUjBQ + MB0GA1UdDgQWBBRy6TrHDFXQtgfFDIbeMKcN6zR93TAOBgNVHQ8BAf8EBAMCBaAw + HwYDVR0jBBgwFoAU5obnoO20A2wTKYH+uCuF4ZW6cCswDQYJKoZIhvcNAQELBQAD + ggEBAE3597yVknsz60h4WJGqvARtSaKIL3TDolOVbRG8/mLWGTCa3CguVMLVLE1I + xtnQZVP4Jgaacks7VmZodKNbTkhdsp2SYLtwjVETFn37KmlStO+th2E9x+RCembL + j5q98OzeQzQgiw6f0AnJIilSXW+JDGevTolnUeZNsqBJ5KiZskRDmK+ghQNR1gJ8 + VctMpMJEGl9zM6g+xgwrdqL9RXb6DpArqR2N+EtTp/Tpv3mkunkkficOlMhTYyGi + SXEE6xozLciQk8+EOF9i8leynKxzhera9nDkGeqEHM+5kEoBMGZiJDjLfsT71jfW + QEcYtMb3OsuhRL2yiXMJXwSYsFU= + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIECLJx+DANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTRaFw0zMTEyMTIwMDM1NTRaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAsiCAp3sTYiCVjNI3srcuHPa3p7BzGmxqMHeCqOU/ATABYTl9JTFEdqPfUGgS + ubiDQ/DRf0pLmzsJL36eZq3mP7qvbuBE00rqWp4GfYYI8m+3yvVO0a/igLh0kRPV + y9zMXLwIrzMupyAvex5g0xbJ7REu0QONf/Ff8obcowLi0ophH5N05Fx4qU+9nosZ + tuEcS8A7DDMbt9liBVeGNYPenUoH2o9eRZ0YjzoGUNXOLsAW+gT/fn3ZkR8EgUiE + LUjpIpOGWOQo3ro74wvkffs6WjMckoWY+kKfJ9nzL6orIZ9F5lNHwmSfgVaK5hcg + J00jZ4SA7pOvu3MtKcuf0zjzrQIDAQABozIwMDAdBgNVHQ4EFgQU5obnoO20A2wT + KYH+uCuF4ZW6cCswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + QnKttaZqVCoui8jQlI8uG6T4Wdg5ElYvO05Kz6dpKCBAxxcDXu4B7B+65bqABVXw + KBu70+oXW9TQHE1psBzKeUeMKk8BMV+q8gCFWHNu5tpgp51xqwQGFFOJTm1HiV+S + /WcnrnZe7XIa/bXbdYHz0uQV9fjMCqw354YGRRd1WWkHZYWrp9YucscpTKdGFQJD + uM+poi57NOANSTgTyyZg3cerZTJjBL92XWDfMv93ZVjUE76B6bXvMJLG3Gh9nYEC + epvLX8PSLdbal8ZBcosduxy1dSiQzy7Hj5wsOuj8neoVRaCHmAXouiJDDpQcnasC + p0XXN2RYSD7FW7RNb4xcNQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.mutual.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.mutual.yaml index ce7fc387c5..bdecbc445d 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.mutual.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.mutual.yaml @@ -18,16 +18,104 @@ name: test vaults: client: - type: filesystem + type: test options: trust: - store: stores/client/trust - type: pkcs12 - password: generated - keys: - store: stores/client/keys - type: pkcs12 - password: generated + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- + key: + alias: client1 + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrn6NhWOvX69jT + 5Xv/MqGEMLtCtMbR3W+ev4f4QXGx3smk3nilx2qdcKGCs/vQsvIbcvRHACpMLgeX + K3z/4UDULKa0sAJBl7/YdffhvqguozJMsi09aNHHuC5pZjeu1BFEcxfhfMamyHcK + 1P4no9nhjrQLW3u4j+7d2AiuoMvvP6BznTr6Q95YHl6l5FxNCk9pevO1bDI6b0qR + 7/NYvpF7fM01yVEyUnvPsOJBChOn5PXvZbkAQZ4laaYcu8c55YmVxsrrstHdoiXc + 7322Vocom8S1JXuoVEhxBtO49bmrm5J7Si1JhAcTXS89r4uJr0g/tVg/5JmuAF3k + vve7WsZjAgMBAAECggEARW+B93m1eZdnE1vuTfKbHFNm//cJ1ZDEfzK4fT1lFXSw + mm6T22aSAP63qZzODcLIZ0icAjnT4xxgX83tdc0ZoH4sOEBZuVX+/UHFN2UewDew + uwz/dq/459fhly0O7EHKdqomCEmmSYYje5Nu/HSzSymkOFAb/zDkkIa+BIDz4Whv + tM8h0SOPCMcW78E2fEfLC5sEATK0B0yJ2QHCJAJ1E1DuiNZGQKn0Jk56QQxdmpsM + a8hOY216RcCq0bhh5+WRCd/fKgmMj9ExgG7JL+JshW69UArIPYfR5NmlLEUL93Ua + rj2yK1U27YI+m0Vhsn+caOZIxAflmBLUG1iny2ANoQKBgQDf5CxqFvvj9naqVy1v + 6GgUFbb0MLsdvbtqbmQq30gtSJqe+5ct2kIHRoWmb/ZxgW+SCp4qFFSWVPysMOtK + qHQHX8N4vwqHDXcgnX5rvaEWlSRziJe8VSyfUPtvDWYua7FbXMV0rvyPerAAzOff + 9sykNcrXE8MsQn/9u9tXTW7aEwKBgQDEPIkXjyUGjZVwo0BjQnZY1qMqX9n07Nk/ + kA+3T23Jvd2sVRYtM8d0y0KmrBUueZmxQpbbdWnD5jeoA8kdJVybO3WOux5O39Sn + e6CsLtaDeNrI0d+0hxGdSCLavavUn0QhUyJS7W6kUhP+1jvghcBstg5xglK/kuij + JNEsvnHscQKBgGHKVr/r1A+o6gHS3AzCFRuYtHWKB2ChK4f8OZIkPnFRAgAo4cps + R2TIH74nrxu6rlG6g4TbpmqXKlnHcC4Gz88cu9M0llOQxRSg1cQXapHjiK1R3vyq + szfO9lN2Jchmz2uZZMFnYPcGXnOrDChdstqSiEtS3W+qiB76e35xWtazAoGBAJku + f/1p+gcRgnP4m4xgFy3l7lxnkiYEtNlPRVVcpWDz2xRpHvSOFMZw3Ehqz+YFehnK + 1yPclYEcNpnqypT70zxBv9R48IG1a7SJZrTBoyXhszdLzQqI3REffEWwBW/mGzLA + SGzfdpzCjWVCKl9rSPgTbVbh2mI89WhUlwwMZbWhAoGANs9+Ahxk/PEh8qJF5Oie + M6Yn+tt4Zc/XiNG1bllLX0aYHmN7TsLqvd4Bz6w44SsK1X2AUjRqutzO9/e8lIHL + YjOdLlotdORDWQc6vGC23TQmiszGoszdtQQDhCkocVi3jV0r8ocUDtOPkijnfl39 + pynEfemPcP7gg/7Gh7mD998= + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDQDCCAiigAwIBAgIEQSJ/bDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM2 + MDBaFw0yNjExMTgwMDM2MDBaMBIxEDAOBgNVBAMTB2NsaWVudDEwggEiMA0GCSqG + SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrn6NhWOvX69jT5Xv/MqGEMLtCtMbR3W+e + v4f4QXGx3smk3nilx2qdcKGCs/vQsvIbcvRHACpMLgeXK3z/4UDULKa0sAJBl7/Y + dffhvqguozJMsi09aNHHuC5pZjeu1BFEcxfhfMamyHcK1P4no9nhjrQLW3u4j+7d + 2AiuoMvvP6BznTr6Q95YHl6l5FxNCk9pevO1bDI6b0qR7/NYvpF7fM01yVEyUnvP + sOJBChOn5PXvZbkAQZ4laaYcu8c55YmVxsrrstHdoiXc7322Vocom8S1JXuoVEhx + BtO49bmrm5J7Si1JhAcTXS89r4uJr0g/tVg/5JmuAF3kvve7WsZjAgMBAAGjUjBQ + MB0GA1UdDgQWBBRy6TrHDFXQtgfFDIbeMKcN6zR93TAOBgNVHQ8BAf8EBAMCBaAw + HwYDVR0jBBgwFoAU5obnoO20A2wTKYH+uCuF4ZW6cCswDQYJKoZIhvcNAQELBQAD + ggEBAE3597yVknsz60h4WJGqvARtSaKIL3TDolOVbRG8/mLWGTCa3CguVMLVLE1I + xtnQZVP4Jgaacks7VmZodKNbTkhdsp2SYLtwjVETFn37KmlStO+th2E9x+RCembL + j5q98OzeQzQgiw6f0AnJIilSXW+JDGevTolnUeZNsqBJ5KiZskRDmK+ghQNR1gJ8 + VctMpMJEGl9zM6g+xgwrdqL9RXb6DpArqR2N+EtTp/Tpv3mkunkkficOlMhTYyGi + SXEE6xozLciQk8+EOF9i8leynKxzhera9nDkGeqEHM+5kEoBMGZiJDjLfsT71jfW + QEcYtMb3OsuhRL2yiXMJXwSYsFU= + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIECLJx+DANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTRaFw0zMTEyMTIwMDM1NTRaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAsiCAp3sTYiCVjNI3srcuHPa3p7BzGmxqMHeCqOU/ATABYTl9JTFEdqPfUGgS + ubiDQ/DRf0pLmzsJL36eZq3mP7qvbuBE00rqWp4GfYYI8m+3yvVO0a/igLh0kRPV + y9zMXLwIrzMupyAvex5g0xbJ7REu0QONf/Ff8obcowLi0ophH5N05Fx4qU+9nosZ + tuEcS8A7DDMbt9liBVeGNYPenUoH2o9eRZ0YjzoGUNXOLsAW+gT/fn3ZkR8EgUiE + LUjpIpOGWOQo3ro74wvkffs6WjMckoWY+kKfJ9nzL6orIZ9F5lNHwmSfgVaK5hcg + J00jZ4SA7pOvu3MtKcuf0zjzrQIDAQABozIwMDAdBgNVHQ4EFgQU5obnoO20A2wT + KYH+uCuF4ZW6cCswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + QnKttaZqVCoui8jQlI8uG6T4Wdg5ElYvO05Kz6dpKCBAxxcDXu4B7B+65bqABVXw + KBu70+oXW9TQHE1psBzKeUeMKk8BMV+q8gCFWHNu5tpgp51xqwQGFFOJTm1HiV+S + /WcnrnZe7XIa/bXbdYHz0uQV9fjMCqw354YGRRd1WWkHZYWrp9YucscpTKdGFQJD + uM+poi57NOANSTgTyyZg3cerZTJjBL92XWDfMv93ZVjUE76B6bXvMJLG3Gh9nYEC + epvLX8PSLdbal8ZBcosduxy1dSiQzy7Hj5wsOuj8neoVRaCHmAXouiJDDpQcnasC + p0XXN2RYSD7FW7RNb4xcNQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.ports.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.ports.yaml index 0b3b17776b..4f9e375946 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.ports.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.ports.yaml @@ -18,12 +18,32 @@ name: test vaults: client: - type: filesystem + type: test options: - trust: - store: stores/client/trust - type: pkcs12 - password: generated + trust: + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.sni.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.sni.yaml index 88269b559f..09090d5aab 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.sni.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.sni.yaml @@ -18,12 +18,32 @@ name: test vaults: client: - type: filesystem + type: test options: - trust: - store: stores/client/trust - type: pkcs12 - password: generated + trust: + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.yaml index a09ccc16d8..adbc32c90c 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.yaml @@ -18,12 +18,32 @@ name: test vaults: client: - type: filesystem + type: test options: - trust: - store: stores/client/trust - type: pkcs12 - password: generated + trust: + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: app0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.alpn.default.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.alpn.default.yaml index 05e079f4de..0cd74032f6 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.alpn.default.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.alpn.default.yaml @@ -18,12 +18,82 @@ name: test vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.alpn.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.alpn.yaml index 6a44f1e199..de228f2841 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.alpn.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.alpn.yaml @@ -18,12 +18,82 @@ name: test vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.handshake.failed.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.handshake.failed.yaml index d0dc007984..90f9162db6 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.handshake.failed.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.handshake.failed.yaml @@ -28,12 +28,82 @@ telemetry: message: The client and server could not negotiate the desired level of security. vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.tls.failed.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.tls.failed.yaml index 2f5a3b47a4..9be3e9d57f 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.tls.failed.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.tls.failed.yaml @@ -28,12 +28,82 @@ telemetry: message: There was a generic error detected by an SSL subsystem. vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.keys.not.found.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.keys.not.found.yaml index 16f38c838f..ae7ce716a2 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.keys.not.found.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.keys.not.found.yaml @@ -18,12 +18,82 @@ name: test vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.mutual.requested.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.mutual.requested.yaml index a4af0daacd..360d322148 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.mutual.requested.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.mutual.requested.yaml @@ -18,16 +18,106 @@ name: test vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated - trust: - store: stores/server/trust - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- + trust: + alias: clientca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIECLJx+DANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTRaFw0zMTEyMTIwMDM1NTRaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAsiCAp3sTYiCVjNI3srcuHPa3p7BzGmxqMHeCqOU/ATABYTl9JTFEdqPfUGgS + ubiDQ/DRf0pLmzsJL36eZq3mP7qvbuBE00rqWp4GfYYI8m+3yvVO0a/igLh0kRPV + y9zMXLwIrzMupyAvex5g0xbJ7REu0QONf/Ff8obcowLi0ophH5N05Fx4qU+9nosZ + tuEcS8A7DDMbt9liBVeGNYPenUoH2o9eRZ0YjzoGUNXOLsAW+gT/fn3ZkR8EgUiE + LUjpIpOGWOQo3ro74wvkffs6WjMckoWY+kKfJ9nzL6orIZ9F5lNHwmSfgVaK5hcg + J00jZ4SA7pOvu3MtKcuf0zjzrQIDAQABozIwMDAdBgNVHQ4EFgQU5obnoO20A2wT + KYH+uCuF4ZW6cCswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + QnKttaZqVCoui8jQlI8uG6T4Wdg5ElYvO05Kz6dpKCBAxxcDXu4B7B+65bqABVXw + KBu70+oXW9TQHE1psBzKeUeMKk8BMV+q8gCFWHNu5tpgp51xqwQGFFOJTm1HiV+S + /WcnrnZe7XIa/bXbdYHz0uQV9fjMCqw354YGRRd1WWkHZYWrp9YucscpTKdGFQJD + uM+poi57NOANSTgTyyZg3cerZTJjBL92XWDfMv93ZVjUE76B6bXvMJLG3Gh9nYEC + epvLX8PSLdbal8ZBcosduxy1dSiQzy7Hj5wsOuj8neoVRaCHmAXouiJDDpQcnasC + p0XXN2RYSD7FW7RNb4xcNQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.mutual.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.mutual.yaml index d4db55f3ef..c7b2bcdbf4 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.mutual.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.mutual.yaml @@ -18,16 +18,106 @@ name: test vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated - trust: - store: stores/server/trust - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- + trust: + alias: clientca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIECLJx+DANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTRaFw0zMTEyMTIwMDM1NTRaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAsiCAp3sTYiCVjNI3srcuHPa3p7BzGmxqMHeCqOU/ATABYTl9JTFEdqPfUGgS + ubiDQ/DRf0pLmzsJL36eZq3mP7qvbuBE00rqWp4GfYYI8m+3yvVO0a/igLh0kRPV + y9zMXLwIrzMupyAvex5g0xbJ7REu0QONf/Ff8obcowLi0ophH5N05Fx4qU+9nosZ + tuEcS8A7DDMbt9liBVeGNYPenUoH2o9eRZ0YjzoGUNXOLsAW+gT/fn3ZkR8EgUiE + LUjpIpOGWOQo3ro74wvkffs6WjMckoWY+kKfJ9nzL6orIZ9F5lNHwmSfgVaK5hcg + J00jZ4SA7pOvu3MtKcuf0zjzrQIDAQABozIwMDAdBgNVHQ4EFgQU5obnoO20A2wT + KYH+uCuF4ZW6cCswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + QnKttaZqVCoui8jQlI8uG6T4Wdg5ElYvO05Kz6dpKCBAxxcDXu4B7B+65bqABVXw + KBu70+oXW9TQHE1psBzKeUeMKk8BMV+q8gCFWHNu5tpgp51xqwQGFFOJTm1HiV+S + /WcnrnZe7XIa/bXbdYHz0uQV9fjMCqw354YGRRd1WWkHZYWrp9YucscpTKdGFQJD + uM+poi57NOANSTgTyyZg3cerZTJjBL92XWDfMv93ZVjUE76B6bXvMJLG3Gh9nYEC + epvLX8PSLdbal8ZBcosduxy1dSiQzy7Hj5wsOuj8neoVRaCHmAXouiJDDpQcnasC + p0XXN2RYSD7FW7RNb4xcNQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.ports.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.ports.yaml index 90fbf5a6d5..146693ea31 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.ports.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.ports.yaml @@ -18,12 +18,82 @@ name: test vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.signer.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.signer.yaml index e78e195a12..90e1ce87cb 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.signer.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.signer.yaml @@ -18,12 +18,32 @@ name: test vaults: server: - type: filesystem + type: test options: - signers: - store: stores/server/signers - type: pkcs12 - password: generated + signer: + alias: serverca + entry: | + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.sni.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.sni.yaml index 0307882adf..8721545d91 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.sni.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.sni.yaml @@ -18,12 +18,82 @@ name: test vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.yaml index f9734e6590..1d5c1227b2 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.yaml +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.yaml @@ -18,12 +18,82 @@ name: test vaults: server: - type: filesystem + type: test options: - keys: - store: stores/server/keys - type: pkcs12 - password: generated + key: + alias: localhost + entry: | + -----BEGIN PRIVATE KEY----- + MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 + jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw + woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP + JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av + tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj + qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ + jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB + 80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 + QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h + fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR + 8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 + 6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA + AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr + tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP + F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn + 8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA + 3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr + XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ + atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb + X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y + 5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv + +6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba + 19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx + aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O + gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ + 4dIOj5XwbSpgiTBrWlctf87U + -----END PRIVATE KEY----- + -----BEGIN CERTIFICATE----- + MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE + CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 + n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR + RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 + u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h + VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P + 0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW + MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z + dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF + AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV + oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi + 6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 + prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo + 4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl + zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz + ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 + MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 + NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL + EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm + b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc + zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk + rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP + g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 + o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj + lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl + rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA + a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 + kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM + FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 + gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f + P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX + 5OQUWOWJqvzyJ8VIbBRDsQ== + -----END CERTIFICATE----- bindings: net0: type: tls diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/keys.client1.pem b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/keys.client1.pem new file mode 100644 index 0000000000..df529b9b9f --- /dev/null +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/keys.client1.pem @@ -0,0 +1,69 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrn6NhWOvX69jT +5Xv/MqGEMLtCtMbR3W+ev4f4QXGx3smk3nilx2qdcKGCs/vQsvIbcvRHACpMLgeX +K3z/4UDULKa0sAJBl7/YdffhvqguozJMsi09aNHHuC5pZjeu1BFEcxfhfMamyHcK +1P4no9nhjrQLW3u4j+7d2AiuoMvvP6BznTr6Q95YHl6l5FxNCk9pevO1bDI6b0qR +7/NYvpF7fM01yVEyUnvPsOJBChOn5PXvZbkAQZ4laaYcu8c55YmVxsrrstHdoiXc +7322Vocom8S1JXuoVEhxBtO49bmrm5J7Si1JhAcTXS89r4uJr0g/tVg/5JmuAF3k +vve7WsZjAgMBAAECggEARW+B93m1eZdnE1vuTfKbHFNm//cJ1ZDEfzK4fT1lFXSw +mm6T22aSAP63qZzODcLIZ0icAjnT4xxgX83tdc0ZoH4sOEBZuVX+/UHFN2UewDew +uwz/dq/459fhly0O7EHKdqomCEmmSYYje5Nu/HSzSymkOFAb/zDkkIa+BIDz4Whv +tM8h0SOPCMcW78E2fEfLC5sEATK0B0yJ2QHCJAJ1E1DuiNZGQKn0Jk56QQxdmpsM +a8hOY216RcCq0bhh5+WRCd/fKgmMj9ExgG7JL+JshW69UArIPYfR5NmlLEUL93Ua +rj2yK1U27YI+m0Vhsn+caOZIxAflmBLUG1iny2ANoQKBgQDf5CxqFvvj9naqVy1v +6GgUFbb0MLsdvbtqbmQq30gtSJqe+5ct2kIHRoWmb/ZxgW+SCp4qFFSWVPysMOtK +qHQHX8N4vwqHDXcgnX5rvaEWlSRziJe8VSyfUPtvDWYua7FbXMV0rvyPerAAzOff +9sykNcrXE8MsQn/9u9tXTW7aEwKBgQDEPIkXjyUGjZVwo0BjQnZY1qMqX9n07Nk/ +kA+3T23Jvd2sVRYtM8d0y0KmrBUueZmxQpbbdWnD5jeoA8kdJVybO3WOux5O39Sn +e6CsLtaDeNrI0d+0hxGdSCLavavUn0QhUyJS7W6kUhP+1jvghcBstg5xglK/kuij +JNEsvnHscQKBgGHKVr/r1A+o6gHS3AzCFRuYtHWKB2ChK4f8OZIkPnFRAgAo4cps +R2TIH74nrxu6rlG6g4TbpmqXKlnHcC4Gz88cu9M0llOQxRSg1cQXapHjiK1R3vyq +szfO9lN2Jchmz2uZZMFnYPcGXnOrDChdstqSiEtS3W+qiB76e35xWtazAoGBAJku +f/1p+gcRgnP4m4xgFy3l7lxnkiYEtNlPRVVcpWDz2xRpHvSOFMZw3Ehqz+YFehnK +1yPclYEcNpnqypT70zxBv9R48IG1a7SJZrTBoyXhszdLzQqI3REffEWwBW/mGzLA +SGzfdpzCjWVCKl9rSPgTbVbh2mI89WhUlwwMZbWhAoGANs9+Ahxk/PEh8qJF5Oie +M6Yn+tt4Zc/XiNG1bllLX0aYHmN7TsLqvd4Bz6w44SsK1X2AUjRqutzO9/e8lIHL +YjOdLlotdORDWQc6vGC23TQmiszGoszdtQQDhCkocVi3jV0r8ocUDtOPkijnfl39 +pynEfemPcP7gg/7Gh7mD998= +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIEQSJ/bDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz +ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM2 +MDBaFw0yNjExMTgwMDM2MDBaMBIxEDAOBgNVBAMTB2NsaWVudDEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrn6NhWOvX69jT5Xv/MqGEMLtCtMbR3W+e +v4f4QXGx3smk3nilx2qdcKGCs/vQsvIbcvRHACpMLgeXK3z/4UDULKa0sAJBl7/Y +dffhvqguozJMsi09aNHHuC5pZjeu1BFEcxfhfMamyHcK1P4no9nhjrQLW3u4j+7d +2AiuoMvvP6BznTr6Q95YHl6l5FxNCk9pevO1bDI6b0qR7/NYvpF7fM01yVEyUnvP +sOJBChOn5PXvZbkAQZ4laaYcu8c55YmVxsrrstHdoiXc7322Vocom8S1JXuoVEhx +BtO49bmrm5J7Si1JhAcTXS89r4uJr0g/tVg/5JmuAF3kvve7WsZjAgMBAAGjUjBQ +MB0GA1UdDgQWBBRy6TrHDFXQtgfFDIbeMKcN6zR93TAOBgNVHQ8BAf8EBAMCBaAw +HwYDVR0jBBgwFoAU5obnoO20A2wTKYH+uCuF4ZW6cCswDQYJKoZIhvcNAQELBQAD +ggEBAE3597yVknsz60h4WJGqvARtSaKIL3TDolOVbRG8/mLWGTCa3CguVMLVLE1I +xtnQZVP4Jgaacks7VmZodKNbTkhdsp2SYLtwjVETFn37KmlStO+th2E9x+RCembL +j5q98OzeQzQgiw6f0AnJIilSXW+JDGevTolnUeZNsqBJ5KiZskRDmK+ghQNR1gJ8 +VctMpMJEGl9zM6g+xgwrdqL9RXb6DpArqR2N+EtTp/Tpv3mkunkkficOlMhTYyGi +SXEE6xozLciQk8+EOF9i8leynKxzhera9nDkGeqEHM+5kEoBMGZiJDjLfsT71jfW +QEcYtMb3OsuhRL2yiXMJXwSYsFU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIECLJx+DANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz +ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 +NTRaFw0zMTEyMTIwMDM1NTRaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL +EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsiCAp3sTYiCVjNI3srcuHPa3p7BzGmxqMHeCqOU/ATABYTl9JTFEdqPfUGgS +ubiDQ/DRf0pLmzsJL36eZq3mP7qvbuBE00rqWp4GfYYI8m+3yvVO0a/igLh0kRPV +y9zMXLwIrzMupyAvex5g0xbJ7REu0QONf/Ff8obcowLi0ophH5N05Fx4qU+9nosZ +tuEcS8A7DDMbt9liBVeGNYPenUoH2o9eRZ0YjzoGUNXOLsAW+gT/fn3ZkR8EgUiE +LUjpIpOGWOQo3ro74wvkffs6WjMckoWY+kKfJ9nzL6orIZ9F5lNHwmSfgVaK5hcg +J00jZ4SA7pOvu3MtKcuf0zjzrQIDAQABozIwMDAdBgNVHQ4EFgQU5obnoO20A2wT +KYH+uCuF4ZW6cCswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA +QnKttaZqVCoui8jQlI8uG6T4Wdg5ElYvO05Kz6dpKCBAxxcDXu4B7B+65bqABVXw +KBu70+oXW9TQHE1psBzKeUeMKk8BMV+q8gCFWHNu5tpgp51xqwQGFFOJTm1HiV+S +/WcnrnZe7XIa/bXbdYHz0uQV9fjMCqw354YGRRd1WWkHZYWrp9YucscpTKdGFQJD +uM+poi57NOANSTgTyyZg3cerZTJjBL92XWDfMv93ZVjUE76B6bXvMJLG3Gh9nYEC +epvLX8PSLdbal8ZBcosduxy1dSiQzy7Hj5wsOuj8neoVRaCHmAXouiJDDpQcnasC +p0XXN2RYSD7FW7RNb4xcNQ== +-----END CERTIFICATE----- diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/signers.clientca.pem b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/signers.clientca.pem new file mode 100644 index 0000000000..8cac297081 --- /dev/null +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/signers.clientca.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIECLJx+DANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz +ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 +NTRaFw0zMTEyMTIwMDM1NTRaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL +EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsiCAp3sTYiCVjNI3srcuHPa3p7BzGmxqMHeCqOU/ATABYTl9JTFEdqPfUGgS +ubiDQ/DRf0pLmzsJL36eZq3mP7qvbuBE00rqWp4GfYYI8m+3yvVO0a/igLh0kRPV +y9zMXLwIrzMupyAvex5g0xbJ7REu0QONf/Ff8obcowLi0ophH5N05Fx4qU+9nosZ +tuEcS8A7DDMbt9liBVeGNYPenUoH2o9eRZ0YjzoGUNXOLsAW+gT/fn3ZkR8EgUiE +LUjpIpOGWOQo3ro74wvkffs6WjMckoWY+kKfJ9nzL6orIZ9F5lNHwmSfgVaK5hcg +J00jZ4SA7pOvu3MtKcuf0zjzrQIDAQABozIwMDAdBgNVHQ4EFgQU5obnoO20A2wT +KYH+uCuF4ZW6cCswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA +QnKttaZqVCoui8jQlI8uG6T4Wdg5ElYvO05Kz6dpKCBAxxcDXu4B7B+65bqABVXw +KBu70+oXW9TQHE1psBzKeUeMKk8BMV+q8gCFWHNu5tpgp51xqwQGFFOJTm1HiV+S +/WcnrnZe7XIa/bXbdYHz0uQV9fjMCqw354YGRRd1WWkHZYWrp9YucscpTKdGFQJD +uM+poi57NOANSTgTyyZg3cerZTJjBL92XWDfMv93ZVjUE76B6bXvMJLG3Gh9nYEC +epvLX8PSLdbal8ZBcosduxy1dSiQzy7Hj5wsOuj8neoVRaCHmAXouiJDDpQcnasC +p0XXN2RYSD7FW7RNb4xcNQ== +-----END CERTIFICATE----- diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/trust.serverca.pem b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/trust.serverca.pem new file mode 100644 index 0000000000..389ef06999 --- /dev/null +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/trust.serverca.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz +ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 +NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL +EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc +zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk +rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP +g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 +o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj +lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl +rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA +a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 +kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM +FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 +gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f +P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX +5OQUWOWJqvzyJ8VIbBRDsQ== +-----END CERTIFICATE----- diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/keys.localhost.pem b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/keys.localhost.pem new file mode 100644 index 0000000000..606d0adb0f --- /dev/null +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/keys.localhost.pem @@ -0,0 +1,71 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEMgOIcsjICH10 +jYmaFQrVkoCcc4SNki6XZTHl3eeedv+rOJmoRKkuBNc2+HSfqiDtfrM9r/4PlVcw +woA25NaAhuF7a59nn59GpdwSf6VH+/UPqgrF5ZBt7Kew3FFFg0Q/c5JxwC78xslP +JwDdR9tqJDV5lrljou/XXum6H0W3to8J7r2faP9lHPCyPTu7ddGMFJpZnm2kV6av +tfiqdsKSg1ysXBCLoYaGZXuIe9b3BuAHKWXbkXrRWpN0DqFVRTbVRirLm+GRHPTj +qCO1d3vkfpGPe0sVigrH3sH8Z4+6xQiDLV8hYN4PfFK6rs/QDgBcLRXgoIxNGj4/ +jTBeWJsNAgMBAAECggEALkIMizNlG6TEz6I/e1DSySBNqpWh/y8kRRXa+fOkFLzB +80DZGc92hB8oDxHtjWezc8uXv0erg0kW0axKRqcV3B/xMgRiBTChgSrCBKqL8bj6 +QsM43wgNUZ2mvBB2KQmWIc/CC4fgjEDiXgM4NPQoS5JV+WEMPO3B1unN+dA9w96h +fn/LsuZddxNA6HxwFwLVu40RCA88447Y2BnK8WI5Li8LurlWzCHd94/c5XBlk6bR +8i5KTF8m2mwcA/juTAzDXPc/GxpHnQ+tPofEplnrMf3Pagxze+VBtcDyb2pftfU6 +6U1yYj/DYCEy5D3GftBJaUdGMy3HJKBqytUiXsMxEQKBgQDpXHi45410AHGMCWgA +AeXV2NhL9mPUZp8ayp46ccwU5/Z2+rMA8tqUeCEEygewwH943QmmtgnrRVQkSfVr +tzGrScekMXRWkegGz2hDAjpYcOYAhaxFs8+lZh1C90KMhplSScA0WgUG6v0/GcYP +F9taSMhoSPdVgWT3wpHzu7m8QwKBgQDXOoclWDI4InRBzlG+neEmvGaTnu74F9Gn +8cXZeMvnP3RpeaUPPbYk/lUXB2UwSQL4NmFHjUiu/7/RCyKEEIotesBDoXzJgAwA +3Pa6wj1PyZjw3d/DCj1ie32iASetgvMrWOYMXbBwoAN/9KnAT+jSDYzYoIqgDvqr +XPltek1+bwKBgQDK8fufOujewF//XFLQ5tWd85awAVhyaMjnwNx4kWzdpZnHgWFZ +atrDEfINOzIS+mYhk4GINXpM3J8/a/5+rfQJNgHkfonhm8SA37GZzP822QB95cKb +X7Qu8K50BZsfoRMH6FG6das3h/ez/9MqXyIJ05BOeV54Qy6u9cx+fn0aBwKBgD8y +5HRGzZhGJbUdDEvYuEBTmhtG1AztkZarG9mb6uPgciJ2oc0z5cQ/GmVEuqXPCpwv ++6izB+C7IGwVxPDamnh4TvSM+sOAYgXu3FRCrRY8sDgqLoZq/1Nnx6BGjowYo6ba +19JRwHmRwvVTtnTOAiOL7wu9OHd/boPbLTLEcvTpAoGBAIrjkrrV6wQd41mCIhXx +aTqA/m3Z/+OqMEAGwZhCN/u4IprcdvhviOtOJnfSJIVi8NayRJ96F0NjNYJvol6O +gzR25MFazsDF1WqU7kO5Z9LI3cUq11ChnjM4pBpFnaGeCL5jiM5KYRZL+jjz3iLZ +4dIOj5XwbSpgiTBrWlctf87U +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIEJ36MAjANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz +ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 +NTZaFw0yNjExMTgwMDM1NTZaMF4xEjAQBgNVBAMTCWxvY2FsaG9zdDEUMBIGA1UE +CxMLRGV2ZWxvcG1lbnQxEDAOBgNVBAoTB0FrbGl2dHkxEzARBgNVBAgTCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAxDIDiHLIyAh9dI2JmhUK1ZKAnHOEjZIul2Ux5d3nnnb/qziZqESpLgTXNvh0 +n6og7X6zPa/+D5VXMMKANuTWgIbhe2ufZ5+fRqXcEn+lR/v1D6oKxeWQbeynsNxR +RYNEP3OSccAu/MbJTycA3UfbaiQ1eZa5Y6Lv117puh9Ft7aPCe69n2j/ZRzwsj07 +u3XRjBSaWZ5tpFemr7X4qnbCkoNcrFwQi6GGhmV7iHvW9wbgByll25F60VqTdA6h +VUU21UYqy5vhkRz046gjtXd75H6Rj3tLFYoKx97B/GePusUIgy1fIWDeD3xSuq7P +0A4AXC0V4KCMTRo+P40wXlibDQIDAQABo2gwZjAdBgNVHQ4EFgQU1/dB6JLv7zHW +MMiE5S3Gmq1JUNowDgYDVR0PAQH/BAQDAgWgMBQGA1UdEQQNMAuCCWxvY2FsaG9z +dDAfBgNVHSMEGDAWgBRConr3AcDWR+WtUfnXRjz/2YgPmDANBgkqhkiG9w0BAQsF +AAOCAQEAFjiQb6eJgD83LjM3AIa1wLFAYadtxVrIKC0m59n8quXGUEqBgMgoIgeV +oBoVrtFxgbpmCxYpQpIdLX5jxCFnxvUUB0+NOIGGnR/mJx3qIq+ki3w5fNRSKyZi +6h4ic75SICYlbLh0fM/5kr31K9ZzdKzd/c9rFHAkz0DtIBlYGmE/p7NzXHKu27f9 +prkHH7rCrnij/lzD+nvkQR1lYHFvaPbuVf738jepM6jcS48ik7p4eNlqqj7s40Mo +4oW2aCzIe0RkGiT/9qdvXQxNumocaOgBtVuuWjgqvEZkIDy5ru5KZBiDdgRMrStl +zrhBhPLC/yM4zbl31vB36MIfTmKMKQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz +ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 +NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL +EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc +zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk +rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP +g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 +o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj +lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl +rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA +a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 +kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM +FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 +gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f +P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX +5OQUWOWJqvzyJ8VIbBRDsQ== +-----END CERTIFICATE----- diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/signers.serverca.pem b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/signers.serverca.pem new file mode 100644 index 0000000000..389ef06999 --- /dev/null +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/signers.serverca.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIEEiflHDANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz +ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 +NTNaFw0zMTEyMTIwMDM1NTNaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL +EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAlmDVsfeWIEjypnw6qs0eVwTeM46KqHEvl5ElOyDoZZcqqZQN/jMW/VqzTbLc +zjYE0HqpZNTbaW80kQ1O/VipDmnousimKHg7QtN5KIhsIelnZSQWq8cV2rtSTFDk +rArE659GPWCPr/OeLT3Nbde0p9psz3uh1HJYVWAbZxWOe3GflSC8pGxu3PirU/kP +g89RKRyO5UsF4feHdkJJqUJ92Th4n34DKQcHuwJ3iYxhB9hOlvI4ESIxM+4eWW89 +o4p2B2Ctwt8rpHDoBsNADophBD5kMT4mv6l5J3kVYy65QH7OfUIH22ApFjABdhGj +lCMYtvSCN1Y1lDBU5M9xrBdERwIDAQABozIwMDAdBgNVHQ4EFgQUQqJ69wHA1kfl +rVH510Y8/9mID5gwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA +a56t9nJWGJlZFa8T1pnf9vdAcoQoqZ8LgKcdcxvGDtGdr5QF8L6LOqoYKUvetHv0 +kdvht0fqv3AZivCVyDIpMw17E5mLu5vvdUQM4E+qLNF6SUhO3c/Elylt2/3YKNBM +FgjV0OdepnPz7/0nGCFUJo1fV8obUQt005P/S/F8g6UsIubcb/V55hR9/9Pruvw8 +gqAWNjPJZ0+BlhTgI505K80JFJ7CWZCaseDSeAkXPhb+a29vP2cDsR6wKZeny4+f +P+TPUku7wEo8v+Tr8L1Esmcoudn6Wq+N3ZBYFLH6T4kqP+0BkDoStFDonUFRWxXX +5OQUWOWJqvzyJ8VIbBRDsQ== +-----END CERTIFICATE----- diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/trust.clientca.pem b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/trust.clientca.pem new file mode 100644 index 0000000000..8cac297081 --- /dev/null +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/trust.clientca.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIECLJx+DANBgkqhkiG9w0BAQsFADBeMREwDwYDVQQDEwhz +ZXJ2ZXJjYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxETAPBgNVBAoTCEFrbGl2aXR5 +MRMwEQYDVQQIEwpDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzAeFw0yMTEyMTQwMDM1 +NTRaFw0zMTEyMTIwMDM1NTRaMF4xETAPBgNVBAMTCHNlcnZlcmNhMRQwEgYDVQQL +EwtEZXZlbG9wbWVudDERMA8GA1UEChMIQWtsaXZpdHkxEzARBgNVBAgTCkNhbGlm +b3JuaWExCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsiCAp3sTYiCVjNI3srcuHPa3p7BzGmxqMHeCqOU/ATABYTl9JTFEdqPfUGgS +ubiDQ/DRf0pLmzsJL36eZq3mP7qvbuBE00rqWp4GfYYI8m+3yvVO0a/igLh0kRPV +y9zMXLwIrzMupyAvex5g0xbJ7REu0QONf/Ff8obcowLi0ophH5N05Fx4qU+9nosZ +tuEcS8A7DDMbt9liBVeGNYPenUoH2o9eRZ0YjzoGUNXOLsAW+gT/fn3ZkR8EgUiE +LUjpIpOGWOQo3ro74wvkffs6WjMckoWY+kKfJ9nzL6orIZ9F5lNHwmSfgVaK5hcg +J00jZ4SA7pOvu3MtKcuf0zjzrQIDAQABozIwMDAdBgNVHQ4EFgQU5obnoO20A2wT +KYH+uCuF4ZW6cCswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA +QnKttaZqVCoui8jQlI8uG6T4Wdg5ElYvO05Kz6dpKCBAxxcDXu4B7B+65bqABVXw +KBu70+oXW9TQHE1psBzKeUeMKk8BMV+q8gCFWHNu5tpgp51xqwQGFFOJTm1HiV+S +/WcnrnZe7XIa/bXbdYHz0uQV9fjMCqw354YGRRd1WWkHZYWrp9YucscpTKdGFQJD +uM+poi57NOANSTgTyyZg3cerZTJjBL92XWDfMv93ZVjUE76B6bXvMJLG3Gh9nYEC +epvLX8PSLdbal8ZBcosduxy1dSiQzy7Hj5wsOuj8neoVRaCHmAXouiJDDpQcnasC +p0XXN2RYSD7FW7RNb4xcNQ== +-----END CERTIFICATE----- diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/schema/tls.schema.patch.json b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/schema/tls.schema.patch.json index 14fee5bc53..0bf4c692eb 100644 --- a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/schema/tls.schema.patch.json +++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/schema/tls.schema.patch.json @@ -184,71 +184,83 @@ "path": "/$defs/options/binding/tls", "value": { - "properties": + "properties": + { + "version": + { + "title": "Version", + "type": "string" + }, + "keys": { - "version": + "title": "Vault Keys", + "type": "array", + "items": { - "title": "Version", "type": "string" - }, - "keys": - { - "title": "Vault Keys", - "type": "array", - "items": - { - "type": "string" - } - }, - "trust": + } + }, + "trust": + { + "title": "Vault Certificates", + "type": "array", + "items": { - "title": "Vault Certificates", - "type": "array", - "items": - { - "type": "string" - } - }, - "trustcacerts": + "type": "string" + } + }, + "trustcacerts": + { + "title": "Trust CA Certificates", + "type": "boolean" + }, + "sni": + { + "title": "Server Names", + "type": "array", + "items": { - "title": "Trust CA Certificates", - "type": "boolean" - }, - "sni": + "type": "string" + } + }, + "alpn": + { + "title": "Application Protocols", + "type": "array", + "items": { - "title": "Server Names", - "type": "array", - "items": - { - "type": "string" - } - }, - "alpn": + "type": [ "string", "null" ] + } + }, + "mutual": + { + "title": "Mutual Authentication", + "type": "string", + "enum": [ "required", "requested", "none" ] + }, + "signers": + { + "title": "Vault Signer Certificates", + "type": "array", + "items": { - "title": "Application Protocols", - "type": "array", - "items": - { - "type": [ "string", "null" ] - } - }, - "mutual": + "type": "string" + } + } + }, + "not": + { + "allOf": + [ { - "title": "Mutual Authentication", - "type": "string", - "enum": [ "required", "requested", "none" ] + "required": ["keys"] }, - "signers": { - "title": "Vault Signer Certificates", - "type": "array", - "items": - { - "type": "string" - } + "required": ["signers"] } - }, - "additionalProperties": false + ] + }, + "additionalProperties": false } } ] diff --git a/specs/binding-tls.spec/src/test/java/io/aklivity/zilla/specs/binding/tls/config/SchemaTest.java b/specs/binding-tls.spec/src/test/java/io/aklivity/zilla/specs/binding/tls/config/SchemaTest.java index 16333bb48e..7ec1669ff4 100644 --- a/specs/binding-tls.spec/src/test/java/io/aklivity/zilla/specs/binding/tls/config/SchemaTest.java +++ b/specs/binding-tls.spec/src/test/java/io/aklivity/zilla/specs/binding/tls/config/SchemaTest.java @@ -21,7 +21,6 @@ import jakarta.json.JsonObject; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -32,7 +31,7 @@ public class SchemaTest @Rule public final ConfigSchemaRule schema = new ConfigSchemaRule() .schemaPatch("io/aklivity/zilla/specs/binding/tls/schema/tls.schema.patch.json") - .schemaPatch("io/aklivity/zilla/specs/vault/filesystem/schema/filesystem.schema.patch.json") + .schemaPatch("io/aklivity/zilla/specs/engine/schema/vault/test.schema.patch.json") .configurationRoot("io/aklivity/zilla/specs/binding/tls/config"); @Test @@ -155,15 +154,6 @@ public void shouldValidateServerMutualRequested() assertThat(config, not(nullValue())); } - @Ignore("TODO: realms") - @Test - public void shouldValidateServerRealm() - { - JsonObject config = schema.validate("server.realm.yaml"); - - assertThat(config, not(nullValue())); - } - @Test public void shouldValidateServerSigner() { diff --git a/specs/binding-ws.spec/pom.xml b/specs/binding-ws.spec/pom.xml index 8ef5cba3d0..7fcff636f8 100644 --- a/specs/binding-ws.spec/pom.xml +++ b/specs/binding-ws.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/catalog-apicurio.spec/pom.xml b/specs/catalog-apicurio.spec/pom.xml index 63c9bdc519..41a5615f07 100644 --- a/specs/catalog-apicurio.spec/pom.xml +++ b/specs/catalog-apicurio.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/catalog-filesystem.spec/pom.xml b/specs/catalog-filesystem.spec/pom.xml index 8df20fe530..5b132c0b52 100644 --- a/specs/catalog-filesystem.spec/pom.xml +++ b/specs/catalog-filesystem.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/catalog-inline.spec/pom.xml b/specs/catalog-inline.spec/pom.xml index 7a8269a1f1..54f79dec4b 100644 --- a/specs/catalog-inline.spec/pom.xml +++ b/specs/catalog-inline.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/catalog-karapace.spec/pom.xml b/specs/catalog-karapace.spec/pom.xml index 1ee29c8112..bcd878e8d1 100644 --- a/specs/catalog-karapace.spec/pom.xml +++ b/specs/catalog-karapace.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/catalog-schema-registry.spec/pom.xml b/specs/catalog-schema-registry.spec/pom.xml index 3cc96941e6..fe7979bb88 100644 --- a/specs/catalog-schema-registry.spec/pom.xml +++ b/specs/catalog-schema-registry.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/engine.spec/pom.xml b/specs/engine.spec/pom.xml index 5379216018..d6296b1b16 100644 --- a/specs/engine.spec/pom.xml +++ b/specs/engine.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/binding/test.schema.patch.json b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/binding/test.schema.patch.json index dfbd5c307e..198f370b19 100644 --- a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/binding/test.schema.patch.json +++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/binding/test.schema.patch.json @@ -59,36 +59,60 @@ }, "assertions": { - "catalog": + "title": "Assertions", + "type": "object", + "properties": { - "type": "object", - "patternProperties": + "catalog": { - "^[a-zA-Z]+[a-zA-Z0-9\\._\\-]*$": + "type": "object", + "patternProperties": { - "type": "array", - "items": + "^[a-zA-Z]+[a-zA-Z0-9\\._\\-]*$": { - "type": "object", - "properties": + "type": "array", + "items": { - "id": + "type": "object", + "properties": { - "type": "integer" - }, - "schema": - { - "type": ["string", "null"] - }, - "delay": - { - "type": "number" + "id": + { + "type": "integer" + }, + "schema": + { + "type": ["string", "null"] + }, + "delay": + { + "type": "number" + } } } } - } + }, + "maxProperties": 1 }, - "maxProperties": 1 + "vault": + { + "type": "object", + "properties": + { + "key": + { + "type": "String" + }, + "signer": + { + "type": "String" + }, + "trust": + { + "type": "String" + } + } + } } }, "port": diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/vault/test.schema.patch.json b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/vault/test.schema.patch.json index 01851cebc6..1bcb67068c 100644 --- a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/vault/test.schema.patch.json +++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/vault/test.schema.patch.json @@ -26,6 +26,73 @@ "type": { "const": "test" + }, + "options": + { + "type": "object", + "properties": + { + "key": + { + "type": "object", + "properties": + { + "alias": + { + "type": "string" + }, + "entry": + { + "type": "string" + } + }, + "required": + [ + "alias", + "entry" + ] + }, + "signer": + { + "type": "object", + "properties": + { + "alias": + { + "type": "string" + }, + "entry": + { + "type": "string" + } + }, + "required": + [ + "alias", + "entry" + ] + }, + "trust": + { + "type": "object", + "properties": + { + "alias": + { + "type": "string" + }, + "entry": + { + "type": "string" + } + }, + "required": + [ + "alias", + "entry" + ] + } + } } } } diff --git a/specs/exporter-otlp.spec/pom.xml b/specs/exporter-otlp.spec/pom.xml index 5d8c89b3d7..6e74e01ec8 100644 --- a/specs/exporter-otlp.spec/pom.xml +++ b/specs/exporter-otlp.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/exporter-prometheus.spec/pom.xml b/specs/exporter-prometheus.spec/pom.xml index 2b1ce460c4..f567f3c71c 100644 --- a/specs/exporter-prometheus.spec/pom.xml +++ b/specs/exporter-prometheus.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/exporter-stdout.spec/pom.xml b/specs/exporter-stdout.spec/pom.xml index 3ba1b32ec2..36d7479746 100644 --- a/specs/exporter-stdout.spec/pom.xml +++ b/specs/exporter-stdout.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/filesystem-http.spec/pom.xml b/specs/filesystem-http.spec/pom.xml index e122a56f03..a9de7783ed 100644 --- a/specs/filesystem-http.spec/pom.xml +++ b/specs/filesystem-http.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/guard-jwt.spec/pom.xml b/specs/guard-jwt.spec/pom.xml index e700fc1123..75a66501e5 100644 --- a/specs/guard-jwt.spec/pom.xml +++ b/specs/guard-jwt.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/metrics-grpc.spec/pom.xml b/specs/metrics-grpc.spec/pom.xml index 03c6b37b72..7382463c66 100644 --- a/specs/metrics-grpc.spec/pom.xml +++ b/specs/metrics-grpc.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/metrics-http.spec/pom.xml b/specs/metrics-http.spec/pom.xml index d92f1ada48..f3a1fe8e1f 100644 --- a/specs/metrics-http.spec/pom.xml +++ b/specs/metrics-http.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/metrics-stream.spec/pom.xml b/specs/metrics-stream.spec/pom.xml index 1f55b14030..eff89f4c9c 100644 --- a/specs/metrics-stream.spec/pom.xml +++ b/specs/metrics-stream.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/model-avro.spec/pom.xml b/specs/model-avro.spec/pom.xml index 72ceacd485..6c55dd2e0f 100644 --- a/specs/model-avro.spec/pom.xml +++ b/specs/model-avro.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/model-core.spec/pom.xml b/specs/model-core.spec/pom.xml index 55c2285b91..b3c9c588d8 100644 --- a/specs/model-core.spec/pom.xml +++ b/specs/model-core.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/model-json.spec/pom.xml b/specs/model-json.spec/pom.xml index 36ba6413e0..e09355ca5e 100644 --- a/specs/model-json.spec/pom.xml +++ b/specs/model-json.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/model-protobuf.spec/pom.xml b/specs/model-protobuf.spec/pom.xml index 8b5a9c977d..8be991d02c 100644 --- a/specs/model-protobuf.spec/pom.xml +++ b/specs/model-protobuf.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/pom.xml b/specs/pom.xml index 8b82c73e9a..a6bc134f00 100644 --- a/specs/pom.xml +++ b/specs/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla zilla - 0.9.92 + 0.9.93 ../pom.xml diff --git a/specs/vault-filesystem.spec/pom.xml b/specs/vault-filesystem.spec/pom.xml index 0411eeb1f3..14bf2f8a53 100644 --- a/specs/vault-filesystem.spec/pom.xml +++ b/specs/vault-filesystem.spec/pom.xml @@ -8,7 +8,7 @@ io.aklivity.zilla specs - 0.9.92 + 0.9.93 ../pom.xml