diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index a8024d1a35..419e015628 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -33,11 +33,14 @@ jobs:
restore-keys: ${{ runner.os }}-m2
- name: Build with Maven
run: ./mvnw -B -U -nsu -Ddocker.logStdout -Dfailsafe.skipAfterFailureCount=1 -Ddocker.verbose install jacoco:report-aggregate
+ env:
+ GITHUB_ACTOR: ${{ github.actor }}
+ GITHUB_TOKEN: ${{ github.token }}
- name: Conditional Artifact Upload
uses: actions/upload-artifact@v4
if: failure()
with:
- name: zilla-build-${{ github.event.number }}
+ name: zilla-build-${{ matrix.java }}-${{ github.event.number }}
path: |
**/hs_err_pid*.log
**/target/surefire-reports/
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 3de9762eea..8b44379671 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -48,6 +48,12 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
+ - name: Setup JDK 17
+ uses: actions/setup-java@v4
+ with:
+ distribution: zulu
+ java-version: 17
+
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
@@ -74,6 +80,9 @@ jobs:
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
+ env:
+ GITHUB_ACTOR: ${{ github.actor }}
+ GITHUB_TOKEN: ${{ github.token }}
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0098da6a19..30ae218f3c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,36 @@
## [Unreleased](https://github.com/aklivity/zilla/tree/HEAD)
-[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.81...HEAD)
+[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.82...HEAD)
+
+**Implemented enhancements:**
+
+- Add asyncapi http-kafka proxy example [\#1077](https://github.com/aklivity/zilla/issues/1077)
+- Use miliseconds in metrics [\#1069](https://github.com/aklivity/zilla/issues/1069)
+- Promote `filesystem` catalog out of incubator [\#1068](https://github.com/aklivity/zilla/issues/1068)
+- Support `asyncapi` mapping `http` protocol to `kafka` protocol [\#1063](https://github.com/aklivity/zilla/issues/1063)
+- Support filtering by kafka structured value field\(s\) [\#1062](https://github.com/aklivity/zilla/issues/1062)
+- Support remote zilla configuration with change detection [\#1061](https://github.com/aklivity/zilla/issues/1061)
+- Use full Event ID and the event name [\#1013](https://github.com/aklivity/zilla/issues/1013)
+- Support configuration of MQTT Publish QoS maximum [\#970](https://github.com/aklivity/zilla/issues/970)
+- Support `sse` server and client via `asyncapi` [\#952](https://github.com/aklivity/zilla/issues/952)
+- Review kafka binding partition offset vs progress offset [\#285](https://github.com/aklivity/zilla/issues/285)
+
+**Fixed bugs:**
+
+- iNotify error when multiple Zilla instances are started in K8s Pods on a Portainer.io host [\#1081](https://github.com/aklivity/zilla/issues/1081)
+- Running `emqtt_bench` `sub` triggers an exception [\#1037](https://github.com/aklivity/zilla/issues/1037)
+- MqttSessionBeginEx missing packetIds in zilla dump [\#1028](https://github.com/aklivity/zilla/issues/1028)
+- Running `emqtt_bench` triggers an exception in mqtt during the decoding [\#999](https://github.com/aklivity/zilla/issues/999)
+- Intermittent NPE when trying to resolve guards [\#994](https://github.com/aklivity/zilla/issues/994)
+
+**Closed issues:**
+
+- Add SSE payload validation to sse-server binding [\#1076](https://github.com/aklivity/zilla/issues/1076)
+
+## [0.9.82](https://github.com/aklivity/zilla/tree/0.9.82) (2024-05-28)
+
+[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.81...0.9.82)
**Fixed bugs:**
@@ -11,6 +40,15 @@
- Running `emqtt_bench` both `sub` and `pub` triggers an exception [\#1000](https://github.com/aklivity/zilla/issues/1000)
- `http-kafka` will `fetch` messages that have been deleted by a retention policy [\#897](https://github.com/aklivity/zilla/issues/897)
+**Merged pull requests:**
+
+- Update to handle catalog IT validation\(resolve schema from subject\) [\#1055](https://github.com/aklivity/zilla/pull/1055) ([aDaemonThread](https://github.com/aDaemonThread))
+- Queue as different kafka produce request if producerId or producerEpoch varies [\#1053](https://github.com/aklivity/zilla/pull/1053) ([akrambek](https://github.com/akrambek))
+- Support kafka cache bootstrap with topic default offset live [\#1052](https://github.com/aklivity/zilla/pull/1052) ([jfallows](https://github.com/jfallows))
+- Set decoder to ignoreAll after session is taken over by other MQTT client [\#1045](https://github.com/aklivity/zilla/pull/1045) ([bmaidics](https://github.com/bmaidics))
+- Add detection of non-compacted session topic [\#1044](https://github.com/aklivity/zilla/pull/1044) ([bmaidics](https://github.com/bmaidics))
+- Fix: http-kafka will fetch messages that have been deleted by a reten… [\#1033](https://github.com/aklivity/zilla/pull/1033) ([aDaemonThread](https://github.com/aDaemonThread))
+
## [0.9.81](https://github.com/aklivity/zilla/tree/0.9.81) (2024-05-24)
[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.80...0.9.81)
diff --git a/build/flyweight-maven-plugin/pom.xml b/build/flyweight-maven-plugin/pom.xml
index 7fe2d1eb72..6692db35fe 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.82
+ 0.9.83
../pom.xml
@@ -17,8 +17,6 @@
zilla::build::flyweight-maven-plugin
- 9
- 9
0.82
2
diff --git a/build/pom.xml b/build/pom.xml
index 5e58384b6f..308a4332e5 100644
--- a/build/pom.xml
+++ b/build/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.82
+ 0.9.83
../pom.xml
diff --git a/cloud/docker-image/pom.xml b/cloud/docker-image/pom.xml
index 60db60ec9b..7e7d0d3603 100644
--- a/cloud/docker-image/pom.xml
+++ b/cloud/docker-image/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
cloud
- 0.9.82
+ 0.9.83
../pom.xml
@@ -253,6 +253,12 @@
${project.version}
runtime
+
+ ${project.groupId}
+ filesystem-http
+ ${project.version}
+ runtime
+
${project.groupId}
metrics-stream
diff --git a/cloud/docker-image/src/main/docker/Dockerfile b/cloud/docker-image/src/main/docker/Dockerfile
index 6717305625..a0d0261cc9 100644
--- a/cloud/docker-image/src/main/docker/Dockerfile
+++ b/cloud/docker-image/src/main/docker/Dockerfile
@@ -13,7 +13,7 @@
# specific language governing permissions and limitations under the License.
#
-FROM eclipse-temurin:21-jdk AS build
+FROM eclipse-temurin:22-jdk AS build
COPY maven /root/.m2/repository
@@ -25,7 +25,7 @@ RUN cat zpm.json.template | sed "s/\${VERSION}/${project.version}/g" | tee zpm.j
RUN ./zpmw install --debug --exclude-remote-repositories
RUN ./zpmw clean --keep-image
-FROM ubuntu:jammy-20240427
+FROM ubuntu:jammy-20240530
ENV ZILLA_VERSION ${project.version}
diff --git a/cloud/docker-image/src/main/docker/alpine.Dockerfile b/cloud/docker-image/src/main/docker/alpine.Dockerfile
index 4dc74d18e9..83a763b034 100644
--- a/cloud/docker-image/src/main/docker/alpine.Dockerfile
+++ b/cloud/docker-image/src/main/docker/alpine.Dockerfile
@@ -27,7 +27,7 @@ RUN apk add --no-cache wget
RUN ./zpmw install --debug --exclude-remote-repositories
RUN ./zpmw clean --keep-image
-FROM alpine:3.19.1
+FROM alpine:3.20.0
ENV ZILLA_VERSION ${project.version}
diff --git a/cloud/docker-image/src/main/docker/assembly.xml b/cloud/docker-image/src/main/docker/assembly.xml
index ca3954717b..7e0d989f1a 100644
--- a/cloud/docker-image/src/main/docker/assembly.xml
+++ b/cloud/docker-image/src/main/docker/assembly.xml
@@ -30,6 +30,7 @@
io/aklivity/zilla/binding-*/**
io/aklivity/zilla/catalog-*/**
io/aklivity/zilla/exporter-*/**
+ io/aklivity/zilla/filesystem-*/**
io/aklivity/zilla/guard-*/**
io/aklivity/zilla/metrics-*/**
io/aklivity/zilla/model-*/**
diff --git a/cloud/docker-image/src/main/docker/zpm.json.template b/cloud/docker-image/src/main/docker/zpm.json.template
index 46961f11bb..7a792ce44d 100644
--- a/cloud/docker-image/src/main/docker/zpm.json.template
+++ b/cloud/docker-image/src/main/docker/zpm.json.template
@@ -50,6 +50,7 @@
"io.aklivity.zilla:exporter-otlp",
"io.aklivity.zilla:exporter-prometheus",
"io.aklivity.zilla:exporter-stdout",
+ "io.aklivity.zilla:filesystem-http",
"io.aklivity.zilla:guard-jwt",
"io.aklivity.zilla:metrics-stream",
"io.aklivity.zilla:metrics-http",
diff --git a/cloud/helm-chart/pom.xml b/cloud/helm-chart/pom.xml
index 9851b6e26b..ed922aab4c 100644
--- a/cloud/helm-chart/pom.xml
+++ b/cloud/helm-chart/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
cloud
- 0.9.82
+ 0.9.83
../pom.xml
diff --git a/cloud/helm-chart/src/main/helm/zilla/helmfile.yaml b/cloud/helm-chart/src/main/helm/zilla/helmfile.yaml
new file mode 100644
index 0000000000..2aef15c088
--- /dev/null
+++ b/cloud/helm-chart/src/main/helm/zilla/helmfile.yaml
@@ -0,0 +1,15 @@
+helmDefaults:
+ wait: true
+ createNamespace: true
+
+releases:
+- name: zilla
+ namespace: zilla
+ chart: oci://ghcr.io/aklivity/charts/zilla
+ version: ^0.9.0
+ set:
+ # single value loaded from a local file, translates to --set-file zilla\\.yaml=zilla.yaml
+ # as described in: https://artifacthub.io/packages/helm/zilla/zilla#configuration
+ - name: "zilla\\.yaml"
+ file: zilla.yaml
+
diff --git a/cloud/helm-chart/src/main/helm/zilla/templates/deployment.yaml b/cloud/helm-chart/src/main/helm/zilla/templates/deployment.yaml
index 73ea458bdd..55ed56c670 100644
--- a/cloud/helm-chart/src/main/helm/zilla/templates/deployment.yaml
+++ b/cloud/helm-chart/src/main/helm/zilla/templates/deployment.yaml
@@ -97,6 +97,11 @@ spec:
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
+ {{- if .Values.volumeMounts }}
+ {{- with .Values.volumeMounts }}
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- end }}
{{- if index .Values "zilla.yaml" }}
- name: {{ include "zilla.fullname" . }}
mountPath: {{ .Values.configPath }}
@@ -127,6 +132,11 @@ spec:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
+ {{- if .Values.volumes }}
+ {{- with .Values.volumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- end }}
{{- if index .Values "zilla.yaml" }}
- name: {{ include "zilla.fullname" . }}
configMap:
diff --git a/cloud/pom.xml b/cloud/pom.xml
index 1646b94827..c484c32f63 100644
--- a/cloud/pom.xml
+++ b/cloud/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.82
+ 0.9.83
../pom.xml
diff --git a/conf/pom.xml b/conf/pom.xml
index 9b641dfcc4..33eee448db 100644
--- a/conf/pom.xml
+++ b/conf/pom.xml
@@ -8,16 +8,11 @@
io.aklivity.zilla
zilla
- 0.9.82
+ 0.9.83
../pom.xml
conf
zilla::conf
-
- 11
- 11
-
-
diff --git a/incubator/binding-amqp.spec/pom.xml b/incubator/binding-amqp.spec/pom.xml
index 263615131a..2e142775d2 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.82
+ 0.9.83
../pom.xml
@@ -24,16 +24,14 @@
- 11
- 11
0.98
0
- org.kaazing
- k3po.lang
+ io.aklivity.k3po
+ lang
provided
@@ -47,8 +45,8 @@
test
- org.kaazing
- k3po.junit
+ io.aklivity.k3po
+ control-junit
test
@@ -110,7 +108,7 @@
moditect-maven-plugin
- org.kaazing
+ io.aklivity.k3po
k3po-maven-plugin
diff --git a/incubator/binding-amqp.spec/src/main/java/io/aklivity/zilla/specs/binding/amqp/internal/AmqpFunctions.java b/incubator/binding-amqp.spec/src/main/java/io/aklivity/zilla/specs/binding/amqp/internal/AmqpFunctions.java
index 10348ac0ba..4690f3f925 100644
--- a/incubator/binding-amqp.spec/src/main/java/io/aklivity/zilla/specs/binding/amqp/internal/AmqpFunctions.java
+++ b/incubator/binding-amqp.spec/src/main/java/io/aklivity/zilla/specs/binding/amqp/internal/AmqpFunctions.java
@@ -26,10 +26,10 @@
import org.agrona.DirectBuffer;
import org.agrona.MutableDirectBuffer;
import org.agrona.concurrent.UnsafeBuffer;
-import org.kaazing.k3po.lang.el.BytesMatcher;
-import org.kaazing.k3po.lang.el.Function;
-import org.kaazing.k3po.lang.el.spi.FunctionMapperSpi;
+import io.aklivity.k3po.runtime.lang.el.BytesMatcher;
+import io.aklivity.k3po.runtime.lang.el.Function;
+import io.aklivity.k3po.runtime.lang.el.spi.FunctionMapperSpi;
import io.aklivity.zilla.specs.binding.amqp.internal.types.AmqpAnnotationFW;
import io.aklivity.zilla.specs.binding.amqp.internal.types.AmqpApplicationPropertyFW;
import io.aklivity.zilla.specs.binding.amqp.internal.types.AmqpBinaryFW;
diff --git a/incubator/binding-amqp.spec/src/main/resources/META-INF/services/org.kaazing.k3po.lang.el.spi.FunctionMapperSpi b/incubator/binding-amqp.spec/src/main/resources/META-INF/services/io.aklivity.k3po.runtime.lang.el.spi.FunctionMapperSpi
similarity index 100%
rename from incubator/binding-amqp.spec/src/main/resources/META-INF/services/org.kaazing.k3po.lang.el.spi.FunctionMapperSpi
rename to incubator/binding-amqp.spec/src/main/resources/META-INF/services/io.aklivity.k3po.runtime.lang.el.spi.FunctionMapperSpi
diff --git a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/internal/AmqpFunctionsTest.java b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/internal/AmqpFunctionsTest.java
index 24c1392412..d4f8493025 100644
--- a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/internal/AmqpFunctionsTest.java
+++ b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/internal/AmqpFunctionsTest.java
@@ -15,6 +15,7 @@
*/
package io.aklivity.zilla.specs.binding.amqp.internal;
+import static io.aklivity.k3po.runtime.lang.internal.el.ExpressionFactoryUtils.newExpressionFactory;
import static io.aklivity.zilla.specs.binding.amqp.internal.AmqpFunctions.abortEx;
import static io.aklivity.zilla.specs.binding.amqp.internal.AmqpFunctions.beginEx;
import static io.aklivity.zilla.specs.binding.amqp.internal.AmqpFunctions.binary32;
@@ -55,7 +56,6 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.kaazing.k3po.lang.internal.el.ExpressionFactoryUtils.newExpressionFactory;
import java.nio.ByteBuffer;
@@ -67,9 +67,9 @@
import org.agrona.concurrent.UnsafeBuffer;
import org.junit.Before;
import org.junit.Test;
-import org.kaazing.k3po.lang.el.BytesMatcher;
-import org.kaazing.k3po.lang.internal.el.ExpressionContext;
+import io.aklivity.k3po.runtime.lang.el.BytesMatcher;
+import io.aklivity.k3po.runtime.lang.internal.el.ExpressionContext;
import io.aklivity.zilla.specs.binding.amqp.internal.AmqpFunctions.AmqpBeginExBuilder;
import io.aklivity.zilla.specs.binding.amqp.internal.types.AmqpPropertiesFW;
import io.aklivity.zilla.specs.binding.amqp.internal.types.stream.AmqpAbortExFW;
diff --git a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/application/StreamIT.java b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/application/StreamIT.java
index 67f981b4e6..5bd7355615 100644
--- a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/application/StreamIT.java
+++ b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/application/StreamIT.java
@@ -23,8 +23,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
public class StreamIT
{
diff --git a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/ConnectionIT.java b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/ConnectionIT.java
index 1056eabf2a..b13c380295 100644
--- a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/ConnectionIT.java
+++ b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/ConnectionIT.java
@@ -23,8 +23,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
public class ConnectionIT
{
diff --git a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/LinkIT.java b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/LinkIT.java
index 6a42c827cb..4ab12b6161 100644
--- a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/LinkIT.java
+++ b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/LinkIT.java
@@ -23,8 +23,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
public class LinkIT
{
diff --git a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/SessionIT.java b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/SessionIT.java
index 33af93a300..d686c2b5c4 100644
--- a/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/SessionIT.java
+++ b/incubator/binding-amqp.spec/src/test/java/io/aklivity/zilla/specs/binding/amqp/streams/network/SessionIT.java
@@ -23,8 +23,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
public class SessionIT
{
diff --git a/incubator/binding-amqp/pom.xml b/incubator/binding-amqp/pom.xml
index 17e5b260b3..af6c107cf6 100644
--- a/incubator/binding-amqp/pom.xml
+++ b/incubator/binding-amqp/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.82
+ 0.9.83
../pom.xml
@@ -24,8 +24,6 @@
- 11
- 11
0.71
1
@@ -66,13 +64,13 @@
test
- org.kaazing
- k3po.junit
+ io.aklivity.k3po
+ control-junit
test
- org.kaazing
- k3po.lang
+ io.aklivity.k3po
+ lang
test
@@ -167,7 +165,7 @@
- org.kaazing
+ io.aklivity.k3po
k3po-maven-plugin
diff --git a/incubator/binding-amqp/src/test/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/server/AdvisoryIT.java b/incubator/binding-amqp/src/test/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/server/AdvisoryIT.java
index c38b02dd34..6de793b651 100644
--- a/incubator/binding-amqp/src/test/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/server/AdvisoryIT.java
+++ b/incubator/binding-amqp/src/test/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/server/AdvisoryIT.java
@@ -26,9 +26,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+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;
diff --git a/incubator/binding-amqp/src/test/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/server/AmqpServerIT.java b/incubator/binding-amqp/src/test/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/server/AmqpServerIT.java
index 2f3e2218b8..8cea06c1bb 100644
--- a/incubator/binding-amqp/src/test/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/server/AmqpServerIT.java
+++ b/incubator/binding-amqp/src/test/java/io/aklivity/zilla/runtime/binding/amqp/internal/stream/server/AmqpServerIT.java
@@ -32,9 +32,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+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;
import io.aklivity.zilla.runtime.engine.test.annotation.Configure;
diff --git a/incubator/command-dump/pom.xml b/incubator/command-dump/pom.xml
index cfcbf7e651..b2b7f67e65 100644
--- a/incubator/command-dump/pom.xml
+++ b/incubator/command-dump/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.82
+ 0.9.83
../pom.xml
@@ -24,8 +24,6 @@
- 11
- 11
1.00
0
@@ -62,13 +60,13 @@
provided
- org.kaazing
- k3po.junit
+ io.aklivity.k3po
+ control-junit
test
- org.kaazing
- k3po.lang
+ io.aklivity.k3po
+ lang
test
@@ -182,7 +180,7 @@
moditect-maven-plugin
- org.kaazing
+ io.aklivity.k3po
k3po-maven-plugin
diff --git a/incubator/command-dump/src/main/resources/io/aklivity/zilla/runtime/command/dump/internal/airline/zilla.lua b/incubator/command-dump/src/main/resources/io/aklivity/zilla/runtime/command/dump/internal/airline/zilla.lua
index 60bf401234..f2514b7e5b 100644
--- a/incubator/command-dump/src/main/resources/io/aklivity/zilla/runtime/command/dump/internal/airline/zilla.lua
+++ b/incubator/command-dump/src/main/resources/io/aklivity/zilla/runtime/command/dump/internal/airline/zilla.lua
@@ -436,6 +436,7 @@ local fields = {
mqtt_ext_subscribe_qos_max = ProtoField.uint16("zilla.mqtt_ext.subscribe_qos_max", "Subscribe QoS Maximum", base.DEC),
mqtt_ext_publish_qos_max = ProtoField.uint16("zilla.mqtt_ext.publish_qos_max", "Publish QoS Maximum", base.DEC),
mqtt_ext_packet_size_max = ProtoField.uint32("zilla.mqtt_ext.packet_size_max", "Packet Size Maximum", base.DEC),
+ mqtt_ext_packet_ids_array_size = ProtoField.int8("zilla.mqtt_ext.packet_ids_array_size", "Size", base.DEC),
-- capabilities
mqtt_ext_capabilities = ProtoField.uint8("zilla.mqtt_ext.capabilities", "Capabilities", base.HEX),
mqtt_ext_capabilities_retain = ProtoField.uint8("zilla.mqtt_ext.capabilities_retain", "RETAIN",
@@ -1755,6 +1756,29 @@ function handle_mqtt_begin_session_extension(buffer, offset, ext_subtree)
local client_id_length, slice_client_id_length, slice_client_id_text = dissect_length_value(buffer, client_id_offset, 2)
add_string_as_subtree(buffer(client_id_offset, client_id_length), ext_subtree, "Client ID: %s",
slice_client_id_length, slice_client_id_text, fields.mqtt_ext_client_id_length, fields.mqtt_ext_client_id)
+ -- packet_ids
+ local packet_ids_offset = client_id_offset + client_id_length
+ local next_offset = dissect_and_add_mqtt_packet_ids(buffer, packet_ids_offset, ext_subtree)
+end
+
+function dissect_and_add_mqtt_packet_ids(buffer, offset, tree)
+ local size_length = 1
+ local slice_array_size = buffer(offset, size_length)
+ local array_size = slice_array_size:le_int();
+ local label = string.format("Packet IDs (%d items)", array_size)
+ local array_subtree = tree:add(zilla_protocol, slice_array_size, label)
+ array_subtree:add_le(fields.mqtt_ext_packet_ids_array_size, slice_array_size)
+ local item_offset = offset + size_length
+ for i = 1, array_size do
+ -- packet_id
+ local item_length = 2
+ local slice_packet_id = buffer(item_offset, item_length)
+ local label = string.format("Packet ID: 0x%04x", slice_packet_id:le_int())
+ local item_subtree = tree:add(zilla_protocol, slice_packet_id, label)
+ item_subtree:add_le(fields.mqtt_ext_packet_id, slice_packet_id)
+ item_offset = item_offset + item_length
+ end
+ return item_offset
end
function handle_mqtt_data_publish_extension(buffer, offset, ext_subtree)
diff --git a/incubator/command-dump/src/main/scripts/io/aklivity/zilla/runtime/command/dump/binding/tls/streams/network/connection.established/client.rpt b/incubator/command-dump/src/main/scripts/io/aklivity/zilla/runtime/command/dump/binding/tls/streams/network/connection.established/client.rpt
index baeb1fe4be..30ce31ec3f 100644
--- a/incubator/command-dump/src/main/scripts/io/aklivity/zilla/runtime/command/dump/binding/tls/streams/network/connection.established/client.rpt
+++ b/incubator/command-dump/src/main/scripts/io/aklivity/zilla/runtime/command/dump/binding/tls/streams/network/connection.established/client.rpt
@@ -19,6 +19,7 @@ connect "tls://localhost:9090"
option tls:transport "zilla://streams/net0"
option tls:trustStoreFile ${core:file('src/test/democa/client/trust')}
option tls:trustStorePassword "generated"
+ option tls:cipherSuites "TLS_AES_256_GCM_SHA384"
option zilla:ephemeral "test"
option zilla:timestamps "false"
option zilla:authorization ${authorization}
diff --git a/incubator/command-dump/src/main/scripts/io/aklivity/zilla/runtime/command/dump/binding/tls/streams/network/connection.established/server.rpt b/incubator/command-dump/src/main/scripts/io/aklivity/zilla/runtime/command/dump/binding/tls/streams/network/connection.established/server.rpt
index ef2b51cfd5..2c98b0fa1c 100644
--- a/incubator/command-dump/src/main/scripts/io/aklivity/zilla/runtime/command/dump/binding/tls/streams/network/connection.established/server.rpt
+++ b/incubator/command-dump/src/main/scripts/io/aklivity/zilla/runtime/command/dump/binding/tls/streams/network/connection.established/server.rpt
@@ -19,6 +19,7 @@ accept "tls://localhost:9090"
option tls:transport "zilla://streams/net0"
option tls:keyStoreFile ${core:file('src/test/democa/server/keys')}
option tls:keyStorePassword "generated"
+ option tls:cipherSuites "TLS_AES_256_GCM_SHA384"
option zilla:timestamps "false"
option zilla:authorization ${authorization}
option zilla:window 65536
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/AmqpLinkNetworkIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/AmqpLinkNetworkIT.java
index 532c87be16..92ce401f21 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/AmqpLinkNetworkIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/AmqpLinkNetworkIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class AmqpLinkNetworkIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/AmqpStreamApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/AmqpStreamApplicationIT.java
index 82ebda73e8..2cd83d50bc 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/AmqpStreamApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/AmqpStreamApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class AmqpStreamApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/FileSystemApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/FileSystemApplicationIT.java
index 2f9fba05cb..b510f10724 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/FileSystemApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/FileSystemApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class FileSystemApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/GrpcServerStreamRpcApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/GrpcServerStreamRpcApplicationIT.java
index e43237ad36..d9be61b006 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/GrpcServerStreamRpcApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/GrpcServerStreamRpcApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class GrpcServerStreamRpcApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/Http2AuthorizationApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/Http2AuthorizationApplicationIT.java
index af8ea39f9b..0a997caee3 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/Http2AuthorizationApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/Http2AuthorizationApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class Http2AuthorizationApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/Http2AuthorizationNetworkIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/Http2AuthorizationNetworkIT.java
index af9d8b3fb4..ce38764dde 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/Http2AuthorizationNetworkIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/Http2AuthorizationNetworkIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class Http2AuthorizationNetworkIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaDescribeApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaDescribeApplicationIT.java
index 7d368e082c..0cbc56e704 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaDescribeApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaDescribeApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaDescribeApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaDescribeConfigsNetworkIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaDescribeConfigsNetworkIT.java
index 02a56dda71..5492e29c23 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaDescribeConfigsNetworkIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaDescribeConfigsNetworkIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaDescribeConfigsNetworkIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaFetchApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaFetchApplicationIT.java
index 1a6320c645..641a123d32 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaFetchApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaFetchApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaFetchApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaGroupApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaGroupApplicationIT.java
index 390cb35616..50ea4907bf 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaGroupApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaGroupApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaGroupApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaInitProducerIdApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaInitProducerIdApplicationIT.java
index 34bfa3cfc3..8e6ee19b3d 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaInitProducerIdApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaInitProducerIdApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaInitProducerIdApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaMergedApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaMergedApplicationIT.java
index 8ba4b53d5b..7879a458cb 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaMergedApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaMergedApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaMergedApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaMetaApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaMetaApplicationIT.java
index ac0453200d..786e2e6941 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaMetaApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaMetaApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaMetaApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaOffsetCommitApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaOffsetCommitApplicationIT.java
index 3f7ad2f928..b443f07a61 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaOffsetCommitApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaOffsetCommitApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaOffsetCommitApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaOffsetFetchApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaOffsetFetchApplicationIT.java
index 2d510ed522..9b2fcf5c3f 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaOffsetFetchApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaOffsetFetchApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaOffsetFetchApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaProduceApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaProduceApplicationIT.java
index 27b65ccea9..896c403d73 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaProduceApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/KafkaProduceApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class KafkaProduceApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishApplicationIT.java
index 42dce7b92d..a84eec4f6d 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class MqttPublishApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishNetworkIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishNetworkIT.java
index 6b6885aa53..bce1d762df 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishNetworkIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishNetworkIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class MqttPublishNetworkIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttSubscribeApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttSubscribeApplicationIT.java
index baeced6908..e13570da1d 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttSubscribeApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/MqttSubscribeApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class MqttSubscribeApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/ProxyApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/ProxyApplicationIT.java
index 84bfe12f51..3b411afd15 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/ProxyApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/ProxyApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class ProxyApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/SseDataApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/SseDataApplicationIT.java
index ee638426ae..8113305b4d 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/SseDataApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/SseDataApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class SseDataApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/TlsApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/TlsApplicationIT.java
index ab54aae486..fb11dcbd43 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/TlsApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/TlsApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class TlsApplicationIT
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/TlsNetworkIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/TlsNetworkIT.java
index 714f1e51b5..6864b2054e 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/TlsNetworkIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/TlsNetworkIT.java
@@ -17,15 +17,14 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.rules.RuleChain.outerRule;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class TlsNetworkIT
@@ -42,7 +41,6 @@ public class TlsNetworkIT
@Rule
public final TestRule chain = outerRule(dump).around(k3po).around(timeout);
- @Ignore
@Test
@Specification({
"${net}/connection.established/client",
diff --git a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/WsAdvisoryApplicationIT.java b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/WsAdvisoryApplicationIT.java
index b5e77248c9..4837c48fa3 100644
--- a/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/WsAdvisoryApplicationIT.java
+++ b/incubator/command-dump/src/test/java/io/aklivity/zilla/runtime/command/dump/internal/WsAdvisoryApplicationIT.java
@@ -22,9 +22,9 @@
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
-import org.kaazing.k3po.junit.annotation.Specification;
-import org.kaazing.k3po.junit.rules.K3poRule;
+import io.aklivity.k3po.runtime.junit.annotation.Specification;
+import io.aklivity.k3po.runtime.junit.rules.K3poRule;
import io.aklivity.zilla.runtime.command.dump.internal.test.DumpRule;
public class WsAdvisoryApplicationIT
diff --git a/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishApplicationIT_shouldSendOneMessage.txt b/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishApplicationIT_shouldSendOneMessage.txt
index dc9ddd9f38..86a3b369d2 100644
--- a/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishApplicationIT_shouldSendOneMessage.txt
+++ b/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/MqttPublishApplicationIT_shouldSendOneMessage.txt
@@ -45,6 +45,8 @@ Zilla Frame
Client ID: client
Length: 6
Client ID: client
+ Packet IDs (-1 items)
+ Size: -1
Frame 2: 230 bytes on wire (1840 bits), 230 bytes captured (1840 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
@@ -93,6 +95,8 @@ Zilla Frame
Client ID: client
Length: 6
Client ID: client
+ Packet IDs (-1 items)
+ Size: -1
Frame 3: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
diff --git a/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/MqttSubscribeApplicationIT_shouldReceiveOneMessage.txt b/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/MqttSubscribeApplicationIT_shouldReceiveOneMessage.txt
index d19231b7ce..5a0f56ff1d 100644
--- a/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/MqttSubscribeApplicationIT_shouldReceiveOneMessage.txt
+++ b/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/MqttSubscribeApplicationIT_shouldReceiveOneMessage.txt
@@ -45,6 +45,8 @@ Zilla Frame
Client ID: client
Length: 6
Client ID: client
+ Packet IDs (-1 items)
+ Size: -1
Frame 2: 230 bytes on wire (1840 bits), 230 bytes captured (1840 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
@@ -93,6 +95,8 @@ Zilla Frame
Client ID: client
Length: 6
Client ID: client
+ Packet IDs (-1 items)
+ Size: -1
Frame 3: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
diff --git a/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/TlsNetworkIT_shouldEstablishConnection.txt b/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/TlsNetworkIT_shouldEstablishConnection.txt
index 3d03b419b8..9e9f90aea6 100644
--- a/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/TlsNetworkIT_shouldEstablishConnection.txt
+++ b/incubator/command-dump/src/test/resources/io/aklivity/zilla/runtime/command/dump/internal/TlsNetworkIT_shouldEstablishConnection.txt
@@ -124,10 +124,10 @@ Zilla Frame
Progress: 0
Progress/Maximum: 0/65536
-Frame 5: 693 bytes on wire (5544 bits), 693 bytes captured (5544 bits)
+Frame 5: 548 bytes on wire (4384 bits), 548 bytes captured (4384 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:2, Dst: fe80::3f3f:0:0:3
-Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 265, Ack: 266, Len: 619
+Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 265, Ack: 266, Len: 474
Zilla Frame
Frame Type ID: 0x00000002
Frame Type: DATA
@@ -157,25 +157,25 @@ Zilla Frame
.... .0.. = INCOMPLETE: Not set (0)
.... 0... = SKIP: Not set (0)
Budget ID: 0x0000000000000000
- Reserved: 482
- Progress: 482
- Progress/Maximum: 482/65536
+ Reserved: 337
+ Progress: 337
+ Progress/Maximum: 337/65536
Payload
- Length: 482
+ Length: 337
Payload
Transport Layer Security
Frame 6: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:2, Dst: fe80::3f3f:0:0:3
-Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 884, Ack: 266, Len: 137
+Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 739, Ack: 266, Len: 137
Zilla Frame
Frame Type ID: 0x40000002
Frame Type: WINDOW
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x000003b0
+ Offset: 0x00000320
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -186,8 +186,8 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: INI
- Sequence: 482
- Acknowledge: 482
+ Sequence: 337
+ Acknowledge: 337
Maximum: 65536
Timestamp: 0x0000000000000000
Trace ID: 0x8000000000000006
@@ -202,14 +202,14 @@ Zilla Frame
Frame 7: 338 bytes on wire (2704 bits), 338 bytes captured (2704 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 266, Ack: 1021, Len: 264
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 266, Ack: 876, Len: 264
Zilla Frame
Frame Type ID: 0x00000002
Frame Type: DATA
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00000410
+ Offset: 0x00000380
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -243,14 +243,14 @@ Transport Layer Security
Frame 8: 217 bytes on wire (1736 bits), 217 bytes captured (1736 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 530, Ack: 1021, Len: 143
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 530, Ack: 876, Len: 143
Zilla Frame
Frame Type ID: 0x00000002
Frame Type: DATA
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x000004f0
+ Offset: 0x00000460
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -284,14 +284,14 @@ Transport Layer Security
Frame 9: 2433 bytes on wire (19464 bits), 2433 bytes captured (19464 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 673, Ack: 1021, Len: 2359
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 673, Ack: 876, Len: 2359
Zilla Frame
Frame Type ID: 0x00000002
Frame Type: DATA
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00000558
+ Offset: 0x000004c8
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -325,14 +325,14 @@ Transport Layer Security
Frame 10: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 3032, Ack: 1021, Len: 137
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 3032, Ack: 876, Len: 137
Zilla Frame
Frame Type ID: 0x40000002
Frame Type: WINDOW
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00000e68
+ Offset: 0x00000dd8
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -359,14 +359,14 @@ Zilla Frame
Frame 11: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 3169, Ack: 1021, Len: 137
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 3169, Ack: 876, Len: 137
Zilla Frame
Frame Type ID: 0x40000002
Frame Type: WINDOW
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00000ec8
+ Offset: 0x00000e38
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -393,14 +393,14 @@ Zilla Frame
Frame 12: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 3306, Ack: 1021, Len: 137
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 3306, Ack: 876, Len: 137
Zilla Frame
Frame Type ID: 0x40000002
Frame Type: WINDOW
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00000f28
+ Offset: 0x00000e98
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -427,14 +427,14 @@ Zilla Frame
Frame 13: 217 bytes on wire (1736 bits), 217 bytes captured (1736 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:2, Dst: fe80::3f3f:0:0:3
-Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1021, Ack: 3443, Len: 143
+Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 876, Ack: 3443, Len: 143
Zilla Frame
Frame Type ID: 0x00000002
Frame Type: DATA
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00000f88
+ Offset: 0x00000ef8
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -445,8 +445,8 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: INI
- Sequence: 482
- Acknowledge: 482
+ Sequence: 337
+ Acknowledge: 337
Maximum: 65536
Timestamp: 0x0000000000000000
Trace ID: 0x800000000000000d
@@ -468,14 +468,14 @@ Transport Layer Security
Frame 14: 301 bytes on wire (2408 bits), 301 bytes captured (2408 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:2, Dst: fe80::3f3f:0:0:3
-Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1164, Ack: 3443, Len: 227
+Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1019, Ack: 3443, Len: 227
Zilla Frame
Frame Type ID: 0x00000002
Frame Type: DATA
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00000ff0
+ Offset: 0x00000f60
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -486,8 +486,8 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: INI
- Sequence: 488
- Acknowledge: 482
+ Sequence: 343
+ Acknowledge: 337
Maximum: 65536
Timestamp: 0x0000000000000000
Trace ID: 0x800000000000000e
@@ -509,14 +509,14 @@ Transport Layer Security
Frame 15: 251 bytes on wire (2008 bits), 251 bytes captured (2008 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:2, Dst: fe80::3f3f:0:0:3
-Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1391, Ack: 3443, Len: 177
+Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1246, Ack: 3443, Len: 177
Zilla Frame
Frame Type ID: 0x00000002
Frame Type: DATA
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x000010a8
+ Offset: 0x00001018
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -527,8 +527,8 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: INI
- Sequence: 578
- Acknowledge: 482
+ Sequence: 433
+ Acknowledge: 337
Maximum: 65536
Timestamp: 0x0000000000000000
Trace ID: 0x800000000000000f
@@ -550,14 +550,14 @@ Transport Layer Security
Frame 16: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:2, Dst: fe80::3f3f:0:0:3
-Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1568, Ack: 3443, Len: 137
+Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1423, Ack: 3443, Len: 137
Zilla Frame
Frame Type ID: 0x40000002
Frame Type: WINDOW
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00001130
+ Offset: 0x000010a0
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -568,8 +568,8 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: INI
- Sequence: 488
- Acknowledge: 488
+ Sequence: 343
+ Acknowledge: 343
Maximum: 65536
Timestamp: 0x0000000000000000
Trace ID: 0x8000000000000010
@@ -584,14 +584,14 @@ Zilla Frame
Frame 17: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:2, Dst: fe80::3f3f:0:0:3
-Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1705, Ack: 3443, Len: 137
+Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1560, Ack: 3443, Len: 137
Zilla Frame
Frame Type ID: 0x40000002
Frame Type: WINDOW
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00001190
+ Offset: 0x00001100
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -602,8 +602,8 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: INI
- Sequence: 578
- Acknowledge: 578
+ Sequence: 433
+ Acknowledge: 433
Maximum: 65536
Timestamp: 0x0000000000000000
Trace ID: 0x8000000000000011
@@ -618,14 +618,14 @@ Zilla Frame
Frame 18: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:2, Dst: fe80::3f3f:0:0:3
-Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1842, Ack: 3443, Len: 137
+Transmission Control Protocol, Src Port: 0, Dst Port: 7114, Seq: 1697, Ack: 3443, Len: 137
Zilla Frame
Frame Type ID: 0x40000002
Frame Type: WINDOW
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x000011f0
+ Offset: 0x00001160
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -636,8 +636,8 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: INI
- Sequence: 618
- Acknowledge: 618
+ Sequence: 473
+ Acknowledge: 473
Maximum: 65536
Timestamp: 0x0000000000000000
Trace ID: 0x8000000000000012
@@ -649,17 +649,17 @@ Zilla Frame
Progress: 0
Progress/Maximum: 0/65536
-Frame 19: 2354 bytes on wire (18832 bits), 2354 bytes captured (18832 bits)
+Frame 19: 2344 bytes on wire (18752 bits), 2344 bytes captured (18752 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 3443, Ack: 1979, Len: 2280
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 3443, Ack: 1834, Len: 2270
Zilla Frame
Frame Type ID: 0x00000002
Frame Type: DATA
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00001250
+ Offset: 0x000011c0
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -682,25 +682,25 @@ Zilla Frame
.... .0.. = INCOMPLETE: Not set (0)
.... 0... = SKIP: Not set (0)
Budget ID: 0x0000000000000000
- Reserved: 2143
- Progress: 2143
- Progress/Maximum: 2143/65536
+ Reserved: 2133
+ Progress: 2133
+ Progress/Maximum: 2133/65536
Payload
- Length: 2143
+ Length: 2133
Payload
Transport Layer Security
Frame 20: 194 bytes on wire (1552 bits), 194 bytes captured (1552 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 5723, Ack: 1979, Len: 120
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 5713, Ack: 1834, Len: 120
Zilla Frame
Frame Type ID: 0x00000003
Frame Type: END
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00001b10
+ Offset: 0x00001a78
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -711,7 +711,7 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: REP
- Sequence: 4498
+ Sequence: 4488
Acknowledge: 2355
Maximum: 65536
Timestamp: 0x0000000000000000
@@ -721,14 +721,14 @@ Zilla Frame
Frame 21: 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits)
Ethernet II, Src: Send_00 (20:53:45:4e:44:00), Dst: Receive_00 (20:52:45:43:56:00)
Internet Protocol Version 6, Src: fe80::3f3f:0:0:3, Dst: fe80::3f3f:0:0:2
-Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 5843, Ack: 1979, Len: 137
+Transmission Control Protocol, Src Port: 7114, Dst Port: 0, Seq: 5833, Ack: 1834, Len: 137
Zilla Frame
Frame Type ID: 0x40000002
Frame Type: WINDOW
Protocol Type ID: 0x99f321bc
Protocol Type: tls
Worker: 0
- Offset: 0x00001b60
+ Offset: 0x00001ac8
Origin ID: 0x0000000100000002
Origin Namespace: test
Origin Binding: net0
@@ -739,8 +739,8 @@ Zilla Frame
Initial ID: 0x3f3f000000000003
Reply ID: 0x3f3f000000000002
Direction: REP
- Sequence: 4498
- Acknowledge: 4498
+ Sequence: 4488
+ Acknowledge: 4488
Maximum: 65536
Timestamp: 0x0000000000000000
Trace ID: 0x8000000000000015
diff --git a/incubator/command-log/pom.xml b/incubator/command-log/pom.xml
index efd7bcd6a6..df3d789626 100644
--- a/incubator/command-log/pom.xml
+++ b/incubator/command-log/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.82
+ 0.9.83
../pom.xml
@@ -24,8 +24,6 @@
- 11
- 11
1.00
0
diff --git a/incubator/command-tune/pom.xml b/incubator/command-tune/pom.xml
index 8bf9760c40..23fcd9f678 100644
--- a/incubator/command-tune/pom.xml
+++ b/incubator/command-tune/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.82
+ 0.9.83
../pom.xml
@@ -24,8 +24,6 @@
- 11
- 11
1.00
0
diff --git a/incubator/pom.xml b/incubator/pom.xml
index 4646e235ca..7aa00bfaa1 100644
--- a/incubator/pom.xml
+++ b/incubator/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.82
+ 0.9.83
../pom.xml
@@ -21,9 +21,6 @@
binding-amqp
- catalog-filesystem.spec
- catalog-filesystem
-
command-log
command-dump
command-tune
@@ -36,11 +33,6 @@
binding-amqp
${project.version}
-
- ${project.groupId}
- catalog-filesystem
- ${project.version}
-
${project.groupId}
command-log
diff --git a/manager/pom.xml b/manager/pom.xml
index c9e5682f37..49a3dd5465 100644
--- a/manager/pom.xml
+++ b/manager/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.82
+ 0.9.83
../pom.xml
@@ -16,8 +16,6 @@
zilla::manager
- 11
- 11
0.61
0
diff --git a/manager/src/main/java/org/apache/ivy/util/url/IvyAuthenticator.java b/manager/src/main/java/org/apache/ivy/util/url/IvyAuthenticator.java
index 26935695b4..57e3b943d0 100644
--- a/manager/src/main/java/org/apache/ivy/util/url/IvyAuthenticator.java
+++ b/manager/src/main/java/org/apache/ivy/util/url/IvyAuthenticator.java
@@ -17,6 +17,8 @@
*/
package org.apache.ivy.util.url;
+import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
+
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Authenticator;
@@ -25,8 +27,6 @@
import org.apache.ivy.util.Credentials;
import org.apache.ivy.util.Message;
-import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
-
/**
*
*/
diff --git a/pom.xml b/pom.xml
index e111f46c9e..511890a517 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
4.0.0
io.aklivity.zilla
zilla
- 0.9.82
+ 0.9.83
pom
zilla
https://github.com/aklivity/zilla
@@ -34,14 +34,24 @@
- github
- https://maven.pkg.github.com/aklivity/packages/
+ aklivity
+ https://maven.packages.aklivity.io/
+
+
+ aklivity
+ https://maven.packages.aklivity.io/
+
+
+
UTF-8
UTF-8
+ 17
+ 17
+ 17
io/aklivity/zilla/conf/checkstyle/configuration.xml
io/aklivity/zilla/conf/checkstyle/suppressions.xml
4.13.0
@@ -51,7 +61,7 @@
4.0.22
2.6.0
5.8.0
- 3.1.0
+ 3.3.0
1.37
@@ -195,18 +205,18 @@
0.1.4
- org.kaazing
- k3po.driver
+ io.aklivity.k3po
+ driver
${k3po.version}
- org.kaazing
- k3po.lang
+ io.aklivity.k3po
+ lang
${k3po.version}
- org.kaazing
- k3po.junit
+ io.aklivity.k3po
+ control-junit
${k3po.version}
@@ -320,6 +330,7 @@
3.1.2
true
+ **/generated-*/**/*
@@ -439,7 +450,7 @@
- org.kaazing
+ io.aklivity.k3po
k3po-maven-plugin
${k3po.version}
@@ -668,7 +679,7 @@
No Snapshots Allowed!
- [13,14)
+ [17,18)
release
diff --git a/runtime/binding-asyncapi/pom.xml b/runtime/binding-asyncapi/pom.xml
index 811e313493..9faf4857f8 100644
--- a/runtime/binding-asyncapi/pom.xml
+++ b/runtime/binding-asyncapi/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.82
+ 0.9.83
../pom.xml
@@ -24,8 +24,6 @@
- 11
- 11
0.60
4
@@ -61,6 +59,12 @@
${project.version}
provided
+
+ io.aklivity.zilla
+ binding-sse
+ ${project.version}
+ provided
+
io.aklivity.zilla
binding-kafka
@@ -79,6 +83,18 @@
${project.version}
provided
+
+ io.aklivity.zilla
+ binding-http-kafka
+ ${project.version}
+ provided
+
+
+ io.aklivity.zilla
+ binding-sse-kafka
+ ${project.version}
+ provided
+
io.aklivity.zilla
binding-tls
@@ -141,13 +157,13 @@
test
- org.kaazing
- k3po.junit
+ io.aklivity.k3po
+ control-junit
test
- org.kaazing
- k3po.lang
+ io.aklivity.k3po
+ lang
test
@@ -157,6 +173,20 @@
${project.version}
test
+
+ io.aklivity.zilla
+ binding-http-kafka
+ test-jar
+ ${project.version}
+ test
+
+
+ io.aklivity.zilla
+ binding-sse-kafka
+ test-jar
+ ${project.version}
+ test
+
org.openjdk.jmh
jmh-core
@@ -176,7 +206,7 @@
flyweight-maven-plugin
${project.version}
- core mqtt http kafka asyncapi
+ core mqtt http sse kafka asyncapi
io.aklivity.zilla.runtime.binding.asyncapi.internal.types
@@ -211,11 +241,13 @@
io/aklivity/zilla/specs/binding/asyncapi/schema/asyncapi.schema.patch.json,
io/aklivity/zilla/specs/binding/mqtt/kafka/schema/mqtt.kafka.schema.patch.json,
io/aklivity/zilla/specs/binding/http/schema/http.schema.patch.json,
+ io/aklivity/zilla/specs/binding/sse/schema/sse.schema.patch.json,
io/aklivity/zilla/specs/binding/kafka/schema/kafka.schema.patch.json,
io/aklivity/zilla/specs/binding/tcp/schema/tcp.schema.patch.json,
io/aklivity/zilla/specs/binding/tls/schema/tls.schema.patch.json,
io/aklivity/zilla/specs/binding/asyncapi/schema/asyncapi.2.6.0.schema.json,
- io/aklivity/zilla/specs/binding/asyncapi/schema/asyncapi.3.0.1.schema.json
+ io/aklivity/zilla/specs/binding/asyncapi/schema/asyncapi.3.0.1.schema.json,
+ io/aklivity/zilla/specs/binding/asyncapi/schema/asyncapi.3.0.2-zilla.schema.json
${project.build.directory}/classes
@@ -280,7 +312,7 @@
- org.kaazing
+ io.aklivity.k3po
k3po-maven-plugin
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/config/AsyncapiParser.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/config/AsyncapiParser.java
index 759cd8ff63..18b5765b62 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/config/AsyncapiParser.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/config/AsyncapiParser.java
@@ -42,15 +42,16 @@
public class AsyncapiParser
{
- private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d\\.\\d)\\.\\d+");
+ private static final Pattern VERSION_PATTERN = Pattern.compile("(?!\\.)(\\d+(\\.\\d+)+)(?:[-.][a-zA-Z]+)?(?![\\d.])$");
private final Map schemas;
public AsyncapiParser()
{
Map schemas = new Object2ObjectHashMap<>();
- schemas.put("2.6", schema("2.6.0"));
- schemas.put("3.0", schema("3.0.1"));
+ schemas.put("2.6.0", schema("2.6.0"));
+ schemas.put("3.0.0", schema("3.0.1"));
+ schemas.put("3.0.2-zilla", schema("3.0.2-zilla"));
this.schemas = unmodifiableMap(schemas);
}
@@ -115,8 +116,7 @@ private String detectAsyncApiVersion(
final String versionString = json.getString("asyncapi");
final Matcher matcher = VERSION_PATTERN.matcher(versionString);
- final String majorMinorVersion = matcher.matches() ? matcher.group(1) : null;
- return majorMinorVersion;
+ return matcher.matches() ? matcher.group(0) : null;
}
else
{
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiBindingConfig.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiBindingConfig.java
index e8b130ec05..dd236f8f38 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiBindingConfig.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiBindingConfig.java
@@ -16,12 +16,14 @@
import static io.aklivity.zilla.runtime.engine.config.KindConfig.CACHE_CLIENT;
import static io.aklivity.zilla.runtime.engine.config.KindConfig.PROXY;
+import static io.aklivity.zilla.runtime.engine.config.KindConfig.SERVER;
import static java.util.stream.Collectors.toList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.function.LongFunction;
@@ -43,10 +45,13 @@
import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiParser;
import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiSchemaConfig;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.Asyncapi;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiBinding;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.types.HttpHeaderFW;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.types.String16FW;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.types.String8FW;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.types.stream.HttpBeginExFW;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.types.stream.MqttBeginExFW;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.types.stream.SseBeginExFW;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiServerView;
import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler;
import io.aklivity.zilla.runtime.engine.config.BindingConfig;
@@ -56,6 +61,8 @@
public final class AsyncapiBindingConfig
{
+ public static final String SEND_OPERATION = "send";
+ public static final String RECEIVE_OPERATION = "receive";
public final long id;
public final String name;
public final KindConfig kind;
@@ -63,13 +70,17 @@ public final class AsyncapiBindingConfig
public final List routes;
private final Int2ObjectHashMap typesByNamespaceId;
- private final Int2ObjectHashMap composites;
+ private final Int2ObjectHashMap composites;
private final Long2LongHashMap apiIdsByNamespaceId;
private final AsyncapiNamespaceGenerator namespaceGenerator;
- private final Long2LongHashMap compositeResolvedIds;
+ private final Object2LongHashMap compositeResolvedIds;
private final Object2ObjectHashMap paths;
+ private final Object2ObjectHashMap topics;
private final Object2LongHashMap schemaIdsByApiId;
private final Map operationIds;
+ private final Map> operationBindings;
+ private final Map receiveOperationIds;
+ private final Map sendOperationIds;
private final LongFunction supplyCatalog;
private final ToLongFunction resolveId;
private final Consumer attach;
@@ -96,11 +107,15 @@ public AsyncapiBindingConfig(
this.options = (AsyncapiOptionsConfig) binding.options;
this.composites = new Int2ObjectHashMap<>();
this.apiIdsByNamespaceId = new Long2LongHashMap(-1);
- this.compositeResolvedIds = new Long2LongHashMap(-1);
+ this.compositeResolvedIds = new Object2LongHashMap<>(-1);
this.schemaIdsByApiId = new Object2LongHashMap<>(-1);
this.typesByNamespaceId = new Int2ObjectHashMap<>();
this.paths = new Object2ObjectHashMap<>();
+ this.topics = new Object2ObjectHashMap<>();
this.operationIds = new TreeMap<>(CharSequence::compare);
+ this.operationBindings = new HashMap<>();
+ this.receiveOperationIds = new TreeMap<>(CharSequence::compare);
+ this.sendOperationIds = new TreeMap<>(CharSequence::compare);
this.helper = new HttpHeaderHelper();
this.parser = new AsyncapiParser();
this.attach = attachComposite;
@@ -114,16 +129,11 @@ public boolean isCompositeOriginId(
return typesByNamespaceId.containsKey(NamespacedId.namespaceId(originId));
}
- public String getCompositeOriginType(
- long originId)
- {
- return typesByNamespaceId.get(NamespacedId.namespaceId(originId));
- }
-
public long resolveCompositeResolvedId(
- long apiId)
+ long apiId,
+ String type)
{
- return overrideRouteId != -1 ? overrideRouteId : compositeResolvedIds.get(apiId);
+ return overrideRouteId != -1 ? overrideRouteId : compositeResolvedIds.get(apiId + type);
}
public long resolveApiId(
@@ -138,7 +148,48 @@ public long resolveApiId(
return schemaIdsByApiId.get(apiId);
}
- public String resolveOperationId(
+ public String resolveMqttOperationId(
+ MqttBeginExFW mqttBeginEx)
+ {
+ String topic;
+ String operationId = null;
+
+ switch (mqttBeginEx.kind())
+ {
+ case MqttBeginExFW.KIND_PUBLISH:
+ topic = mqttBeginEx.publish().topic().asString();
+ for (Map.Entry item : paths.entrySet())
+ {
+ Matcher matcher = item.getKey();
+ matcher.reset(topic);
+ if (matcher.find())
+ {
+ String channelName = item.getValue();
+ operationId = sendOperationIds.get(channelName);
+ break;
+ }
+ }
+ break;
+ case MqttBeginExFW.KIND_SUBSCRIBE:
+ topic = mqttBeginEx.subscribe().filters().matchFirst(x -> true).pattern().asString();
+ for (Map.Entry item : paths.entrySet())
+ {
+ Matcher matcher = item.getKey();
+ matcher.reset(topic);
+ if (matcher.find())
+ {
+ String channelName = item.getValue();
+ operationId = receiveOperationIds.get(channelName);
+ break;
+ }
+ }
+ break;
+ }
+
+ return operationId;
+ }
+
+ public String resolveHttpOperationId(
HttpBeginExFW httpBeginEx)
{
helper.visit(httpBeginEx);
@@ -160,6 +211,26 @@ public String resolveOperationId(
return operationId;
}
+ public String resolveSseOperationId(
+ SseBeginExFW sseBeginEx)
+ {
+ String operationId = null;
+
+ for (Map.Entry item : paths.entrySet())
+ {
+ Matcher matcher = item.getKey();
+ matcher.reset(sseBeginEx.path().asString());
+ if (matcher.find())
+ {
+ String channelName = item.getValue();
+ operationId = operationIds.get(channelName);
+ break;
+ }
+ }
+
+ return operationId;
+ }
+
public AsyncapiRouteConfig resolve(
long authorization)
{
@@ -193,14 +264,37 @@ public void attach(
attachServerClientBinding(binding, configs);
}
- for (Map.Entry entry : composites.entrySet())
+ for (Map.Entry entry : composites.entrySet())
{
Integer k = entry.getKey();
- NamespaceConfig v = entry.getValue();
- List bindings = v.bindings.stream()
- .filter(b -> b.type.equals("mqtt") || b.type.equals("http") ||
- b.type.equals("kafka") && b.kind == CACHE_CLIENT || b.type.equals("mqtt-kafka"))
- .collect(toList());
+ CompositeNamespace v = entry.getValue();
+ NamespaceConfig namespaceConfig = v.composite;
+ List bindings;
+ boolean containsSse = namespaceConfig.bindings.stream().anyMatch(b -> b.type.equals("sse"));
+ if (containsSse)
+ {
+ if (binding.kind.equals(SERVER))
+ {
+ bindings = namespaceConfig.bindings.stream()
+ .filter(b -> b.type.equals("http") || b.type.equals("http-kafka") || b.type.equals("sse"))
+ .collect(toList());
+ }
+ else
+ {
+ bindings = namespaceConfig.bindings.stream()
+ .filter(b -> b.type.equals("sse"))
+ .collect(toList());
+ }
+ }
+ else
+ {
+ bindings = namespaceConfig.bindings.stream()
+ .filter(b -> b.type.equals("mqtt") || b.type.equals("http") || b.type.equals("sse") ||
+ b.type.equals("kafka") && b.kind == CACHE_CLIENT || b.type.equals("mqtt-kafka") ||
+ b.type.equals("http-kafka") || b.type.equals("sse-kafka"))
+ .collect(toList());
+ }
+
extractResolveId(k, bindings);
extractNamespace(k, bindings);
}
@@ -208,7 +302,7 @@ public void attach(
public void detach()
{
- composites.forEach((k, v) -> detach.accept(v));
+ composites.forEach((k, v) -> detach.accept(v.composite));
composites.clear();
}
@@ -224,8 +318,8 @@ private void attachProxyBinding(
Object2ObjectHashMap::new));
namespaceGenerator.init(binding);
- final NamespaceConfig composite = namespaceGenerator.generateProxy(binding, asyncapis, schemaIdsByApiId::get);
- composite.readURL = binding.readURL;
+ final List labels = configs.stream().map(c -> c.apiLabel).collect(toList());
+ final NamespaceConfig composite = namespaceGenerator.generateProxy(binding, asyncapis, schemaIdsByApiId::get, labels);
attach.accept(composite);
updateNamespace(configs, composite, new ArrayList<>(asyncapis.values()));
}
@@ -254,7 +348,6 @@ private void attachServerClientBinding(
namespaceConfig.servers.forEach(s -> s.setAsyncapiProtocol(
namespaceGenerator.resolveProtocol(s.protocol(), options, namespaceConfig.asyncapis, namespaceConfig.servers)));
final NamespaceConfig composite = namespaceGenerator.generate(binding, namespaceConfig);
- composite.readURL = binding.readURL;
attach.accept(composite);
updateNamespace(namespaceConfig.configs, composite, namespaceConfig.asyncapis);
}
@@ -267,7 +360,7 @@ private void updateNamespace(
{
configs.forEach(c ->
{
- composites.put(c.schemaId, composite);
+ composites.put(c.schemaId, new CompositeNamespace(composite, c.asyncapi.operations.keySet()));
schemaIdsByApiId.put(c.apiLabel, c.schemaId);
});
asyncapis.forEach(this::extractChannels);
@@ -290,7 +383,11 @@ private void extractResolveId(
int schemaId,
List bindings)
{
- bindings.forEach(b -> compositeResolvedIds.put(schemaId, b.id));
+ bindings.forEach(b ->
+ {
+ String operationType = b.type.replace("-kafka", "");
+ compositeResolvedIds.put(schemaId + operationType, b.id);
+ });
}
private void extractOperations(
@@ -300,6 +397,16 @@ private void extractOperations(
{
String[] refParts = v.channel.ref.split("/");
operationIds.put(refParts[refParts.length - 1], k);
+ if (SEND_OPERATION.equals(v.action))
+ {
+ sendOperationIds.put(refParts[refParts.length - 1], k);
+ }
+ else if (RECEIVE_OPERATION.equals(v.action))
+ {
+ receiveOperationIds.put(refParts[refParts.length - 1], k);
+ }
+
+ operationBindings.put(k, v.bindings);
});
}
@@ -419,4 +526,18 @@ private void visitAuthority(
authority = authorityRO.wrap(value.buffer(), value.offset(), value.limit());
}
}
+
+ static class CompositeNamespace
+ {
+ NamespaceConfig composite;
+ Set operations;
+
+ CompositeNamespace(
+ NamespaceConfig composite,
+ Set operations)
+ {
+ this.composite = composite;
+ this.operations = operations;
+ }
+ }
}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiClientNamespaceGenerator.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiClientNamespaceGenerator.java
index e1f2908402..b7e44e36fc 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiClientNamespaceGenerator.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiClientNamespaceGenerator.java
@@ -32,14 +32,11 @@ public NamespaceConfig generate(
BindingConfig binding,
AsyncapiNamespaceConfig namespaceConfig)
{
- List servers = namespaceConfig.servers;
- AsyncapiOptionsConfig options = binding.options != null ? (AsyncapiOptionsConfig) binding.options : EMPTY_OPTION;
+ final List servers = namespaceConfig.servers;
+ final AsyncapiOptionsConfig options = binding.options != null ? (AsyncapiOptionsConfig) binding.options : EMPTY_OPTION;
final List metricRefs = binding.telemetryRef != null ?
binding.telemetryRef.metricRefs : emptyList();
- //TODO: keep it until we support different protocols on the same composite binding
- AsyncapiServerView serverView = servers.get(0);
- this.protocol = serverView.getAsyncapiProtocol();
int[] compositeSecurePorts = resolvePorts(servers, true);
this.isTlsEnabled = compositeSecurePorts.length > 0;
@@ -48,24 +45,70 @@ public NamespaceConfig generate(
.name(String.format("%s.%s-%s", qname, "$composite", namespace))
.inject(n -> this.injectNamespaceMetric(n, !metricRefs.isEmpty()))
.inject(n -> this.injectCatalog(n, namespaceConfig.asyncapis))
- .inject(n -> protocol.injectProtocolClientCache(n, metricRefs))
- .binding()
- .name(String.format("%s_client0", protocol.scheme))
- .type(protocol.scheme)
- .kind(CLIENT)
- .inject(b -> this.injectMetrics(b, metricRefs, protocol.scheme))
- .inject(protocol::injectProtocolClientOptions)
- .exit(isTlsEnabled ? "tls_client0" : "tcp_client0")
- .build()
- .inject(n -> injectTlsClient(n, options, metricRefs))
+ .inject(n -> this.injectProtocolClients(n, servers, metricRefs))
+ .inject(n -> this.injectProtocolRelatedBindings(n, servers, metricRefs))
+ .inject(n -> this.injectTlsClient(n, options, metricRefs))
+ .inject(n -> this.injectTcpClient(n, servers, options, metricRefs))
+ .build();
+ }
+
+ private NamespaceConfigBuilder injectTcpClient(
+ NamespaceConfigBuilder namespace,
+ List servers,
+ AsyncapiOptionsConfig options,
+ List metricRefs)
+ {
+ for (AsyncapiServerView server : servers)
+ {
+ final AsyncapiProtocol protocol = server.getAsyncapiProtocol();
+ namespace = namespace
.binding()
.name("tcp_client0")
.type("tcp")
.kind(CLIENT)
- .inject(b -> this.injectMetrics(b, metricRefs, "tcp"))
+ .inject(b -> this.injectMetrics(b, metricRefs))
.options(!protocol.scheme.equals(AyncapiKafkaProtocol.SCHEME) ? options.tcp : null)
- .build()
.build();
+ }
+
+ return namespace;
+ }
+
+ private NamespaceConfigBuilder injectProtocolClients(
+ NamespaceConfigBuilder namespace,
+ List servers,
+ List metricRefs)
+ {
+ for (AsyncapiServerView server : servers)
+ {
+ final AsyncapiProtocol protocol = server.getAsyncapiProtocol();
+ final String scheme = protocol.scheme;
+ final String exit = "sse".equals(scheme) ? "http_client0" : isTlsEnabled ? "tls_client0" : "tcp_client0";
+ namespace = namespace
+ .inject(n -> protocol.injectProtocolClientCache(n, metricRefs))
+ .binding()
+ .name(String.format("%s_client0", scheme))
+ .type(scheme)
+ .kind(CLIENT)
+ .inject(b -> this.injectMetrics(b, metricRefs))
+ .inject(protocol::injectProtocolClientOptions)
+ .exit(exit)
+ .build();
+ }
+ return namespace;
+ }
+
+ protected NamespaceConfigBuilder injectProtocolRelatedBindings(
+ NamespaceConfigBuilder namespace,
+ List servers,
+ List metricRefs)
+ {
+ for (AsyncapiServerView server : servers)
+ {
+ final AsyncapiProtocol protocol = server.getAsyncapiProtocol();
+ namespace = protocol.injectProtocolRelatedClientBindings(namespace, metricRefs, isTlsEnabled);
+ }
+ return namespace;
}
private NamespaceConfigBuilder injectTlsClient(
@@ -80,7 +123,7 @@ private NamespaceConfigBuilder injectTlsClient(
.name("tls_client0")
.type("tls")
.kind(CLIENT)
- .inject(b -> this.injectMetrics(b, metricRefs, "tls"))
+ .inject(b -> this.injectMetrics(b, metricRefs))
.options(options.tls)
.vault(String.format("%s:%s", this.namespace, vault))
.exit("tcp_client0")
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiConditionConfigAdapter.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiConditionConfigAdapter.java
index 8d659d7141..cc3e31656c 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiConditionConfigAdapter.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiConditionConfigAdapter.java
@@ -42,8 +42,11 @@ public JsonObject adaptToJson(
JsonObjectBuilder object = Json.createObjectBuilder();
object.add(API_ID_NAME, asyncapiCondition.apiId);
- object.add(OPERATION_ID_NAME, asyncapiCondition.operationId);
+ if (asyncapiCondition.operationId != null)
+ {
+ object.add(OPERATION_ID_NAME, asyncapiCondition.operationId);
+ }
return object.build();
}
@@ -51,8 +54,14 @@ public JsonObject adaptToJson(
public ConditionConfig adaptFromJson(
JsonObject object)
{
- String apiId = object.getString(API_ID_NAME);
- String operationId = object.getString(OPERATION_ID_NAME);
+ String apiId = object.containsKey(API_ID_NAME)
+ ? object.getString(API_ID_NAME)
+ : null;
+
+ String operationId = object.containsKey(OPERATION_ID_NAME)
+ ? object.getString(OPERATION_ID_NAME)
+ : null;
+
return new AsyncapiConditionConfig(apiId, operationId);
}
}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiHttpKafkaProxy.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiHttpKafkaProxy.java
new file mode 100644
index 0000000000..485d4aa746
--- /dev/null
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiHttpKafkaProxy.java
@@ -0,0 +1,346 @@
+/*
+ * 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.asyncapi.internal.config;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiOptionsConfig;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.Asyncapi;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiChannel;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiMessage;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiOperation;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiReply;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiChannelView;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiCorrelationIdView;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiMessageView;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiSchemaView;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaConditionConfig;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithConfig;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithConfigBuilder;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithFetchConfig;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithFetchConfigBuilder;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithFetchFilterConfig;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithFetchMergeConfig;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithProduceAsyncHeaderConfig;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithProduceConfig;
+import io.aklivity.zilla.runtime.binding.http.kafka.config.HttpKafkaWithProduceConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.BindingConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.RouteConfigBuilder;
+
+public class AsyncapiHttpKafkaProxy extends AsyncapiProxy
+{
+ private static final String CORRELATION_ID = "\\{correlationId\\}";
+ private static final String PARAMETERS = "\\{(?!correlationId)(\\w+)\\}";
+ private static final String HEADER_LOCATION = "([^/]+)$";
+ private static final String ASYNCAPI_KAFKA_PROTOCOL_NAME = "kafka";
+ private static final String ASYNCAPI_HTTP_PROTOCOL_NAME = "http";
+ private static final String ASYNCAPI_SEND_ACTION_NAME = "send";
+ private static final String ASYNCAPI_RECEIVE_ACTION_NAME = "receive";
+ private static final Pattern PARAMETER_PATTERN = Pattern.compile("\\{([^}]+)\\}");
+ private static final Pattern HEADER_LOCATION_PATTERN = Pattern.compile(HEADER_LOCATION);
+
+ private final Matcher parameters = PARAMETER_PATTERN.matcher("");
+ private final Matcher headerLocation = HEADER_LOCATION_PATTERN.matcher("");
+
+ protected AsyncapiHttpKafkaProxy(
+ String qname,
+ Map asyncapis)
+ {
+ super("http-kafka", qname, asyncapis);
+ }
+
+ @Override
+ protected BindingConfigBuilder injectProxyRoutes(
+ BindingConfigBuilder binding,
+ List routes)
+ {
+ inject:
+ for (AsyncapiRouteConfig route : routes)
+ {
+ final Asyncapi kafkaAsyncapi = asyncapis.get(route.with.apiId);
+
+ for (AsyncapiConditionConfig condition : route.when)
+ {
+ final Asyncapi httpAsyncapi = asyncapis.get(condition.apiId);
+ if (httpAsyncapi.servers.values().stream().noneMatch(s -> s.protocol.startsWith(ASYNCAPI_HTTP_PROTOCOL_NAME)))
+ {
+ break inject;
+ }
+ final AsyncapiOperation whenOperation = httpAsyncapi.operations.get(condition.operationId);
+ if (whenOperation == null)
+ {
+ for (Map.Entry e : httpAsyncapi.operations.entrySet())
+ {
+ AsyncapiOperation withOperation = route.with.operationId != null ?
+ kafkaAsyncapi.operations.get(route.with.operationId) : kafkaAsyncapi.operations.get(e.getKey());
+ if (withOperation != null)
+ {
+ binding = addHttpKafkaRoute(binding, kafkaAsyncapi, httpAsyncapi, e.getValue(), withOperation);
+ }
+ }
+ }
+ else
+ {
+ AsyncapiOperation withOperation = kafkaAsyncapi.operations.get(route.with.operationId);
+ binding = addHttpKafkaRoute(binding, kafkaAsyncapi, httpAsyncapi, whenOperation, withOperation);
+ }
+ }
+ }
+ return binding;
+ }
+
+ private BindingConfigBuilder addHttpKafkaRoute(
+ BindingConfigBuilder binding,
+ Asyncapi kafkaAsyncapi,
+ Asyncapi httpAsyncapi,
+ AsyncapiOperation whenOperation,
+ AsyncapiOperation withOperation)
+ {
+
+ final AsyncapiChannelView channel = AsyncapiChannelView.of(httpAsyncapi.channels, whenOperation.channel);
+ String path = channel.address();
+ if (whenOperation.bindings != null)
+ {
+ String method = whenOperation.bindings.get("http").method;
+ final List paramNames = findParams(path);
+
+ AsyncapiChannelView httpChannel = AsyncapiChannelView.of(httpAsyncapi.channels, whenOperation.channel);
+
+ boolean async = httpChannel.messages().values()
+ .stream().anyMatch(asyncapiMessage ->
+ {
+ AsyncapiMessageView message =
+ AsyncapiMessageView.of(httpAsyncapi.components.messages, asyncapiMessage);
+ return message.correlationId() != null;
+ });
+
+ if (async)
+ {
+ for (AsyncapiOperation operation : httpAsyncapi.operations.values())
+ {
+ AsyncapiChannelView channelView = AsyncapiChannelView.of(httpAsyncapi.channels, operation.channel);
+ if (parameters.reset(channelView.address()).find())
+ {
+ AsyncapiReply reply = withOperation.reply;
+ if (reply != null)
+ {
+ final RouteConfigBuilder> asyncRouteBuilder = binding.route();
+ binding = addAsyncOperation(asyncRouteBuilder, httpAsyncapi, kafkaAsyncapi, operation,
+ withOperation);
+ }
+ }
+ }
+ }
+
+ final RouteConfigBuilder> routeBuilder = binding.route();
+ routeBuilder
+ .exit(qname)
+ .when(HttpKafkaConditionConfig::builder)
+ .method(method)
+ .path(path)
+ .build()
+ .inject(r -> injectHttpKafkaRouteWith(r, httpAsyncapi, kafkaAsyncapi, whenOperation,
+ withOperation, paramNames));
+ binding = routeBuilder.build();
+ }
+ return binding;
+ }
+
+ private BindingConfigBuilder addAsyncOperation(
+ RouteConfigBuilder> routeBuilder,
+ Asyncapi httpAsyncapi,
+ Asyncapi kafkaAsyncapi,
+ AsyncapiOperation httpOperation,
+ AsyncapiOperation kafkaOperation)
+ {
+ final AsyncapiChannelView channel = AsyncapiChannelView.of(httpAsyncapi.channels, httpOperation.channel);
+ String path = channel.address();
+ String method = httpOperation.bindings.get("http").method;
+ final List paramNames = findParams(path);
+ return routeBuilder
+ .exit(qname)
+ .when(HttpKafkaConditionConfig::builder)
+ .method(method)
+ .path(path)
+ .build()
+ .inject(r -> injectAsyncProduceHttpKafkaRouteWith(r, httpAsyncapi, kafkaAsyncapi, httpOperation,
+ kafkaOperation, paramNames))
+ .build();
+ }
+
+ @Override
+ public BindingConfigBuilder injectProxyOptions(
+ BindingConfigBuilder binding,
+ AsyncapiOptionsConfig options)
+ {
+ return binding;
+ }
+
+ private List findParams(
+ String item)
+ {
+ List paramNames = new ArrayList<>();
+ Matcher matcher = parameters.reset(item);
+ while (matcher.find())
+ {
+ paramNames.add(parameters.group(1));
+ }
+ return paramNames;
+ }
+
+ private RouteConfigBuilder injectHttpKafkaRouteWith(
+ RouteConfigBuilder route,
+ Asyncapi httpAsyncapi,
+ Asyncapi kafkaAsyncapi,
+ AsyncapiOperation httpOperation,
+ AsyncapiOperation kafkaOperation,
+ List paramNames)
+ {
+ final HttpKafkaWithConfigBuilder newWith = HttpKafkaWithConfig.builder();
+ final AsyncapiChannelView channel = AsyncapiChannelView
+ .of(kafkaAsyncapi.channels, kafkaOperation.channel);
+ final String topic = channel.address();
+
+ switch (kafkaOperation.action)
+ {
+ case "receive":
+ newWith.fetch(HttpKafkaWithFetchConfig.builder()
+ .topic(topic)
+ .inject(with -> injectHttpKafkaRouteFetchWith(with, httpAsyncapi, httpOperation, paramNames))
+ .build());
+ break;
+ case "send":
+ newWith.produce(HttpKafkaWithProduceConfig.builder()
+ .topic(topic)
+ .inject(w -> injectHttpKafkaRouteProduceWith(w, httpOperation, kafkaOperation, httpAsyncapi,
+ kafkaAsyncapi.channels, paramNames))
+ .build());
+ break;
+ }
+
+ route.with(newWith.build());
+
+ return route;
+ }
+
+ private RouteConfigBuilder injectAsyncProduceHttpKafkaRouteWith(
+ RouteConfigBuilder route,
+ Asyncapi httpAsyncapi,
+ Asyncapi kafkaAsyncapi,
+ AsyncapiOperation httpOperation,
+ AsyncapiOperation kafkaOperation,
+ List paramNames)
+ {
+ final HttpKafkaWithConfigBuilder newWith = HttpKafkaWithConfig.builder();
+ final AsyncapiChannelView channel = AsyncapiChannelView.of(kafkaAsyncapi.channels, kafkaOperation.channel);
+ final String topic = channel.address();
+
+ newWith.produce(HttpKafkaWithProduceConfig.builder()
+ .topic(topic)
+ .inject(w -> injectHttpKafkaRouteProduceWith(w, httpOperation, kafkaOperation, httpAsyncapi,
+ kafkaAsyncapi.channels, paramNames))
+ .build());
+ route.with(newWith.build());
+
+ return route;
+ }
+
+ private HttpKafkaWithFetchConfigBuilder injectHttpKafkaRouteFetchWith(
+ HttpKafkaWithFetchConfigBuilder fetch,
+ Asyncapi httpAsyncapi,
+ AsyncapiOperation httpOperation,
+ List paramNames)
+ {
+ final AsyncapiChannelView channel = AsyncapiChannelView.of(httpAsyncapi.channels, httpOperation.channel);
+ merge:
+ for (Map.Entry message : channel.messages().entrySet())
+ {
+ AsyncapiMessageView messageView = AsyncapiMessageView.of(httpAsyncapi.components.messages, message.getValue());
+ AsyncapiSchemaView schema = AsyncapiSchemaView.of(httpAsyncapi.components.schemas, messageView.payload());
+
+ if (schema != null && "array".equals(schema.getType()))
+ {
+ fetch.merged(HttpKafkaWithFetchMergeConfig.builder()
+ .contentType("application/json")
+ .initial("[]")
+ .path("/-")
+ .build());
+ break merge;
+ }
+ }
+
+ if (!paramNames.isEmpty())
+ {
+ fetch.filters(List.of(HttpKafkaWithFetchFilterConfig.builder()
+ .key(String.format("${params.%s}", paramNames.get(paramNames.size() - 1)))
+ .build()));
+ }
+
+ return fetch;
+ }
+
+ private HttpKafkaWithProduceConfigBuilder injectHttpKafkaRouteProduceWith(
+ HttpKafkaWithProduceConfigBuilder produce,
+ AsyncapiOperation httpOperation,
+ AsyncapiOperation kafkaOperation,
+ Asyncapi httpAsyncapi,
+ Map kafkaChannels,
+ List paramNames)
+ {
+ final String key = !paramNames.isEmpty() ? String.format("${params.%s}",
+ paramNames.get(paramNames.size() - 1)) : "${idempotencyKey}";
+
+ produce.acks("in_sync_replicas").key(key);
+
+ AsyncapiChannelView httpChannel = AsyncapiChannelView.of(httpAsyncapi.channels, httpOperation.channel);
+
+ httpChannel.messages().values()
+ .forEach(asyncapiMessage ->
+ {
+ AsyncapiMessageView message = AsyncapiMessageView.of(httpAsyncapi.components.messages, asyncapiMessage);
+ if (message.correlationId() != null)
+ {
+ AsyncapiCorrelationIdView correlationId =
+ AsyncapiCorrelationIdView.of(httpAsyncapi.components.correlationIds, message.correlationId());
+ if (headerLocation.reset(correlationId.location()).find())
+ {
+ String headerName = headerLocation.group(1);
+ String location = message.headers().properties.get(headerName).format;
+ location = location.replaceAll(CORRELATION_ID, "\\${correlationId}");
+ location = location.replaceAll(PARAMETERS, "\\${params.$1}");
+ produce.async(HttpKafkaWithProduceAsyncHeaderConfig.builder()
+ .name("location")
+ .value(location)
+ .build());
+ }
+ }
+ });
+
+ AsyncapiReply reply = kafkaOperation.reply;
+ if (reply != null)
+ {
+ AsyncapiChannelView channel = AsyncapiChannelView.of(kafkaChannels, reply.channel);
+ produce.replyTo(channel.address());
+ }
+
+ produce.build();
+
+ return produce;
+ }
+}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiHttpProtocol.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiHttpProtocol.java
index 5f959d2628..39e8e5fa57 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiHttpProtocol.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiHttpProtocol.java
@@ -22,6 +22,7 @@
import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiOptionsConfig;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.Asyncapi;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiBinding;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiMessage;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiOperation;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiParameter;
@@ -107,21 +108,50 @@ public BindingConfigBuilder injectProtocolServerRoutes(
for (Map.Entry entry : asyncapi.servers.entrySet())
{
AsyncapiServerView server = AsyncapiServerView.of(entry.getValue());
- for (String name : asyncapi.operations.keySet())
+ if ("http".equals(server.protocol()))
{
- AsyncapiOperation operation = asyncapi.operations.get(name);
- AsyncapiChannelView channel = AsyncapiChannelView.of(asyncapi.channels, operation.channel);
- String path = channel.address().replaceAll("\\{[^}]+\\}", "*");
- String method = operation.bindings.get("http").method;
- binding
- .route()
- .exit(qname)
- .when(HttpConditionConfig::builder)
- .header(":path", path)
- .header(":method", method)
- .build()
- .inject(route -> injectHttpServerRouteGuarded(route, server))
- .build();
+ for (String name : asyncapi.operations.keySet())
+ {
+ AsyncapiOperation operation = asyncapi.operations.get(name);
+ AsyncapiChannelView channel = AsyncapiChannelView.of(asyncapi.channels, operation.channel);
+ String path = channel.address().replaceAll("\\{[^}]+\\}", "*");
+ if (operation.bindings != null)
+ {
+ AsyncapiBinding httpBinding = operation.bindings.get("http");
+ if (httpBinding != null)
+ {
+ String method = httpBinding.method;
+ binding
+ .route()
+ .exit(qname)
+ .when(HttpConditionConfig::builder)
+ .header(":path", path)
+ .header(":method", method)
+ .build()
+ .inject(route -> injectHttpServerRouteGuarded(route, server))
+ .build();
+ }
+ }
+ }
+ }
+ else if ("sse".equals(server.protocol()))
+ {
+ for (String name : asyncapi.operations.keySet())
+ {
+ AsyncapiOperation operation = asyncapi.operations.get(name);
+ if (operation.bindings == null)
+ {
+ AsyncapiChannelView channel = AsyncapiChannelView.of(asyncapi.channels, operation.channel);
+ String path = channel.address().replaceAll("\\{[^}]+\\}", "*");
+ binding
+ .route()
+ .exit("sse_server0")
+ .when(HttpConditionConfig::builder)
+ .header(":path", path)
+ .build()
+ .build();
+ }
+ }
}
}
}
@@ -154,10 +184,11 @@ private HttpOptionsConfigBuilder injectHttpServerRequests(
AsyncapiOperation operation = asyncapi.operations.get(name);
AsyncapiChannelView channel = AsyncapiChannelView.of(asyncapi.channels, operation.channel);
String path = channel.address();
- Method method = Method.valueOf(operation.bindings.get("http").method);
- if (channel.messages() != null && !channel.messages().isEmpty() ||
+
+ if (operation.bindings != null && channel.messages() != null && !channel.messages().isEmpty() ||
channel.parameters() != null && !channel.parameters().isEmpty())
{
+ Method method = Method.valueOf(operation.bindings.get("http").method);
options
.request()
.path(path)
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiMqttKafkaProxy.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiMqttKafkaProxy.java
new file mode 100644
index 0000000000..f069d12eae
--- /dev/null
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiMqttKafkaProxy.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.asyncapi.internal.config;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiOptionsConfig;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.Asyncapi;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiOperation;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.types.MqttQoS;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiChannelView;
+import io.aklivity.zilla.runtime.binding.mqtt.kafka.config.MqttKafkaConditionConfig;
+import io.aklivity.zilla.runtime.binding.mqtt.kafka.config.MqttKafkaConditionKind;
+import io.aklivity.zilla.runtime.binding.mqtt.kafka.config.MqttKafkaOptionsConfig;
+import io.aklivity.zilla.runtime.binding.mqtt.kafka.config.MqttKafkaWithConfig;
+import io.aklivity.zilla.runtime.engine.config.BindingConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.RouteConfigBuilder;
+
+public class AsyncapiMqttKafkaProxy extends AsyncapiProxy
+{
+ private static final String ASYNCAPI_KAFKA_PROTOCOL_NAME = "kafka";
+ private static final String ASYNCAPI_MQTT_PROTOCOL_NAME = "mqtt";
+ private static final String ASYNCAPI_SEND_ACTION_NAME = "send";
+ private static final String ASYNCAPI_RECEIVE_ACTION_NAME = "receive";
+
+ protected AsyncapiMqttKafkaProxy(
+ String qname,
+ Map asyncapis)
+ {
+ super("mqtt-kafka", qname, asyncapis);
+ }
+
+ @Override
+ protected BindingConfigBuilder injectProxyRoutes(
+ BindingConfigBuilder binding,
+ List routes)
+ {
+ inject:
+ for (AsyncapiRouteConfig route : routes)
+ {
+ final RouteConfigBuilder> routeBuilder = binding.route();
+
+ final Asyncapi kafkaAsyncapi = asyncapis.get(route.with.apiId);
+
+ final AsyncapiOperation withOperation = kafkaAsyncapi.operations.get(route.with.operationId);
+ final String messages = AsyncapiChannelView.of(kafkaAsyncapi.channels, withOperation.channel).address();
+
+ for (AsyncapiConditionConfig condition : route.when)
+ {
+ final Asyncapi mqttAsyncapi = asyncapis.get(condition.apiId);
+ if (mqttAsyncapi.servers.values().stream().noneMatch(s -> s.protocol.startsWith(ASYNCAPI_MQTT_PROTOCOL_NAME)))
+ {
+ break inject;
+ }
+ final AsyncapiOperation whenOperation = mqttAsyncapi.operations.get(condition.operationId);
+ final AsyncapiChannelView channel = AsyncapiChannelView.of(mqttAsyncapi.channels, whenOperation.channel);
+ final MqttKafkaConditionKind kind = whenOperation.action.equals(ASYNCAPI_SEND_ACTION_NAME) ?
+ MqttKafkaConditionKind.PUBLISH : MqttKafkaConditionKind.SUBSCRIBE;
+ String topic = channel.address();
+
+ routeBuilder
+ .when(MqttKafkaConditionConfig::builder)
+ .topic(topic)
+ .kind(kind)
+ .build()
+ .with(MqttKafkaWithConfig::builder)
+ .messages(messages.replaceAll("\\{([^{}]*)\\}", "\\${params.$1}"))
+ .build()
+ .exit(qname);
+ }
+ binding = routeBuilder.build();
+ }
+ return binding;
+ }
+
+ @Override
+ public BindingConfigBuilder injectProxyOptions(
+ BindingConfigBuilder binding,
+ AsyncapiOptionsConfig options)
+ {
+ String sessions = "";
+ String messages = "";
+ String retained = "";
+ for (Asyncapi asyncapi : asyncapis.values())
+ {
+ if (asyncapi.channels.containsKey(options.mqttKafka.channels.sessions))
+ {
+ sessions = asyncapi.channels.get(options.mqttKafka.channels.sessions).address;
+ }
+
+ if (asyncapi.channels.containsKey(options.mqttKafka.channels.messages))
+ {
+ messages = asyncapi.channels.get(options.mqttKafka.channels.messages).address;
+ }
+
+ if (asyncapi.channels.containsKey(options.mqttKafka.channels.retained))
+ {
+ retained = asyncapi.channels.get(options.mqttKafka.channels.retained).address;
+ }
+ }
+ return binding
+ .options(MqttKafkaOptionsConfig::builder)
+ .topics()
+ .sessions(sessions)
+ .messages(messages)
+ .retained(retained)
+ .build()
+ .publish()
+ .qosMax(MqttQoS.EXACTLY_ONCE.name().toLowerCase())
+ .build()
+ .clients(Collections.emptyList())
+ .build();
+ }
+}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiNamespaceGenerator.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiNamespaceGenerator.java
index ddf75ede2c..9cf08a0de7 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiNamespaceGenerator.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiNamespaceGenerator.java
@@ -16,6 +16,7 @@
import static com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature.MINIMIZE_QUOTES;
import static com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature.WRITE_DOC_START_MARKER;
+import static io.aklivity.zilla.runtime.common.feature.FeatureFilter.featureEnabled;
import static java.util.stream.Collectors.toList;
import static org.agrona.LangUtil.rethrowUnchecked;
@@ -67,7 +68,6 @@ public abstract class AsyncapiNamespaceGenerator
protected Map asyncapis;
protected boolean isTlsEnabled;
- protected AsyncapiProtocol protocol;
protected String qname;
protected String namespace;
protected String qvault;
@@ -92,7 +92,8 @@ public NamespaceConfig generate(
public NamespaceConfig generateProxy(
BindingConfig binding,
Map asyncapis,
- ToLongFunction resolveApiId)
+ ToLongFunction resolveApiId,
+ List labels)
{
return null;
}
@@ -103,7 +104,7 @@ protected AsyncapiProtocol resolveProtocol(
List asyncapis,
List servers)
{
- Pattern pattern = Pattern.compile("(http|mqtt|kafka)");
+ Pattern pattern = Pattern.compile("(http|sse|mqtt|kafka)");
Matcher matcher = pattern.matcher(protocolName);
AsyncapiProtocol protocol = null;
if (matcher.find())
@@ -113,6 +114,14 @@ protected AsyncapiProtocol resolveProtocol(
case "http":
protocol = new AsyncapiHttpProtocol(qname, asyncapis, options, protocolName);
break;
+ case "sse":
+ case "secure-sse":
+ if (featureEnabled(AsyncapiSseProtocol.class))
+ {
+ final boolean httpServerAvailable = servers.stream().anyMatch(s -> "http".equals(s.protocol()));
+ protocol = new AsyncapiSseProtocol(qname, httpServerAvailable, asyncapis, options, protocolName);
+ }
+ break;
case "mqtt":
protocol = new AsyncapiMqttProtocol(qname, asyncapis, options, protocolName, namespace);
break;
@@ -186,6 +195,20 @@ public int[] resolvePorts(
return ports;
}
+ public int[] resolvePortForServer(
+ AsyncapiServerView server,
+ boolean secure)
+ {
+ int[] ports = {};
+
+ if (server.getAsyncapiProtocol().isSecure() == secure)
+ {
+ ports = new int[] { server.getPort() };
+ }
+
+ return ports;
+ }
+
protected NamespaceConfigBuilder injectCatalog(
NamespaceConfigBuilder namespace,
List asyncapis)
@@ -275,8 +298,7 @@ protected static String writeSchemaYaml(
protected BindingConfigBuilder injectMetrics(
BindingConfigBuilder binding,
- List metricRefs,
- String protocol)
+ List metricRefs)
{
List metrics = metricRefs.stream()
.filter(m -> m.name.startsWith("stream."))
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProtocol.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProtocol.java
index 4c9a60f1bb..298886736a 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProtocol.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProtocol.java
@@ -45,6 +45,7 @@ public abstract class AsyncapiProtocol
protected Map securitySchemes;
protected boolean isJwtEnabled;
public final String scheme;
+ public final String tcpRoute;
public final String protocol;
protected AsyncapiProtocol(
@@ -52,15 +53,41 @@ protected AsyncapiProtocol(
List asyncapis,
String protocol,
String scheme)
+ {
+ this(qname, asyncapis, protocol, scheme, scheme);
+ }
+
+ protected AsyncapiProtocol(
+ String qname,
+ List asyncapis,
+ String protocol,
+ String scheme,
+ String tcpRoute)
{
this.qname = qname;
this.asyncapis = asyncapis;
this.protocol = protocol;
this.scheme = scheme;
+ this.tcpRoute = tcpRoute;
this.securitySchemes = resolveSecuritySchemes();
this.isJwtEnabled = !securitySchemes.isEmpty();
}
+ public NamespaceConfigBuilder injectProtocolRelatedServerBindings(
+ NamespaceConfigBuilder namespace,
+ List metricRefs)
+ {
+ return namespace;
+ }
+
+ public NamespaceConfigBuilder injectProtocolRelatedClientBindings(
+ NamespaceConfigBuilder namespace,
+ List metricRefs,
+ boolean isTlsEnabled)
+ {
+ return namespace;
+ }
+
public abstract BindingConfigBuilder injectProtocolServerOptions(
BindingConfigBuilder binding);
@@ -153,8 +180,7 @@ protected Map resolveSecuritySchemes()
protected BindingConfigBuilder injectMetrics(
BindingConfigBuilder binding,
- List metricRefs,
- String protocol)
+ List metricRefs)
{
if (metricRefs != null && !metricRefs.isEmpty())
{
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProxy.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProxy.java
new file mode 100644
index 0000000000..728e25f05b
--- /dev/null
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProxy.java
@@ -0,0 +1,47 @@
+/*
+ * 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.asyncapi.internal.config;
+
+import java.util.List;
+import java.util.Map;
+
+import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiOptionsConfig;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.Asyncapi;
+import io.aklivity.zilla.runtime.engine.config.BindingConfigBuilder;
+
+public abstract class AsyncapiProxy
+{
+ protected final String type;
+ protected final String qname;
+ protected final Map asyncapis;
+
+ protected AsyncapiProxy(
+ String type,
+ String qname,
+ Map asyncapis)
+ {
+ this.type = type;
+ this.qname = qname;
+ this.asyncapis = asyncapis;
+ }
+
+ protected abstract BindingConfigBuilder injectProxyRoutes(
+ BindingConfigBuilder binding,
+ List routes);
+
+ public abstract BindingConfigBuilder injectProxyOptions(
+ BindingConfigBuilder binding,
+ AsyncapiOptionsConfig options);
+}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProxyNamespaceGenerator.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProxyNamespaceGenerator.java
index 79cb502d77..cb70410dee 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProxyNamespaceGenerator.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiProxyNamespaceGenerator.java
@@ -17,37 +17,34 @@
import static io.aklivity.zilla.runtime.engine.config.KindConfig.PROXY;
import static java.util.Collections.emptyList;
-import java.util.Collections;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.ToLongFunction;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiOptionsConfig;
import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.Asyncapi;
-import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiOperation;
-import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiChannelView;
-import io.aklivity.zilla.runtime.binding.mqtt.kafka.config.MqttKafkaConditionConfig;
-import io.aklivity.zilla.runtime.binding.mqtt.kafka.config.MqttKafkaConditionKind;
-import io.aklivity.zilla.runtime.binding.mqtt.kafka.config.MqttKafkaOptionsConfig;
-import io.aklivity.zilla.runtime.binding.mqtt.kafka.config.MqttKafkaWithConfig;
import io.aklivity.zilla.runtime.engine.config.BindingConfig;
-import io.aklivity.zilla.runtime.engine.config.BindingConfigBuilder;
import io.aklivity.zilla.runtime.engine.config.MetricRefConfig;
import io.aklivity.zilla.runtime.engine.config.NamespaceConfig;
-import io.aklivity.zilla.runtime.engine.config.RouteConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.NamespaceConfigBuilder;
public class AsyncapiProxyNamespaceGenerator extends AsyncapiNamespaceGenerator
{
- private static final String ASYNCAPI_SEND_ACTION_NAME = "send";
- private static final String ASYNCAPI_RECEIVE_ACTION_NAME = "receive";
private static final String ASYNCAPI_KAFKA_PROTOCOL_NAME = "kafka";
private static final String ASYNCAPI_MQTT_PROTOCOL_NAME = "mqtt";
+ private static final String ASYNCAPI_HTTP_PROTOCOL_NAME = "http";
+ private static final String ASYNCAPI_SSE_PROTOCOL_NAME = "sse";
public NamespaceConfig generateProxy(
BindingConfig binding,
Map asyncapis,
- ToLongFunction resolveApiId)
+ ToLongFunction resolveApiId,
+ List labels)
{
AsyncapiOptionsConfig options = binding.options != null ? (AsyncapiOptionsConfig) binding.options : EMPTY_OPTION;
List routes = binding.routes.stream()
@@ -58,92 +55,76 @@ public NamespaceConfig generateProxy(
final List metricRefs = binding.telemetryRef != null ?
binding.telemetryRef.metricRefs : emptyList();
- String sessions = "";
- String messages = "";
- String retained = "";
- for (Asyncapi asyncapi : asyncapis.values())
- {
- if (asyncapi.channels.containsKey(options.mqttKafka.channels.sessions))
- {
- sessions = asyncapi.channels.get(options.mqttKafka.channels.sessions).address;
- }
-
- if (asyncapi.channels.containsKey(options.mqttKafka.channels.messages))
- {
- messages = asyncapi.channels.get(options.mqttKafka.channels.messages).address;
- }
+ final Map> routesByProtocol = new HashMap<>();
- if (asyncapi.channels.containsKey(options.mqttKafka.channels.retained))
- {
- retained = asyncapi.channels.get(options.mqttKafka.channels.retained).address;
- }
- }
-
- return NamespaceConfig.builder()
- .name(String.format("%s/%s", qname, "mqtt-kafka"))
- .inject(n -> this.injectNamespaceMetric(n, !metricRefs.isEmpty()))
- .binding()
- .name("mqtt_kafka_proxy0")
- .type("mqtt-kafka")
- .kind(PROXY)
- .inject(b -> this.injectMetrics(b, metricRefs, "mqtt-kafka"))
- .options(MqttKafkaOptionsConfig::builder)
- .topics()
- .sessions(sessions)
- .messages(messages)
- .retained(retained)
- .build()
- .clients(Collections.emptyList())
- .build()
- .inject(b -> this.injectMqttKafkaRoutes(b, routes))
- .build()
- .build();
- }
-
- public BindingConfigBuilder injectMqttKafkaRoutes(
- BindingConfigBuilder binding,
- List routes)
- {
inject:
for (AsyncapiRouteConfig route : routes)
{
- final RouteConfigBuilder> routeBuilder = binding.route();
-
final Asyncapi kafkaAsyncapi = asyncapis.get(route.with.apiId);
-
if (kafkaAsyncapi.servers.values().stream().anyMatch(s -> !s.protocol.startsWith(ASYNCAPI_KAFKA_PROTOCOL_NAME)))
{
break inject;
}
- final AsyncapiOperation withOperation = kafkaAsyncapi.operations.get(route.with.operationId);
- final String messages = AsyncapiChannelView.of(kafkaAsyncapi.channels, withOperation.channel).address();
-
for (AsyncapiConditionConfig condition : route.when)
{
- final Asyncapi mqttAsyncapi = asyncapis.get(condition.apiId);
- if (mqttAsyncapi.servers.values().stream().anyMatch(s -> !s.protocol.startsWith(ASYNCAPI_MQTT_PROTOCOL_NAME)))
+ final Asyncapi asyncapi = asyncapis.get(condition.apiId);
+ if (asyncapi.servers.values().stream().anyMatch(s ->
+ !s.protocol.startsWith(ASYNCAPI_MQTT_PROTOCOL_NAME) &&
+ !s.protocol.startsWith(ASYNCAPI_HTTP_PROTOCOL_NAME) &&
+ !s.protocol.startsWith(ASYNCAPI_SSE_PROTOCOL_NAME)))
{
break inject;
}
- final AsyncapiOperation whenOperation = mqttAsyncapi.operations.get(condition.operationId);
- final AsyncapiChannelView channel = AsyncapiChannelView.of(mqttAsyncapi.channels, whenOperation.channel);
- final MqttKafkaConditionKind kind = whenOperation.action.equals(ASYNCAPI_SEND_ACTION_NAME) ?
- MqttKafkaConditionKind.PUBLISH : MqttKafkaConditionKind.SUBSCRIBE;
- String topic = channel.address();
+ asyncapi.servers.values()
+ .forEach(s -> routesByProtocol.computeIfAbsent(s.protocol, c -> new ArrayList<>()).add(route));
+ }
+ }
+
+ final String namespace = String.join("+", labels);
+ NamespaceConfigBuilder builder = NamespaceConfig.builder()
+ .name(String.format("%s/%s", qname, namespace))
+ .inject(n -> this.injectNamespaceMetric(n, !metricRefs.isEmpty()));
+
+ routesByProtocol.forEach((k, r) ->
+ {
+ final AsyncapiProxy proxy = resolveProxy(k);
+ builder.binding()
+ .name(String.format("%s_proxy0", proxy.type))
+ .type(proxy.type)
+ .kind(PROXY)
+ .inject(b -> this.injectMetrics(b, metricRefs))
+ .inject(b -> proxy.injectProxyOptions(b, options))
+ .inject(b -> proxy.injectProxyRoutes(b, r))
+ .build();
+ });
- routeBuilder
- .when(MqttKafkaConditionConfig::builder)
- .topic(topic)
- .kind(kind)
- .build()
- .with(MqttKafkaWithConfig::builder)
- .messages(messages.replaceAll("\\{([^{}]*)\\}", "\\${params.$1}"))
- .build()
- .exit(qname);
+
+ return builder.build();
+ }
+
+ private AsyncapiProxy resolveProxy(
+ String protocol)
+ {
+ Pattern pattern = Pattern.compile("(http|mqtt|sse)");
+ Matcher matcher = pattern.matcher(protocol);
+ AsyncapiProxy proxy = null;
+ if (matcher.find())
+ {
+ switch (matcher.group())
+ {
+ case "http":
+ proxy = new AsyncapiHttpKafkaProxy(qname, asyncapis);
+ break;
+ case "sse":
+ proxy = new AsyncapiSseKafkaProxy(qname, asyncapis);
+ break;
+ case "mqtt":
+ proxy = new AsyncapiMqttKafkaProxy(qname, asyncapis);
+ break;
}
- binding = routeBuilder.build();
}
- return binding;
+ return proxy;
}
+
}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiServerNamespaceGenerator.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiServerNamespaceGenerator.java
index c58961015a..6fb4caac16 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiServerNamespaceGenerator.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiServerNamespaceGenerator.java
@@ -23,12 +23,14 @@
import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiServerView;
import io.aklivity.zilla.runtime.binding.tcp.config.TcpConditionConfig;
import io.aklivity.zilla.runtime.binding.tcp.config.TcpOptionsConfig;
+import io.aklivity.zilla.runtime.binding.tls.config.TlsConditionConfig;
import io.aklivity.zilla.runtime.binding.tls.config.TlsOptionsConfig;
import io.aklivity.zilla.runtime.engine.config.BindingConfig;
import io.aklivity.zilla.runtime.engine.config.BindingConfigBuilder;
import io.aklivity.zilla.runtime.engine.config.MetricRefConfig;
import io.aklivity.zilla.runtime.engine.config.NamespaceConfig;
import io.aklivity.zilla.runtime.engine.config.NamespaceConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.RouteConfigBuilder;
public class AsyncapiServerNamespaceGenerator extends AsyncapiNamespaceGenerator
{
@@ -41,9 +43,6 @@ public NamespaceConfig generate(
final List metricRefs = binding.telemetryRef != null ?
binding.telemetryRef.metricRefs : emptyList();
- //TODO: keep it until we support different protocols on the same composite binding
- AsyncapiServerView serverView = servers.get(0);
- this.protocol = serverView.getAsyncapiProtocol();
final String namespace = String.join("+", namespaceConfig.asyncapiLabels);
return NamespaceConfig.builder()
@@ -51,16 +50,44 @@ public NamespaceConfig generate(
.inject(n -> this.injectNamespaceMetric(n, !metricRefs.isEmpty()))
.inject(n -> this.injectCatalog(n, namespaceConfig.asyncapis))
.inject(n -> injectTcpServer(n, servers, options, metricRefs))
- .inject(n -> injectTlsServer(n, options))
+ .inject(n -> injectTlsServer(n, servers, options))
+ .inject(n -> injectProtocolRelatedBindings(n, servers, metricRefs))
+ .inject(n -> injectProtocolServers(n, servers, metricRefs))
+ .build();
+ }
+
+ protected NamespaceConfigBuilder injectProtocolRelatedBindings(
+ NamespaceConfigBuilder namespace,
+ List servers,
+ List metricRefs)
+ {
+ for (AsyncapiServerView server : servers)
+ {
+ final AsyncapiProtocol protocol = server.getAsyncapiProtocol();
+ namespace = protocol.injectProtocolRelatedServerBindings(namespace, metricRefs);
+ }
+ return namespace;
+ }
+
+ private NamespaceConfigBuilder injectProtocolServers(
+ NamespaceConfigBuilder namespace,
+ List servers,
+ List metricRefs)
+ {
+ for (AsyncapiServerView server : servers)
+ {
+ final AsyncapiProtocol protocol = server.getAsyncapiProtocol();
+ namespace = namespace
.binding()
.name(String.format("%s_server0", protocol.scheme))
.type(protocol.scheme)
- .inject(b -> this.injectMetrics(b, metricRefs, protocol.scheme))
+ .inject(b -> this.injectMetrics(b, metricRefs))
.kind(SERVER)
- .inject(b -> protocol.injectProtocolServerOptions(b))
- .inject(b -> protocol.injectProtocolServerRoutes(b))
- .build()
+ .inject(protocol::injectProtocolServerOptions)
+ .inject(protocol::injectProtocolServerRoutes)
.build();
+ }
+ return namespace;
}
private NamespaceConfigBuilder injectTcpServer(
@@ -70,10 +97,6 @@ private NamespaceConfigBuilder injectTcpServer(
List metricRefs)
{
int[] allPorts = resolveAllPorts(servers);
- int[] compositePorts = resolvePorts(servers, false);
- int[] compositeSecurePorts = resolvePorts(servers, true);
-
- this.isTlsEnabled = compositeSecurePorts.length > 0;
final TcpOptionsConfig tcpOption = options.tcp != null ? options.tcp :
TcpOptionsConfig.builder()
@@ -86,56 +109,74 @@ private NamespaceConfigBuilder injectTcpServer(
.name("tcp_server0")
.type("tcp")
.kind(SERVER)
- .inject(b -> this.injectMetrics(b, metricRefs, "tcp"))
+ .inject(b -> this.injectMetrics(b, metricRefs))
.options(tcpOption)
- .inject(b -> this.injectPlainTcpRoute(b, compositePorts))
- .inject(b -> this.injectTlsTcpRoute(b, compositeSecurePorts, metricRefs))
+ .inject(b -> this.injectPlainTcpRoute(b, servers))
+ .inject(b -> this.injectTlsTcpRoute(b, servers, metricRefs))
.build();
return namespace;
}
- private BindingConfigBuilder injectPlainTcpRoute(
+ protected BindingConfigBuilder injectPlainTcpRoute(
BindingConfigBuilder binding,
- int[] compositePorts)
+ List servers)
{
- binding
- .route()
+ for (AsyncapiServerView server : servers)
+ {
+ final RouteConfigBuilder> routeBuilder = binding.route();
+ final AsyncapiProtocol protocol = server.getAsyncapiProtocol();
+ final int[] compositePorts = new int[] { server.getPort() };
+ binding = routeBuilder
.when(TcpConditionConfig::builder)
.ports(compositePorts)
.build()
- .exit(String.format("%s_server0", protocol.scheme))
- .build();
+ .exit(String.format("%s_server0", protocol.tcpRoute))
+ .build();
+ }
return binding;
}
private BindingConfigBuilder injectTlsTcpRoute(
BindingConfigBuilder binding,
- int[] compositeSecurePorts,
+ List servers,
List metricRefs)
{
- if (isTlsEnabled)
+ for (AsyncapiServerView server : servers)
{
- binding
- .inject(b -> this.injectMetrics(b, metricRefs, "tls"))
- .route()
- .when(TcpConditionConfig::builder)
+ final RouteConfigBuilder> routeBuilder = binding.route();
+ int[] compositeSecurePorts = resolvePortForServer(server, true);
+
+ if (compositeSecurePorts.length > 0)
+ {
+ isTlsEnabled = true;
+ binding =
+ routeBuilder
+ .when(TcpConditionConfig::builder)
.ports(compositeSecurePorts)
.build()
.exit("tls_server0")
.build();
+ }
+ }
+ if (isTlsEnabled)
+ {
+ binding = binding
+ .inject(b -> this.injectMetrics(b, metricRefs));
}
return binding;
}
private NamespaceConfigBuilder injectTlsServer(
NamespaceConfigBuilder namespace,
+ List servers,
AsyncapiOptionsConfig options)
{
+ BindingConfigBuilder> binding = namespace.binding();
if (isTlsEnabled)
{
- namespace
- .binding()
+ binding =
+ binding
.name("tls_server0")
.type("tls")
.kind(SERVER)
@@ -144,9 +185,21 @@ private NamespaceConfigBuilder injectTlsServer(
.sni(options.tls.sni)
.alpn(options.tls.alpn)
.build()
- .vault(String.format("%s:%s", this.namespace, vault))
+ .vault(String.format("%s:%s", this.namespace, vault));
+ }
+ for (AsyncapiServerView server : servers)
+ {
+ final RouteConfigBuilder>> routeBuilder = binding.route();
+ final AsyncapiProtocol protocol = server.getAsyncapiProtocol();
+ if (protocol.isSecure())
+ {
+ routeBuilder
+ .when(TlsConditionConfig::builder)
+ .ports(new int[] { server.getPort() })
+ .build()
.exit(String.format("%s_server0", protocol.scheme))
.build();
+ }
}
return namespace;
}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiSseKafkaProxy.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiSseKafkaProxy.java
new file mode 100644
index 0000000000..fae1fea243
--- /dev/null
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiSseKafkaProxy.java
@@ -0,0 +1,140 @@
+/*
+ * 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.asyncapi.internal.config;
+
+import static io.aklivity.zilla.runtime.binding.sse.kafka.config.SseKafkaWithConfig.EVENT_ID_DEFAULT;
+
+import java.util.List;
+import java.util.Map;
+
+import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiOptionsConfig;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.Asyncapi;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiOperation;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiChannelView;
+import io.aklivity.zilla.runtime.binding.sse.kafka.config.SseKafkaConditionConfig;
+import io.aklivity.zilla.runtime.binding.sse.kafka.config.SseKafkaWithConfig;
+import io.aklivity.zilla.runtime.binding.sse.kafka.config.SseKafkaWithConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.BindingConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.RouteConfigBuilder;
+
+public class AsyncapiSseKafkaProxy extends AsyncapiProxy
+{
+ private static final String ASYNCAPI_KAFKA_PROTOCOL_NAME = "kafka";
+ private static final String ASYNCAPI_SSE_PROTOCOL_NAME = "sse";
+ private static final String ASYNCAPI_RECEIVE_ACTION_NAME = "receive";
+
+ protected AsyncapiSseKafkaProxy(
+ String qname,
+ Map asyncapis)
+ {
+ super("sse-kafka", qname, asyncapis);
+ }
+
+ @Override
+ protected BindingConfigBuilder injectProxyRoutes(
+ BindingConfigBuilder binding,
+ List routes)
+ {
+ inject:
+ for (AsyncapiRouteConfig route : routes)
+ {
+ final Asyncapi kafkaAsyncapi = asyncapis.get(route.with.apiId);
+
+ for (AsyncapiConditionConfig condition : route.when)
+ {
+ final Asyncapi sseAsyncapi = asyncapis.get(condition.apiId);
+ if (sseAsyncapi.servers.values().stream().noneMatch(s -> s.protocol.startsWith(ASYNCAPI_SSE_PROTOCOL_NAME)))
+ {
+ break inject;
+ }
+ final AsyncapiOperation whenOperation = sseAsyncapi.operations.get(condition.operationId);
+ if (whenOperation == null)
+ {
+ for (Map.Entry e : sseAsyncapi.operations.entrySet())
+ {
+ AsyncapiOperation withOperation = route.with.operationId != null ?
+ kafkaAsyncapi.operations.get(route.with.operationId) : kafkaAsyncapi.operations.get(e.getKey());
+ if (withOperation != null)
+ {
+ binding = addSseKafkaRoute(binding, kafkaAsyncapi, sseAsyncapi, e.getValue(), withOperation);
+ }
+ }
+ }
+ else
+ {
+ AsyncapiOperation withOperation = kafkaAsyncapi.operations.get(route.with.operationId);
+ binding = addSseKafkaRoute(binding, kafkaAsyncapi, sseAsyncapi, whenOperation, withOperation);
+ }
+ }
+ }
+ return binding;
+ }
+
+ private BindingConfigBuilder addSseKafkaRoute(
+ BindingConfigBuilder binding,
+ Asyncapi kafkaAsyncapi,
+ Asyncapi sseAsyncapi,
+ AsyncapiOperation whenOperation,
+ AsyncapiOperation withOperation)
+ {
+
+ if (whenOperation.bindings == null)
+ {
+ final AsyncapiChannelView channel = AsyncapiChannelView.of(sseAsyncapi.channels, whenOperation.channel);
+ String path = channel.address();
+
+ final RouteConfigBuilder> routeBuilder = binding.route();
+ routeBuilder
+ .exit(qname)
+ .when(SseKafkaConditionConfig::builder)
+ .path(path)
+ .build()
+ .inject(r -> injectSseKafkaRouteWith(r, kafkaAsyncapi, withOperation));
+ binding = routeBuilder.build();
+ }
+ return binding;
+ }
+
+ @Override
+ public BindingConfigBuilder injectProxyOptions(
+ BindingConfigBuilder binding,
+ AsyncapiOptionsConfig options)
+ {
+ return binding;
+ }
+
+ private RouteConfigBuilder injectSseKafkaRouteWith(
+ RouteConfigBuilder route,
+ Asyncapi kafkaAsyncapi,
+ AsyncapiOperation kafkaOperation)
+ {
+ final SseKafkaWithConfigBuilder newWith = SseKafkaWithConfig.builder();
+ final AsyncapiChannelView channel = AsyncapiChannelView
+ .of(kafkaAsyncapi.channels, kafkaOperation.channel);
+ final String topic = channel.address();
+
+ if (ASYNCAPI_RECEIVE_ACTION_NAME.equals(kafkaOperation.action))
+ {
+ newWith
+ .topic(topic)
+ .eventId(EVENT_ID_DEFAULT)
+ .build();
+ }
+
+ route.with(newWith.build());
+
+ return route;
+ }
+}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiSseProtocol.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiSseProtocol.java
new file mode 100644
index 0000000000..b37dd34751
--- /dev/null
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AsyncapiSseProtocol.java
@@ -0,0 +1,172 @@
+/*
+ * 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.asyncapi.internal.config;
+
+import static io.aklivity.zilla.runtime.binding.asyncapi.internal.config.AsyncapiNamespaceGenerator.APPLICATION_JSON;
+import static io.aklivity.zilla.runtime.engine.config.KindConfig.CLIENT;
+import static io.aklivity.zilla.runtime.engine.config.KindConfig.SERVER;
+
+import java.util.List;
+import java.util.Map;
+
+import io.aklivity.zilla.runtime.binding.asyncapi.config.AsyncapiOptionsConfig;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.Asyncapi;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiChannel;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiMessage;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.model.AsyncapiOperation;
+import io.aklivity.zilla.runtime.binding.asyncapi.internal.view.AsyncapiChannelView;
+import io.aklivity.zilla.runtime.binding.sse.config.SseConditionConfig;
+import io.aklivity.zilla.runtime.binding.sse.config.SseOptionsConfig;
+import io.aklivity.zilla.runtime.binding.sse.config.SseOptionsConfigBuilder;
+import io.aklivity.zilla.runtime.common.feature.Incubating;
+import io.aklivity.zilla.runtime.engine.config.BindingConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.MetricRefConfig;
+import io.aklivity.zilla.runtime.engine.config.NamespaceConfigBuilder;
+import io.aklivity.zilla.runtime.model.json.config.JsonModelConfig;
+
+@Incubating
+public class AsyncapiSseProtocol extends AsyncapiProtocol
+{
+ private static final String SCHEME = "sse";
+ private static final String SECURE_PROTOCOL = "secure-sse";
+
+ private final boolean httpServerAvailable;
+ private final AsyncapiOptionsConfig options;
+
+ protected AsyncapiSseProtocol(
+ String qname,
+ boolean httpServerAvailable,
+ List asyncapis,
+ AsyncapiOptionsConfig options,
+ String protocol)
+ {
+ super(qname, asyncapis, protocol, SCHEME, "http");
+ this.httpServerAvailable = httpServerAvailable;
+ this.options = options;
+ }
+
+ @Override
+ public NamespaceConfigBuilder injectProtocolRelatedServerBindings(
+ NamespaceConfigBuilder namespace,
+ List metricRefs)
+ {
+ if (!httpServerAvailable)
+ {
+ final AsyncapiProtocol httpProtocol = new AsyncapiHttpProtocol(qname, asyncapis, options, "http");
+
+ namespace
+ .binding()
+ .name(String.format("%s_server0", httpProtocol.scheme))
+ .type(httpProtocol.scheme)
+ .inject(b -> this.injectMetrics(b, metricRefs))
+ .kind(SERVER)
+ .inject(httpProtocol::injectProtocolServerOptions)
+ .inject(httpProtocol::injectProtocolServerRoutes)
+ .build();
+ }
+ return namespace;
+ }
+
+ @Override
+ public BindingConfigBuilder injectProtocolServerOptions(
+ BindingConfigBuilder binding)
+ {
+ binding
+ .options(SseOptionsConfig::builder)
+ .inject(this::injectSsePathsOptions)
+ .build();
+ return binding;
+ }
+
+ @Override
+ public BindingConfigBuilder injectProtocolServerRoutes(
+ BindingConfigBuilder binding)
+ {
+ for (Asyncapi asyncapi : asyncapis)
+ {
+ for (String name : asyncapi.operations.keySet())
+ {
+ AsyncapiOperation operation = asyncapi.operations.get(name);
+ if (operation.bindings == null)
+ {
+ AsyncapiChannelView channel = AsyncapiChannelView.of(asyncapi.channels, operation.channel);
+ String path = channel.address().replaceAll("\\{[^}]+\\}", "*");
+ binding
+ .route()
+ .exit(qname)
+ .when(SseConditionConfig::builder)
+ .path(path)
+ .build()
+ .build();
+ }
+ }
+ }
+ return binding;
+ }
+
+ @Override
+ public NamespaceConfigBuilder injectProtocolRelatedClientBindings(
+ NamespaceConfigBuilder namespace,
+ List metricRefs,
+ boolean isTlsEnabled)
+ {
+ if (!httpServerAvailable)
+ {
+ namespace
+ .binding()
+ .name(String.format("%s_client0", "http"))
+ .type("http")
+ .kind(CLIENT)
+ .inject(b -> this.injectMetrics(b, metricRefs))
+ .exit(isTlsEnabled ? "tls_client0" : "tcp_client0")
+ .build();
+ }
+ return namespace;
+ }
+
+ @Override
+ protected boolean isSecure()
+ {
+ return protocol.equals(SECURE_PROTOCOL);
+ }
+
+
+ private SseOptionsConfigBuilder injectSsePathsOptions(
+ SseOptionsConfigBuilder options)
+ {
+ for (Asyncapi asyncapi : asyncapis)
+ {
+ for (Map.Entry channelEntry : asyncapi.channels.entrySet())
+ {
+ String path = channelEntry.getValue().address.replaceAll("\\{[^}]+\\}", "*");
+ Map messages = channelEntry.getValue().messages;
+ if (hasJsonContentType(asyncapi))
+ {
+ options
+ .request()
+ .path(path)
+ .content(JsonModelConfig::builder)
+ .catalog()
+ .name(INLINE_CATALOG_NAME)
+ .inject(cataloged -> injectJsonSchemas(cataloged, asyncapi, messages, APPLICATION_JSON))
+ .build()
+ .build()
+ .build();
+ }
+ }
+ }
+ return options;
+ }
+}
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AyncapiKafkaProtocol.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AyncapiKafkaProtocol.java
index dbe6cd174b..6f5dc1004b 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AyncapiKafkaProtocol.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/config/AyncapiKafkaProtocol.java
@@ -71,7 +71,7 @@ public NamespaceConfigBuilder injectProtocolClientCache(
.name("kafka_cache_client0")
.type("kafka")
.kind(KindConfig.CACHE_CLIENT)
- .inject(b -> this.injectMetrics(b, metricRefs, "kafka"))
+ .inject(b -> this.injectMetrics(b, metricRefs))
.options(KafkaOptionsConfig::builder)
.inject(this::injectKafkaTopicOptions)
.build()
@@ -81,7 +81,7 @@ public NamespaceConfigBuilder injectProtocolClientCache(
.name("kafka_cache_server0")
.type("kafka")
.kind(KindConfig.CACHE_SERVER)
- .inject(b -> this.injectMetrics(b, metricRefs, "kafka"))
+ .inject(b -> this.injectMetrics(b, metricRefs))
.options(KafkaOptionsConfig::builder)
.inject(this::injectKafkaBootstrapOptions)
.inject(this::injectKafkaTopicOptions)
diff --git a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/model/AsyncapiComponents.java b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/model/AsyncapiComponents.java
index 5f751c1b67..185abee13e 100644
--- a/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/model/AsyncapiComponents.java
+++ b/runtime/binding-asyncapi/src/main/java/io/aklivity/zilla/runtime/binding/asyncapi/internal/model/AsyncapiComponents.java
@@ -21,6 +21,7 @@ public class AsyncapiComponents
public Map securitySchemes;
public Map messages;
public Map schemas;
+ public Map correlationIds;
public Map