diff --git a/incubator/catalog-schema-registry.spec/src/main/resources/META-INF/zilla/schema_registry.idl b/incubator/catalog-schema-registry.spec/src/main/resources/META-INF/zilla/schema_registry.idl
index df61e3605c..ae86ba3c4c 100644
--- a/incubator/catalog-schema-registry.spec/src/main/resources/META-INF/zilla/schema_registry.idl
+++ b/incubator/catalog-schema-registry.spec/src/main/resources/META-INF/zilla/schema_registry.idl
@@ -21,16 +21,16 @@ scope schema_registry
REMOTE_ACCESS_REJECTED (1)
}
- struct SchemaRegistryRemoteAccessRejected extends core::event::Event
+ struct SchemaRegistryRemoteAccessRejectedEx extends core::stream::Extension
{
string8 method;
string16 url;
int16 status;
}
- union SchemaRegistryEvent switch (SchemaRegistryEventType)
+ union SchemaRegistryEventEx switch (SchemaRegistryEventType)
{
- case REMOTE_ACCESS_REJECTED: SchemaRegistryRemoteAccessRejected remoteAccessRejected;
+ case REMOTE_ACCESS_REJECTED: SchemaRegistryRemoteAccessRejectedEx remoteAccessRejected;
}
}
}
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/config/client.yaml b/incubator/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/config/event.yaml
similarity index 62%
rename from incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/config/client.yaml
rename to incubator/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/config/event.yaml
index ff4c4a3aea..7e4e18bc0f 100644
--- a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/config/client.yaml
+++ b/incubator/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/config/event.yaml
@@ -17,10 +17,22 @@
name: test
telemetry:
exporters:
- stdout0:
- type: stdout
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.catalog0
+ message: REMOTE_ACCESS_REJECTED GET http://localhost:8081/schemas/ids/0 0
+catalogs:
+ catalog0:
+ type: schema-registry
+ options:
+ url: http://localhost:8081
bindings:
- app0:
- type: kafka
- kind: client
- exit: net0
+ net0:
+ type: test
+ kind: server
+ options:
+ catalogs:
+ - catalog0
+ exit: app0
diff --git a/incubator/catalog-schema-registry/pom.xml b/incubator/catalog-schema-registry/pom.xml
index 22c39b3d02..eb3a2dc794 100644
--- a/incubator/catalog-schema-registry/pom.xml
+++ b/incubator/catalog-schema-registry/pom.xml
@@ -24,7 +24,7 @@
11
11
- 0.80
+ 0.90
0
diff --git a/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventContext.java b/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventContext.java
index 42770a31b1..baa8c36fb8 100644
--- a/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventContext.java
+++ b/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventContext.java
@@ -14,14 +14,17 @@
*/
package io.aklivity.zilla.runtime.catalog.schema.registry.internal;
+import static io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.event.SchemaRegistryEventType.REMOTE_ACCESS_REJECTED;
+
import java.net.http.HttpRequest;
import java.nio.ByteBuffer;
import java.time.Clock;
-import org.agrona.MutableDirectBuffer;
+import org.agrona.concurrent.AtomicBuffer;
import org.agrona.concurrent.UnsafeBuffer;
-import io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.event.SchemaRegistryEventFW;
+import io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.event.SchemaRegistryEventExFW;
import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
@@ -29,8 +32,10 @@ public class SchemaRegistryEventContext
{
private static final int EVENT_BUFFER_CAPACITY = 1024;
- private final SchemaRegistryEventFW.Builder schemaRegistryEventRW = new SchemaRegistryEventFW.Builder();
- private final MutableDirectBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer extensionBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final EventFW.Builder eventRW = new EventFW.Builder();
+ private final SchemaRegistryEventExFW.Builder schemaRegistryEventExRW = new SchemaRegistryEventExFW.Builder();
private final int schemaRegistryTypeId;
private final MessageConsumer eventWriter;
private final Clock clock;
@@ -48,17 +53,22 @@ public void remoteAccessRejected(
HttpRequest httpRequest,
int status)
{
- SchemaRegistryEventFW event = schemaRegistryEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ SchemaRegistryEventExFW extension = schemaRegistryEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.remoteAccessRejected(e -> e
- .timestamp(clock.millis())
- .traceId(0L)
- .namespacedId(catalogId)
+ .typeId(REMOTE_ACCESS_REJECTED.value())
.method(httpRequest.method())
.url(httpRequest.uri().toString())
.status((short) status)
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(0L)
+ .namespacedId(catalogId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(schemaRegistryTypeId, event.buffer(), event.offset(), event.limit());
}
}
diff --git a/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventFormatter.java b/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventFormatter.java
new file mode 100644
index 0000000000..73d2ea40ec
--- /dev/null
+++ b/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventFormatter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.runtime.catalog.schema.registry.internal;
+
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.StringFW;
+import io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.event.SchemaRegistryEventExFW;
+import io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.event.SchemaRegistryRemoteAccessRejectedExFW;
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;
+
+public final class SchemaRegistryEventFormatter implements EventFormatterSpi
+{
+ private static final String REMOTE_ACCESS_REJECTED = "REMOTE_ACCESS_REJECTED %s %s %d";
+
+ private final EventFW eventRO = new EventFW();
+ private final SchemaRegistryEventExFW schemaRegistryEventExRO = new SchemaRegistryEventExFW();
+
+ SchemaRegistryEventFormatter(
+ Configuration config)
+ {
+ }
+
+ public String format(
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ final SchemaRegistryEventExFW extension = schemaRegistryEventExRO
+ .wrap(event.extension().buffer(), event.extension().offset(), event.extension().limit());
+ String result = null;
+ switch (extension.kind())
+ {
+ case REMOTE_ACCESS_REJECTED:
+ {
+ SchemaRegistryRemoteAccessRejectedExFW ex = extension.remoteAccessRejected();
+ result = String.format(REMOTE_ACCESS_REJECTED, asString(ex.method()), asString(ex.url()),
+ ex.status());
+ break;
+ }
+ }
+ return result;
+ }
+
+ private static String asString(
+ StringFW stringFW)
+ {
+ String s = stringFW.asString();
+ return s == null ? "" : s;
+ }
+}
diff --git a/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventFormatterFactory.java b/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventFormatterFactory.java
new file mode 100644
index 0000000000..dab25606c1
--- /dev/null
+++ b/incubator/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryEventFormatterFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.runtime.catalog.schema.registry.internal;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
+
+public final class SchemaRegistryEventFormatterFactory implements EventFormatterFactorySpi
+{
+ @Override
+ public SchemaRegistryEventFormatter create(
+ Configuration config)
+ {
+ return new SchemaRegistryEventFormatter(config);
+ }
+
+ @Override
+ public String type()
+ {
+ return SchemaRegistryCatalog.NAME;
+ }
+}
diff --git a/incubator/catalog-schema-registry/src/main/moditect/module-info.java b/incubator/catalog-schema-registry/src/main/moditect/module-info.java
index 3c87217f1f..0481132093 100644
--- a/incubator/catalog-schema-registry/src/main/moditect/module-info.java
+++ b/incubator/catalog-schema-registry/src/main/moditect/module-info.java
@@ -22,4 +22,7 @@
provides io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi
with io.aklivity.zilla.runtime.catalog.schema.registry.internal.config.SchemaRegistryOptionsConfigAdapter;
+
+ provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
+ with io.aklivity.zilla.runtime.catalog.schema.registry.internal.SchemaRegistryEventFormatterFactory;
}
diff --git a/incubator/catalog-schema-registry/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi b/incubator/catalog-schema-registry/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
new file mode 100644
index 0000000000..dc17437b9b
--- /dev/null
+++ b/incubator/catalog-schema-registry/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.catalog.schema.registry.internal.SchemaRegistryEventFormatterFactory
\ No newline at end of file
diff --git a/incubator/catalog-schema-registry/src/test/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/EventIT.java b/incubator/catalog-schema-registry/src/test/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/EventIT.java
new file mode 100644
index 0000000000..a558900735
--- /dev/null
+++ b/incubator/catalog-schema-registry/src/test/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/EventIT.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.runtime.catalog.schema.registry.internal;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.rules.RuleChain.outerRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.DisableOnDebug;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.kaazing.k3po.junit.annotation.Specification;
+import org.kaazing.k3po.junit.rules.K3poRule;
+
+import io.aklivity.zilla.runtime.engine.test.EngineRule;
+import io.aklivity.zilla.runtime.engine.test.annotation.Configuration;
+
+public class EventIT
+{
+ private final K3poRule k3po = new K3poRule()
+ .addScriptRoot("net", "io/aklivity/zilla/specs/engine/streams/network")
+ .addScriptRoot("app", "io/aklivity/zilla/specs/engine/streams/application");
+
+ private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS));
+
+ private final EngineRule engine = new EngineRule()
+ .directory("target/zilla-itests")
+ .countersBufferCapacity(4096)
+ .configurationRoot("io/aklivity/zilla/specs/catalog/schema/registry/config")
+ .external("app0")
+ .clean();
+
+ @Rule
+ public final TestRule chain = outerRule(engine).around(k3po).around(timeout);
+
+ @Test
+ @Configuration("event.yaml")
+ @Specification({
+ "${net}/event/client",
+ "${app}/event/server"
+ })
+ public void shouldLogEvents() throws Exception
+ {
+ k3po.finish();
+ }
+}
diff --git a/incubator/exporter-stdout.spec/pom.xml b/incubator/exporter-stdout.spec/pom.xml
index 8db58bd8c7..d099bd275d 100644
--- a/incubator/exporter-stdout.spec/pom.xml
+++ b/incubator/exporter-stdout.spec/pom.xml
@@ -41,18 +41,6 @@
engine.spec
${project.version}
-
- ${project.groupId}
- binding-http.spec
- ${project.version}
- test
-
-
- ${project.groupId}
- binding-proxy.spec
- ${project.version}
- test
-
junit
junit
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.authorization.credentials.yaml b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.authorization.credentials.yaml
deleted file mode 100644
index a6daa035f9..0000000000
--- a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.authorization.credentials.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Copyright 2021-2023 Aklivity Inc
-#
-# Licensed under the Aklivity Community License (the "License"); you may not use
-# this file except in compliance with the License. You may obtain a copy of the
-# License at
-#
-# https://www.aklivity.io/aklivity-community-license/
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OF ANY KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations under the License.
-#
-
----
-name: test
-telemetry:
- exporters:
- stdout0:
- type: stdout
-guards:
- jwt0:
- type: jwt
- options:
- issuer: https://auth.example.com
- audience: https://api.example.com
- keys:
- - kty: RSA
- n: qqEu50hX+43Bx4W1UYWnAVKwFm+vDbP0kuIOSLVNa+HKQdHTf+3Sei5UCnkskn796izA29D0DdCy3ET9oaKRHIJyKbqFl0rv6f516QzOoXKC6N01sXBHBE/ovs0wwDvlaW+gFGPgkzdcfUlyrWLDnLV7LcuQymhTND2uH0oR3wJnNENN/OFgM1KGPPDOe19YsIKdLqARgxrhZVsh06OurEviZTXOBFI5r+yac7haDwOQhLHXNv+Y9MNvxs5QLWPFIM3bNUWfYrJnLrs4hGJS+y/KDM9Si+HL30QAFXy4YNO33J8DHjZ7ddG5n8/FqplOKvRtUgjcKWlxoGY4VdVaDQ==
- e: AQAB
- alg: RS256
- kid: example
-bindings:
- net0:
- type: http
- kind: server
- options:
- versions:
- - http/1.1
- authorization:
- jwt0:
- credentials:
- cookies:
- access_token: "{credentials}"
- headers:
- authorization: Bearer {credentials}
- query:
- access_token: "{credentials}"
- routes:
- - exit: app0
- guarded:
- jwt0: []
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.yaml b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.yaml
deleted file mode 100644
index 7202d45307..0000000000
--- a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright 2021-2023 Aklivity Inc
-#
-# Licensed under the Aklivity Community License (the "License"); you may not use
-# this file except in compliance with the License. You may obtain a copy of the
-# License at
-#
-# https://www.aklivity.io/aklivity-community-license/
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OF ANY KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations under the License.
-#
-
----
-name: test
-telemetry:
- exporters:
- stdout0:
- type: stdout
-bindings:
- net0:
- type: http
- kind: server
- options:
- versions:
- - http/1.1
- routes:
- - exit: app0
- when:
- - headers:
- :authority: localhost:8080
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tcp/config/client.host.yaml b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tcp/config/client.host.yaml
deleted file mode 100644
index 04191ddc52..0000000000
--- a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tcp/config/client.host.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright 2021-2023 Aklivity Inc
-#
-# Licensed under the Aklivity Community License (the "License"); you may not use
-# this file except in compliance with the License. You may obtain a copy of the
-# License at
-#
-# https://www.aklivity.io/aklivity-community-license/
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OF ANY KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations under the License.
-#
-
----
-name: test
-telemetry:
- exporters:
- stdout0:
- type: stdout
-bindings:
- app0:
- type: tcp
- kind: client
- options:
- host: localhost
- port: 8080
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.yaml b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.yaml
deleted file mode 100644
index fd7e4b90a0..0000000000
--- a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# Copyright 2021-2023 Aklivity Inc
-#
-# Licensed under the Aklivity Community License (the "License"); you may not use
-# this file except in compliance with the License. You may obtain a copy of the
-# License at
-#
-# https://www.aklivity.io/aklivity-community-license/
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OF ANY KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations under the License.
-#
-
----
-name: test
-telemetry:
- exporters:
- stdout0:
- type: stdout
-vaults:
- server:
- type: filesystem
- options:
- keys:
- store: stores/server/keys
- type: pkcs12
- password: generated
-bindings:
- net0:
- type: tls
- kind: server
- vault: server
- options:
- keys:
- - localhost
- exit: app0
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/.gitignore b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/.gitignore
deleted file mode 100644
index 507484f3e9..0000000000
--- a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.crt
-*.csr
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/keys b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/keys
deleted file mode 100644
index d2fa3da9b9..0000000000
Binary files a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/keys and /dev/null differ
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/signers b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/signers
deleted file mode 100644
index 58e72c4460..0000000000
Binary files a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/signers and /dev/null differ
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/trust b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/trust
deleted file mode 100644
index bb624ca8c8..0000000000
Binary files a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/client/trust and /dev/null differ
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/keys b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/keys
deleted file mode 100644
index e10b65832b..0000000000
Binary files a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/keys and /dev/null differ
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/signers b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/signers
deleted file mode 100644
index 0c8e698ab1..0000000000
Binary files a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/signers and /dev/null differ
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/trust b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/trust
deleted file mode 100644
index 377ed0c4c4..0000000000
Binary files a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/stores/server/trust and /dev/null differ
diff --git a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.yaml b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/exporter/stdout/config/server.event.yaml
similarity index 82%
rename from incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.yaml
rename to incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/exporter/stdout/config/server.event.yaml
index effa3e4a6f..58c11c47ea 100644
--- a/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.yaml
+++ b/incubator/exporter-stdout.spec/src/main/scripts/io/aklivity/zilla/specs/exporter/stdout/config/server.event.yaml
@@ -21,13 +21,10 @@ telemetry:
type: stdout
bindings:
net0:
- type: http
+ type: test
kind: server
options:
- versions:
- - h2
- routes:
- - exit: app0
- when:
- - headers:
- :authority: localhost:8080
+ events:
+ - timestamp: 42
+ message: test event message
+ exit: app0
diff --git a/incubator/exporter-stdout/pom.xml b/incubator/exporter-stdout/pom.xml
index 58bf155c90..8d551a92c5 100644
--- a/incubator/exporter-stdout/pom.xml
+++ b/incubator/exporter-stdout/pom.xml
@@ -26,7 +26,7 @@
11
11
- 0.75
+ 0.90
0
@@ -43,48 +43,6 @@
${project.version}
provided
-
- ${project.groupId}
- binding-http.spec
- ${project.version}
- provided
-
-
- ${project.groupId}
- binding-kafka.spec
- ${project.version}
- provided
-
-
- ${project.groupId}
- binding-tcp.spec
- ${project.version}
- provided
-
-
- ${project.groupId}
- binding-tls.spec
- ${project.version}
- provided
-
-
- ${project.groupId}
- catalog-schema-registry.spec
- ${project.version}
- provided
-
-
- ${project.groupId}
- guard-jwt.spec
- ${project.version}
- provided
-
-
- ${project.groupId}
- vault-filesystem.spec
- ${project.version}
- provided
-
${project.groupId}
engine
@@ -92,54 +50,6 @@
${project.version}
test
-
- ${project.groupId}
- binding-http
- ${project.version}
- test
-
-
- ${project.groupId}
- binding-kafka
- ${project.version}
- test
-
-
- ${project.groupId}
- binding-tcp
- ${project.version}
- test
-
-
- ${project.groupId}
- binding-tls
- ${project.version}
- test
-
-
- ${project.groupId}
- catalog-schema-registry
- ${project.version}
- test
-
-
- ${project.groupId}
- guard-jwt
- ${project.version}
- test
-
-
- ${project.groupId}
- model-json
- ${project.version}
- test
-
-
- ${project.groupId}
- vault-filesystem
- ${project.version}
- test
-
junit
junit
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/StdoutExporterContext.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/StdoutExporterContext.java
index bb8d7d3adb..c7cdec617b 100644
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/StdoutExporterContext.java
+++ b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/StdoutExporterContext.java
@@ -22,6 +22,7 @@
import io.aklivity.zilla.runtime.engine.config.AttributeConfig;
import io.aklivity.zilla.runtime.engine.config.ExporterConfig;
import io.aklivity.zilla.runtime.engine.config.KindConfig;
+import io.aklivity.zilla.runtime.engine.event.EventFormatter;
import io.aklivity.zilla.runtime.engine.exporter.ExporterContext;
import io.aklivity.zilla.runtime.engine.exporter.ExporterHandler;
import io.aklivity.zilla.runtime.engine.metrics.Collector;
@@ -63,10 +64,9 @@ public String supplyQName(
return context.supplyQName(namespacedId);
}
- public int supplyTypeId(
- String name)
+ public EventFormatter supplyEventFormatter()
{
- return context.supplyTypeId(name);
+ return context.supplyEventFormatter();
}
public MessageReader supplyEventReader()
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/EventHandler.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/EventHandler.java
deleted file mode 100644
index f8f2a84e8b..0000000000
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/EventHandler.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.exporter.stdout.internal.stream;
-
-import java.io.PrintStream;
-import java.time.Instant;
-import java.time.OffsetDateTime;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-
-import org.agrona.DirectBuffer;
-
-import io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterContext;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.StringFW;
-
-public abstract class EventHandler
-{
- protected static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z");
-
- protected final StdoutExporterContext context;
- protected final PrintStream out;
-
- public EventHandler(
- StdoutExporterContext context,
- PrintStream out)
- {
- this.context = context;
- this.out = out;
- }
-
- public abstract void handleEvent(
- int msgTypeId,
- DirectBuffer buffer,
- int index,
- int length);
-
- protected static String asString(
- StringFW stringFW)
- {
- String s = stringFW.asString();
- return s == null ? "" : s;
- }
-
- protected static String identity(
- StringFW identity)
- {
- int length = identity.length();
- return length <= 0 ? "-" : identity.asString();
- }
-
- protected static String asDateTime(
- long timestamp)
- {
- Instant instant = Instant.ofEpochMilli(timestamp);
- OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(instant, ZoneId.systemDefault());
- return offsetDateTime.format(FORMATTER);
- }
-}
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutEventsStream.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutEventsStream.java
index c6e330f377..1a866e87c2 100644
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutEventsStream.java
+++ b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutEventsStream.java
@@ -15,34 +15,37 @@
package io.aklivity.zilla.runtime.exporter.stdout.internal.stream;
import java.io.PrintStream;
+import java.time.Instant;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
import org.agrona.DirectBuffer;
-import org.agrona.collections.Int2ObjectHashMap;
-import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
import io.aklivity.zilla.runtime.engine.binding.function.MessageReader;
+import io.aklivity.zilla.runtime.engine.event.EventFormatter;
import io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterContext;
+import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.EventFW;
public class StdoutEventsStream
{
+ private static final String FORMAT = "%s [%s] %s%n"; // qname [timestamp] extension\n
+ private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MMM/yyyy:HH:mm:ss Z");
+
+ private final StdoutExporterContext context;
private final MessageReader readEvent;
- private final Int2ObjectHashMap eventHandlers;
+ private final EventFormatter formatter;
+ private final EventFW eventRO = new EventFW();
+ private final PrintStream out;
public StdoutEventsStream(
StdoutExporterContext context,
PrintStream out)
{
+ this.context = context;
this.readEvent = context.supplyEventReader();
-
- final Int2ObjectHashMap eventHandlers = new Int2ObjectHashMap<>();
- eventHandlers.put(context.supplyTypeId("http"), new StdoutHttpHandler(context, out)::handleEvent);
- eventHandlers.put(context.supplyTypeId("jwt"), new StdoutJwtHandler(context, out)::handleEvent);
- eventHandlers.put(context.supplyTypeId("kafka"), new StdoutKafkaHandler(context, out)::handleEvent);
- eventHandlers.put(context.supplyTypeId("schema-registry"),
- new StdoutSchemaRegistryHandler(context, out)::handleEvent);
- eventHandlers.put(context.supplyTypeId("tcp"), new StdoutTcpHandler(context, out)::handleEvent);
- eventHandlers.put(context.supplyTypeId("tls"), new StdoutTlsHandler(context, out)::handleEvent);
- this.eventHandlers = eventHandlers;
+ this.formatter = context.supplyEventFormatter();
+ this.out = out;
}
public int process()
@@ -56,10 +59,17 @@ private void handleEvent(
int index,
int length)
{
- final MessageConsumer handler = eventHandlers.get(msgTypeId);
- if (handler != null)
- {
- handler.accept(msgTypeId, buffer, index, length);
- }
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ String qname = context.supplyQName(event.namespacedId());
+ String extension = formatter.format(msgTypeId, buffer, index, length);
+ out.format(FORMAT, qname, asDateTime(event.timestamp()), extension);
+ }
+
+ private static String asDateTime(
+ long timestamp)
+ {
+ Instant instant = Instant.ofEpochMilli(timestamp);
+ OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(instant, ZoneId.systemDefault());
+ return offsetDateTime.format(FORMATTER);
}
}
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutHttpHandler.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutHttpHandler.java
deleted file mode 100644
index 86dabe799b..0000000000
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutHttpHandler.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.exporter.stdout.internal.stream;
-
-import java.io.PrintStream;
-
-import org.agrona.DirectBuffer;
-
-import io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterContext;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.HttpEventFW;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.HttpRequestAcceptedFW;
-
-public class StdoutHttpHandler extends EventHandler
-{
- private static final String REQUEST_ACCEPTED_FORMAT = "%s %s [%s] REQUEST_ACCEPTED %s %s %s %s%n";
-
- private final HttpEventFW httpEventRO = new HttpEventFW();
-
- public StdoutHttpHandler(
- StdoutExporterContext context,
- PrintStream out)
- {
- super(context, out);
- }
-
- public void handleEvent(
- int msgTypeId,
- DirectBuffer buffer,
- int index,
- int length)
- {
- final HttpEventFW event = httpEventRO.wrap(buffer, index, index + length);
- switch (event.kind())
- {
- case REQUEST_ACCEPTED:
- {
- HttpRequestAcceptedFW e = event.requestAccepted();
- String qname = context.supplyQName(e.namespacedId());
- out.format(REQUEST_ACCEPTED_FORMAT, qname, identity(e.identity()), asDateTime(e.timestamp()), asString(e.scheme()),
- asString(e.method()), asString(e.authority()), asString(e.path()));
- break;
- }
- }
- }
-}
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutJwtHandler.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutJwtHandler.java
deleted file mode 100644
index 7acf1ee0fe..0000000000
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutJwtHandler.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.exporter.stdout.internal.stream;
-
-import java.io.PrintStream;
-
-import org.agrona.DirectBuffer;
-
-import io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterContext;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.JwtAuthorizationFailedFW;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.JwtEventFW;
-
-public class StdoutJwtHandler extends EventHandler
-{
- private static final String AUTHORIZATION_FAILED_FORMAT = "%s %s [%s] AUTHORIZATION_FAILED%n";
-
- private final JwtEventFW jwtEventRO = new JwtEventFW();
-
- public StdoutJwtHandler(
- StdoutExporterContext context,
- PrintStream out)
- {
- super(context, out);
- }
-
- public void handleEvent(
- int msgTypeId,
- DirectBuffer buffer,
- int index,
- int length)
- {
- JwtEventFW event = jwtEventRO.wrap(buffer, index, index + length);
- switch (event.kind())
- {
- case AUTHORIZATION_FAILED:
- JwtAuthorizationFailedFW e = event.authorizationFailed();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(AUTHORIZATION_FAILED_FORMAT, qname, identity(e.identity()), asDateTime(e.timestamp()));
- break;
- }
- }
-}
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutKafkaHandler.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutKafkaHandler.java
deleted file mode 100644
index bae2026051..0000000000
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutKafkaHandler.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.exporter.stdout.internal.stream;
-
-import java.io.PrintStream;
-
-import org.agrona.DirectBuffer;
-
-import io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterContext;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.EventFW;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.KafkaApiVersionRejectedFW;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.KafkaEventFW;
-
-public class StdoutKafkaHandler extends EventHandler
-{
- private static final String AUTHORIZATION_FAILED_FORMAT = "%s - [%s] AUTHORIZATION_FAILED%n";
- private static final String API_VERSION_REJECTED_FORMAT = "%s - [%s] API_VERSION_REJECTED %d %d%n";
-
- private final KafkaEventFW kafkaEventRO = new KafkaEventFW();
-
- public StdoutKafkaHandler(
- StdoutExporterContext context,
- PrintStream out)
- {
- super(context, out);
- }
-
- public void handleEvent(
- int msgTypeId,
- DirectBuffer buffer,
- int index,
- int length)
- {
- final KafkaEventFW event = kafkaEventRO.wrap(buffer, index, index + length);
- switch (event.kind())
- {
- case AUTHORIZATION_FAILED:
- {
- EventFW e = event.authorizationFailed();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(AUTHORIZATION_FAILED_FORMAT, qname, asDateTime(e.timestamp()));
- break;
- }
- case API_VERSION_REJECTED:
- {
- KafkaApiVersionRejectedFW e = event.apiVersionRejected();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(API_VERSION_REJECTED_FORMAT, qname, asDateTime(e.timestamp()), e.apiKey(), e.apiVersion());
- break;
- }
- }
- }
-}
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutSchemaRegistryHandler.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutSchemaRegistryHandler.java
deleted file mode 100644
index 376826b0fd..0000000000
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutSchemaRegistryHandler.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.exporter.stdout.internal.stream;
-
-import java.io.PrintStream;
-
-import org.agrona.DirectBuffer;
-
-import io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterContext;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.SchemaRegistryEventFW;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.SchemaRegistryRemoteAccessRejectedFW;
-
-public class StdoutSchemaRegistryHandler extends EventHandler
-{
- private static final String REMOTE_ACCESS_REJECTED = "%s - [%s] REMOTE_ACCESS_REJECTED %s %s %d%n";
-
- private final SchemaRegistryEventFW schemaRegistryEventRO = new SchemaRegistryEventFW();
-
- public StdoutSchemaRegistryHandler(
- StdoutExporterContext context,
- PrintStream out)
- {
- super(context, out);
- }
-
- public void handleEvent(
- int msgTypeId,
- DirectBuffer buffer,
- int index,
- int length)
- {
- SchemaRegistryEventFW event = schemaRegistryEventRO.wrap(buffer, index, index + length);
- switch (event.kind())
- {
- case REMOTE_ACCESS_REJECTED:
- SchemaRegistryRemoteAccessRejectedFW e = event.remoteAccessRejected();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(REMOTE_ACCESS_REJECTED, qname, asDateTime(e.timestamp()), asString(e.method()), asString(e.url()),
- e.status());
- break;
- }
- }
-}
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutTcpHandler.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutTcpHandler.java
deleted file mode 100644
index 0584a4eddf..0000000000
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutTcpHandler.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.exporter.stdout.internal.stream;
-
-import java.io.PrintStream;
-
-import org.agrona.DirectBuffer;
-
-import io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterContext;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.TcpDnsFailedFW;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.TcpEventFW;
-
-public class StdoutTcpHandler extends EventHandler
-{
- private static final String DNS_FAILED_FORMAT = "%s - [%s] DNS_FAILED %s%n";
-
- private final TcpEventFW tcpEventRO = new TcpEventFW();
-
- public StdoutTcpHandler(
- StdoutExporterContext context,
- PrintStream out)
- {
- super(context, out);
- }
-
- public void handleEvent(
- int msgTypeId,
- DirectBuffer buffer,
- int index,
- int length)
- {
- final TcpEventFW event = tcpEventRO.wrap(buffer, index, index + length);
- switch (event.kind())
- {
- case DNS_FAILED:
- TcpDnsFailedFW e = event.dnsFailed();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(DNS_FAILED_FORMAT, qname, asDateTime(e.timestamp()), asString(e.address()));
- break;
- }
- }
-}
diff --git a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutTlsHandler.java b/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutTlsHandler.java
deleted file mode 100644
index a3ecce6abf..0000000000
--- a/incubator/exporter-stdout/src/main/java/io/aklivity/zilla/runtime/exporter/stdout/internal/stream/StdoutTlsHandler.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.exporter.stdout.internal.stream;
-
-import java.io.PrintStream;
-
-import org.agrona.DirectBuffer;
-
-import io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterContext;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.EventFW;
-import io.aklivity.zilla.runtime.exporter.stdout.internal.types.event.TlsEventFW;
-
-public class StdoutTlsHandler extends EventHandler
-{
- private static final String TLS_FAILED_FORMAT = "%s - [%s] TLS_FAILED%n";
- private static final String PROTOCOL_REJECTED_FORMAT = "%s - [%s] PROTOCOL_REJECTED%n";
- private static final String KEY_REJECTED_FORMAT = "%s - [%s] KEY_REJECTED%n";
- private static final String PEER_NOT_VERIFIED_FORMAT = "%s - [%s] PEER_NOT_VERIFIED%n";
- private static final String HANDSHAKE_FAILED_FORMAT = "%s - [%s] HANDSHAKE_FAILED%n";
-
- private final TlsEventFW tlsEventRO = new TlsEventFW();
-
- public StdoutTlsHandler(
- StdoutExporterContext context,
- PrintStream out)
- {
- super(context, out);
- }
-
- public void handleEvent(
- int msgTypeId,
- DirectBuffer buffer,
- int index,
- int length)
- {
- TlsEventFW event = tlsEventRO.wrap(buffer, index, index + length);
- switch (event.kind())
- {
- case TLS_FAILED:
- {
- EventFW e = event.tlsFailed();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(TLS_FAILED_FORMAT, qname, asDateTime(e.timestamp()));
- break;
- }
- case TLS_PROTOCOL_REJECTED:
- {
- EventFW e = event.tlsProtocolRejected();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(PROTOCOL_REJECTED_FORMAT, qname, asDateTime(e.timestamp()));
- break;
- }
- case TLS_KEY_REJECTED:
- {
- EventFW e = event.tlsKeyRejected();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(KEY_REJECTED_FORMAT, qname, asDateTime(e.timestamp()));
- break;
- }
- case TLS_PEER_NOT_VERIFIED:
- {
- EventFW e = event.tlsPeerNotVerified();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(PEER_NOT_VERIFIED_FORMAT, qname, asDateTime(e.timestamp()));
- break;
- }
- case TLS_HANDSHAKE_FAILED:
- {
- EventFW e = event.tlsHandshakeFailed();
- String qname = context.supplyQName(e.namespacedId());
- out.printf(HANDSHAKE_FAILED_FORMAT, qname, asDateTime(e.timestamp()));
- break;
- }
- }
- }
-}
diff --git a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/StdoutExporterConfigurationTest.java b/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/StdoutExporterConfigurationTest.java
new file mode 100644
index 0000000000..7d2c479f55
--- /dev/null
+++ b/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/StdoutExporterConfigurationTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.runtime.exporter.stdout.internal;
+
+import static io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutConfiguration.STDOUT_OUTPUT;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class StdoutExporterConfigurationTest
+{
+ public static final String STDOUT_OUTPUT_NAME = "zilla.exporter.stdout.output";
+
+ @Test
+ public void shouldVerifyConstants()
+ {
+ assertEquals(STDOUT_OUTPUT.name(), STDOUT_OUTPUT_NAME);
+ }
+}
diff --git a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/JwtEventsIT.java b/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/EventIT.java
similarity index 68%
rename from incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/JwtEventsIT.java
rename to incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/EventIT.java
index 41fa36d119..b31462dda6 100644
--- a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/JwtEventsIT.java
+++ b/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/EventIT.java
@@ -14,7 +14,7 @@
*/
package io.aklivity.zilla.runtime.exporter.stdout.internal.events;
-import static io.aklivity.zilla.runtime.binding.http.internal.HttpConfiguration.HTTP_SERVER_HEADER;
+import static io.aklivity.zilla.runtime.exporter.stdout.internal.StdoutExporterConfigurationTest.STDOUT_OUTPUT_NAME;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.rules.RuleChain.outerRule;
@@ -32,19 +32,18 @@
import io.aklivity.zilla.runtime.engine.test.annotation.Configuration;
import io.aklivity.zilla.runtime.engine.test.annotation.Configure;
-public class JwtEventsIT
+public class EventIT
{
private final K3poRule k3po = new K3poRule()
- .addScriptRoot("net", "io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/authorization")
- .addScriptRoot("app", "io/aklivity/zilla/specs/binding/http/streams/application/rfc7230/authorization");
+ .addScriptRoot("net", "io/aklivity/zilla/specs/engine/streams/network")
+ .addScriptRoot("app", "io/aklivity/zilla/specs/engine/streams/application");
- private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS));
+ private final TestRule timeout = new DisableOnDebug(new Timeout(5, SECONDS));
private final EngineRule engine = new EngineRule()
.directory("target/zilla-itests")
- .countersBufferCapacity(8192)
- .configure(HTTP_SERVER_HEADER, "Zilla")
- .configurationRoot("io/aklivity/zilla/specs/binding/http/config/v1.1")
+ .countersBufferCapacity(4096)
+ .configurationRoot("io/aklivity/zilla/specs/exporter/stdout/config")
.external("app0")
.clean();
@@ -54,15 +53,16 @@ public class JwtEventsIT
public final TestRule chain = outerRule(output).around(engine).around(k3po).around(timeout);
@Test
- @Configuration("server.authorization.credentials.yaml")
+ @Configuration("server.event.yaml")
@Specification({
- "${net}/reject.credentials.header/client",
+ "${net}/event/client",
+ "${app}/event/server"
})
- @Configure(name = "zilla.exporter.stdout.output",
+ @Configure(name = STDOUT_OUTPUT_NAME,
value = "io.aklivity.zilla.runtime.exporter.stdout.internal.events.StdoutOutputRule.OUT")
- public void shouldRejectCredentialsHeader() throws Exception
+ public void shouldLogEvents() throws Exception
{
k3po.finish();
- output.expect(Pattern.compile("test.net0 user \\[[^\\]]+\\] AUTHORIZATION_FAILED\n"));
+ output.expect(Pattern.compile("test.net0 \\[[^\\]]+\\] test event message\n"));
}
}
diff --git a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/TlsEventsIT.java b/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/TlsEventsIT.java
deleted file mode 100644
index cb201e110c..0000000000
--- a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/TlsEventsIT.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.exporter.stdout.internal.events;
-
-import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_DRAIN_ON_CLOSE;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.junit.rules.RuleChain.outerRule;
-
-import java.util.regex.Pattern;
-
-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.zilla.runtime.engine.test.EngineRule;
-import io.aklivity.zilla.runtime.engine.test.annotation.Configuration;
-import io.aklivity.zilla.runtime.engine.test.annotation.Configure;
-
-public class TlsEventsIT
-{
- private final K3poRule k3po = new K3poRule()
- .addScriptRoot("net", "io/aklivity/zilla/specs/binding/tls/streams/network")
- .addScriptRoot("app", "io/aklivity/zilla/specs/binding/tls/streams/application");
-
- private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS));
-
- private final EngineRule engine = new EngineRule()
- .directory("target/zilla-itests")
- .countersBufferCapacity(8192)
- .configurationRoot("io/aklivity/zilla/specs/binding/tls/config")
- .external("app0")
- .configure(ENGINE_DRAIN_ON_CLOSE, false)
- .clean();
-
- private final StdoutOutputRule output = new StdoutOutputRule();
-
- @Rule
- public final TestRule chain = outerRule(output).around(engine).around(k3po).around(timeout);
-
- @Test
- @Configuration("server.yaml")
- @Specification({
- "${net}/client.hello.malformed/client"})
- @Configure(name = "zilla.exporter.stdout.output",
- value = "io.aklivity.zilla.runtime.exporter.stdout.internal.events.StdoutOutputRule.OUT")
- public void shouldResetMalformedClientHello() throws Exception
- {
- k3po.finish();
- output.expect(Pattern.compile("test.net0 - \\[[^\\]]+\\] TLS_FAILED\n"));
- }
-
- @Test
- @Configuration("server.yaml")
- @Specification({
- "${net}/server.handshake.timeout/client"})
- @Configure(name = "zilla.binding.tls.handshake.timeout", value = "1")
- @Configure(name = "zilla.exporter.stdout.output",
- value = "io.aklivity.zilla.runtime.exporter.stdout.internal.events.StdoutOutputRule.OUT")
- public void shouldTimeoutHandshake() throws Exception
- {
- k3po.finish();
- output.expect(Pattern.compile("test.net0 - \\[[^\\]]+\\] HANDSHAKE_FAILED\n"));
- }
-}
diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventContext.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventContext.java
index f4c0ee0fc1..0b81d70e4b 100644
--- a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventContext.java
+++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventContext.java
@@ -15,6 +15,8 @@
*/
package io.aklivity.zilla.runtime.binding.http.internal;
+import static io.aklivity.zilla.runtime.binding.http.internal.types.event.HttpEventType.REQUEST_ACCEPTED;
+
import java.nio.ByteBuffer;
import java.time.Clock;
import java.util.Map;
@@ -25,7 +27,8 @@
import io.aklivity.zilla.runtime.binding.http.internal.types.Array32FW;
import io.aklivity.zilla.runtime.binding.http.internal.types.HttpHeaderFW;
import io.aklivity.zilla.runtime.binding.http.internal.types.String8FW;
-import io.aklivity.zilla.runtime.binding.http.internal.types.event.HttpEventFW;
+import io.aklivity.zilla.runtime.binding.http.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.binding.http.internal.types.event.HttpEventExFW;
import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
import io.aklivity.zilla.runtime.engine.guard.GuardHandler;
@@ -39,7 +42,9 @@ public class HttpEventContext
private static final String8FW HEADER_PATH = new String8FW(":path");
private final AtomicBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
- private final HttpEventFW.Builder httpEventRW = new HttpEventFW.Builder();
+ private final AtomicBuffer extensionBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final EventFW.Builder eventRW = new EventFW.Builder();
+ private final HttpEventExFW.Builder httpEventExRW = new HttpEventExFW.Builder();
private final int httpTypeId;
private final MessageConsumer eventWriter;
private final Clock clock;
@@ -60,12 +65,10 @@ public void requestAccepted(
Map headers)
{
String identity = guard == null ? null : guard.identity(authorization);
- HttpEventFW event = httpEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ HttpEventExFW extension = httpEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.requestAccepted(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(REQUEST_ACCEPTED.value())
.identity(identity)
.scheme(headers.get(":scheme"))
.method(headers.get(":method"))
@@ -73,6 +76,13 @@ public void requestAccepted(
.path(headers.get(":path"))
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(httpTypeId, event.buffer(), event.offset(), event.limit());
}
@@ -84,12 +94,10 @@ public void requestAccepted(
Array32FW headers)
{
String identity = guard == null ? null : guard.identity(authorization);
- HttpEventFW event = httpEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ HttpEventExFW extension = httpEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.requestAccepted(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(REQUEST_ACCEPTED.value())
.identity(identity)
.scheme(headers.matchFirst(h -> HEADER_SCHEME.equals(h.name())).value().asString())
.method(headers.matchFirst(h -> HEADER_METHOD.equals(h.name())).value().asString())
@@ -97,6 +105,13 @@ public void requestAccepted(
.path(headers.matchFirst(h -> HEADER_PATH.equals(h.name())).value().asString())
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(httpTypeId, event.buffer(), event.offset(), event.limit());
}
}
diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventFormatter.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventFormatter.java
new file mode 100644
index 0000000000..221b3097a8
--- /dev/null
+++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventFormatter.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.binding.http.internal;
+
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.binding.http.internal.types.StringFW;
+import io.aklivity.zilla.runtime.binding.http.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.binding.http.internal.types.event.HttpEventExFW;
+import io.aklivity.zilla.runtime.binding.http.internal.types.event.HttpRequestAcceptedExFW;
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;
+
+public final class HttpEventFormatter implements EventFormatterSpi
+{
+ private static final String REQUEST_ACCEPTED_FORMAT = "REQUEST_ACCEPTED %s %s %s %s %s";
+
+ private final EventFW eventRO = new EventFW();
+ private final HttpEventExFW httpEventExRO = new HttpEventExFW();
+
+ HttpEventFormatter(
+ Configuration config)
+ {
+ }
+
+ public String format(
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ final HttpEventExFW extension = httpEventExRO
+ .wrap(event.extension().buffer(), event.extension().offset(), event.extension().limit());
+ String result = null;
+ switch (extension.kind())
+ {
+ case REQUEST_ACCEPTED:
+ {
+ HttpRequestAcceptedExFW ex = extension.requestAccepted();
+ result = String.format(REQUEST_ACCEPTED_FORMAT, identity(ex.identity()), asString(ex.scheme()), asString(ex.method()),
+ asString(ex.authority()), asString(ex.path()));
+ break;
+ }
+ }
+ return result;
+ }
+
+ private static String asString(
+ StringFW stringFW)
+ {
+ String s = stringFW.asString();
+ return s == null ? "" : s;
+ }
+
+ private static String identity(
+ StringFW identity)
+ {
+ int length = identity.length();
+ return length <= 0 ? "-" : identity.asString();
+ }
+}
diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventFormatterFactory.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventFormatterFactory.java
new file mode 100644
index 0000000000..d50404473d
--- /dev/null
+++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/HttpEventFormatterFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.binding.http.internal;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
+
+public final class HttpEventFormatterFactory implements EventFormatterFactorySpi
+{
+ @Override
+ public HttpEventFormatter create(
+ Configuration config)
+ {
+ return new HttpEventFormatter(config);
+ }
+
+ @Override
+ public String type()
+ {
+ return HttpBinding.NAME;
+ }
+}
diff --git a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/stream/HttpServerFactory.java b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/stream/HttpServerFactory.java
index 7b6a5fc925..69bd7f202c 100644
--- a/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/stream/HttpServerFactory.java
+++ b/runtime/binding-http/src/main/java/io/aklivity/zilla/runtime/binding/http/internal/stream/HttpServerFactory.java
@@ -2271,7 +2271,7 @@ private boolean onDecodeHeaders(
final HttpHeaderFW connection = beginEx.headers().matchFirst(h -> HEADER_CONNECTION.equals(h.name()));
exchange.responseClosing = connection != null && connectionClose.reset(connection.value().asString()).matches();
- event.requestAccepted(traceId, routedId, guard, authorization, beginEx.headers());
+ event.requestAccepted(traceId, originId, guard, authorization, beginEx.headers());
this.exchange = exchange;
}
return headersValid;
diff --git a/runtime/binding-http/src/main/moditect/module-info.java b/runtime/binding-http/src/main/moditect/module-info.java
index 6f1b960854..b837b223eb 100644
--- a/runtime/binding-http/src/main/moditect/module-info.java
+++ b/runtime/binding-http/src/main/moditect/module-info.java
@@ -27,4 +27,7 @@
provides io.aklivity.zilla.runtime.engine.config.ConditionConfigAdapterSpi
with io.aklivity.zilla.runtime.binding.http.internal.config.HttpConditionConfigAdapter;
+
+ provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
+ with io.aklivity.zilla.runtime.binding.http.internal.HttpEventFormatterFactory;
}
diff --git a/runtime/binding-http/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi b/runtime/binding-http/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
new file mode 100644
index 0000000000..1365f0fabe
--- /dev/null
+++ b/runtime/binding-http/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.binding.http.internal.HttpEventFormatterFactory
diff --git a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/Http11EventsIT.java b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7230/server/EventIT.java
similarity index 60%
rename from incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/Http11EventsIT.java
rename to runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7230/server/EventIT.java
index c942d6e141..06e97df87b 100644
--- a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/Http11EventsIT.java
+++ b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7230/server/EventIT.java
@@ -1,25 +1,25 @@
/*
- * Copyright 2021-2023 Aklivity Inc
+ * 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
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
*
- * https://www.aklivity.io/aklivity-community-license/
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*/
-package io.aklivity.zilla.runtime.exporter.stdout.internal.events;
+package io.aklivity.zilla.runtime.binding.http.internal.streams.rfc7230.server;
import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_BUFFER_SLOT_CAPACITY;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.rules.RuleChain.outerRule;
-import java.util.regex.Pattern;
-
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
@@ -30,9 +30,8 @@
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;
-public class Http11EventsIT
+public class EventIT
{
private final K3poRule k3po = new K3poRule()
.addScriptRoot("net", "io/aklivity/zilla/specs/binding/http/streams/network/rfc7230/message.format")
@@ -48,21 +47,17 @@ public class Http11EventsIT
.external("app0")
.clean();
- private final StdoutOutputRule output = new StdoutOutputRule();
-
@Rule
- public final TestRule chain = outerRule(output).around(engine).around(k3po).around(timeout);
+ public final TestRule chain = outerRule(engine).around(k3po).around(timeout);
@Test
- @Configuration("server.yaml")
+ @Ignore
+ @Configuration("server.event.yaml")
@Specification({
"${net}/request.with.headers/client",
"${app}/request.with.headers/server" })
- @Configure(name = "zilla.exporter.stdout.output",
- value = "io.aklivity.zilla.runtime.exporter.stdout.internal.events.StdoutOutputRule.OUT")
public void requestWithHeaders() throws Exception
{
k3po.finish();
- output.expect(Pattern.compile("test.app0 - \\[[^\\]]+\\] REQUEST_ACCEPTED http GET localhost:8080 /\n"));
}
}
diff --git a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/Http2EventsIT.java b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/EventIT.java
similarity index 60%
rename from incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/Http2EventsIT.java
rename to runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/EventIT.java
index e858786c85..8bf5686dbf 100644
--- a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/Http2EventsIT.java
+++ b/runtime/binding-http/src/test/java/io/aklivity/zilla/runtime/binding/http/internal/streams/rfc7540/server/EventIT.java
@@ -1,25 +1,25 @@
/*
- * Copyright 2021-2023 Aklivity Inc
+ * 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
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
*
- * https://www.aklivity.io/aklivity-community-license/
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*/
-package io.aklivity.zilla.runtime.exporter.stdout.internal.events;
+package io.aklivity.zilla.runtime.binding.http.internal.streams.rfc7540.server;
import static io.aklivity.zilla.runtime.binding.http.internal.HttpConfiguration.HTTP_CONCURRENT_STREAMS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.rules.RuleChain.outerRule;
-import java.util.regex.Pattern;
-
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
@@ -30,9 +30,8 @@
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;
-public class Http2EventsIT
+public class EventIT
{
private final K3poRule k3po = new K3poRule()
.addScriptRoot("net", "io/aklivity/zilla/specs/binding/http/streams/network/rfc7540/message.format")
@@ -48,21 +47,17 @@ public class Http2EventsIT
.external("app0")
.clean();
- private final StdoutOutputRule output = new StdoutOutputRule();
-
@Rule
- public final TestRule chain = outerRule(output).around(engine).around(k3po).around(timeout);
+ public final TestRule chain = outerRule(engine).around(k3po).around(timeout);
@Test
- @Configuration("server.yaml")
+ @Ignore
+ @Configuration("server.event.yaml")
@Specification({
"${net}/connection.headers/client",
"${app}/connection.headers/server" })
- @Configure(name = "zilla.exporter.stdout.output",
- value = "io.aklivity.zilla.runtime.exporter.stdout.internal.events.StdoutOutputRule.OUT")
public void connectionHeaders() throws Exception
{
k3po.finish();
- output.expect(Pattern.compile("test.net0 - \\[[^\\]]+\\] REQUEST_ACCEPTED http GET localhost:8080 /\n"));
}
}
diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventContext.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventContext.java
index 86e8bc3168..587280caae 100644
--- a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventContext.java
+++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventContext.java
@@ -15,23 +15,28 @@
*/
package io.aklivity.zilla.runtime.binding.kafka.internal;
+import static io.aklivity.zilla.runtime.binding.kafka.internal.types.event.KafkaEventType.API_VERSION_REJECTED;
+import static io.aklivity.zilla.runtime.binding.kafka.internal.types.event.KafkaEventType.AUTHORIZATION_FAILED;
+
import java.nio.ByteBuffer;
import java.time.Clock;
-import org.agrona.MutableDirectBuffer;
+import org.agrona.concurrent.AtomicBuffer;
import org.agrona.concurrent.UnsafeBuffer;
-import io.aklivity.zilla.runtime.binding.kafka.internal.types.event.KafkaEventFW;
+import io.aklivity.zilla.runtime.binding.kafka.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.binding.kafka.internal.types.event.KafkaEventExFW;
import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
public class KafkaEventContext
{
private static final int EVENT_BUFFER_CAPACITY = 1024;
- private static final int ERROR_NONE = 0;
- private final KafkaEventFW.Builder kafkaEventRW = new KafkaEventFW.Builder();
- private final MutableDirectBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer extensionBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final EventFW.Builder eventRW = new EventFW.Builder();
+ private final KafkaEventExFW.Builder kafkaEventExRW = new KafkaEventExFW.Builder();
private final int kafkaTypeId;
private final MessageConsumer eventWriter;
private final Clock clock;
@@ -46,16 +51,23 @@ public KafkaEventContext(
public void authorizationFailed(
long traceId,
- long bindingId)
+ long bindingId,
+ String identity)
{
- KafkaEventFW event = kafkaEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ KafkaEventExFW extension = kafkaEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.authorizationFailed(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(AUTHORIZATION_FAILED.value())
+ .identity(identity)
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(kafkaTypeId, event.buffer(), event.offset(), event.limit());
}
@@ -65,16 +77,21 @@ public void apiVersionRejected(
int apiKey,
int apiVersion)
{
- KafkaEventFW event = kafkaEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ KafkaEventExFW extension = kafkaEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.apiVersionRejected(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(API_VERSION_REJECTED.value())
.apiKey(apiKey)
.apiVersion(apiVersion)
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(kafkaTypeId, event.buffer(), event.offset(), event.limit());
}
}
diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventFormatter.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventFormatter.java
new file mode 100644
index 0000000000..515aa6f08e
--- /dev/null
+++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventFormatter.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.binding.kafka.internal;
+
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.binding.kafka.internal.types.StringFW;
+import io.aklivity.zilla.runtime.binding.kafka.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.binding.kafka.internal.types.event.KafkaApiVersionRejectedExFW;
+import io.aklivity.zilla.runtime.binding.kafka.internal.types.event.KafkaAuthorizationFailedExFW;
+import io.aklivity.zilla.runtime.binding.kafka.internal.types.event.KafkaEventExFW;
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;
+
+public final class KafkaEventFormatter implements EventFormatterSpi
+{
+ private static final String AUTHORIZATION_FAILED_FORMAT = "AUTHORIZATION_FAILED %s";
+ private static final String API_VERSION_REJECTED_FORMAT = "API_VERSION_REJECTED %d %d";
+
+ private final EventFW eventRO = new EventFW();
+ private final KafkaEventExFW kafkaEventExRO = new KafkaEventExFW();
+
+ KafkaEventFormatter(
+ Configuration config)
+ {
+ }
+
+ public String format(
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ final KafkaEventExFW extension = kafkaEventExRO
+ .wrap(event.extension().buffer(), event.extension().offset(), event.extension().limit());
+ String result = null;
+ switch (extension.kind())
+ {
+ case AUTHORIZATION_FAILED:
+ {
+ KafkaAuthorizationFailedExFW ex = extension.authorizationFailed();
+ result = String.format(AUTHORIZATION_FAILED_FORMAT, identity(ex.identity()));
+ break;
+ }
+ case API_VERSION_REJECTED:
+ {
+ final KafkaApiVersionRejectedExFW ex = extension.apiVersionRejected();
+ result = String.format(API_VERSION_REJECTED_FORMAT, ex.apiKey(), ex.apiVersion());
+ }
+ }
+ return result;
+ }
+
+ private static String identity(
+ StringFW identity)
+ {
+ int length = identity.length();
+ return length <= 0 ? "-" : identity.asString();
+ }
+}
diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventFormatterFactory.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventFormatterFactory.java
new file mode 100644
index 0000000000..f522ba7851
--- /dev/null
+++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaEventFormatterFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.binding.kafka.internal;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
+
+public final class KafkaEventFormatterFactory implements EventFormatterFactorySpi
+{
+ @Override
+ public KafkaEventFormatter create(
+ Configuration config)
+ {
+ return new KafkaEventFormatter(config);
+ }
+
+ @Override
+ public String type()
+ {
+ return KafkaBinding.NAME;
+ }
+}
diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientSaslHandshaker.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientSaslHandshaker.java
index ca61063380..2e3ed716a4 100644
--- a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientSaslHandshaker.java
+++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/KafkaClientSaslHandshaker.java
@@ -708,7 +708,7 @@ private int decodeSaslPlainAuthenticate(
final int errorCode = authenticateResponse.errorCode();
if (errorCode != ERROR_NONE)
{
- event.authorizationFailed(traceId, client.originId);
+ event.authorizationFailed(traceId, client.originId, client.sasl.username);
}
progress = authenticateResponse.limit();
@@ -746,7 +746,7 @@ private int decodeSaslScramAuthenticateFirst(
final int errorCode = authenticateResponse.errorCode();
if (errorCode != ERROR_NONE)
{
- event.authorizationFailed(traceId, client.originId);
+ event.authorizationFailed(traceId, client.originId, client.sasl.username);
}
progress = authenticateResponse.limit();
diff --git a/runtime/binding-kafka/src/main/moditect/module-info.java b/runtime/binding-kafka/src/main/moditect/module-info.java
index b15ffc4089..1191e87119 100644
--- a/runtime/binding-kafka/src/main/moditect/module-info.java
+++ b/runtime/binding-kafka/src/main/moditect/module-info.java
@@ -34,4 +34,7 @@
provides io.aklivity.zilla.runtime.binding.kafka.identity.KafkaClientIdSupplierFactorySpi
with io.aklivity.zilla.runtime.binding.kafka.internal.identity.KafkaConfluentClientIdSupplierFactory;
+
+ provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
+ with io.aklivity.zilla.runtime.binding.kafka.internal.KafkaEventFormatterFactory;
}
diff --git a/runtime/binding-kafka/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi b/runtime/binding-kafka/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
new file mode 100644
index 0000000000..6659873202
--- /dev/null
+++ b/runtime/binding-kafka/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.binding.kafka.internal.KafkaEventFormatterFactory
diff --git a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/KafkaEventsIT.java b/runtime/binding-kafka/src/test/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/EventIT.java
similarity index 58%
rename from incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/KafkaEventsIT.java
rename to runtime/binding-kafka/src/test/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/EventIT.java
index e1e8c9fda7..e62066ce95 100644
--- a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/KafkaEventsIT.java
+++ b/runtime/binding-kafka/src/test/java/io/aklivity/zilla/runtime/binding/kafka/internal/stream/EventIT.java
@@ -1,24 +1,23 @@
/*
- * Copyright 2021-2023 Aklivity Inc
+ * 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
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
*
- * https://www.aklivity.io/aklivity-community-license/
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*/
-package io.aklivity.zilla.runtime.exporter.stdout.internal.events;
+package io.aklivity.zilla.runtime.binding.kafka.internal.stream;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.rules.RuleChain.outerRule;
-import java.util.regex.Pattern;
-
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
@@ -29,9 +28,8 @@
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;
-public class KafkaEventsIT
+public class EventIT
{
private final K3poRule k3po = new K3poRule()
.addScriptRoot("net", "io/aklivity/zilla/specs/binding/kafka/streams/network/group.f1.j5.s3.l3.h3")
@@ -43,27 +41,22 @@ public class KafkaEventsIT
.directory("target/zilla-itests")
.countersBufferCapacity(8192)
.configure("zilla.binding.kafka.client.instance.id",
- "io.aklivity.zilla.runtime.exporter.stdout.internal.events.KafkaEventsIT::supplyInstanceId")
+ "io.aklivity.zilla.runtime.binding.kafka.internal.stream.EventIT::supplyInstanceId")
.configurationRoot("io/aklivity/zilla/specs/binding/kafka/config")
.external("net0")
.clean();
- private final StdoutOutputRule output = new StdoutOutputRule();
-
@Rule
- public final TestRule chain = outerRule(output).around(engine).around(k3po).around(timeout);
+ public final TestRule chain = outerRule(engine).around(k3po).around(timeout);
@Test
- @Configuration("client.yaml")
+ @Configuration("client.event.yaml")
@Specification({
"${app}/invalid.describe.config/client",
"${net}/invalid.describe.config/server"})
- @Configure(name = "zilla.exporter.stdout.output",
- value = "io.aklivity.zilla.runtime.exporter.stdout.internal.events.StdoutOutputRule.OUT")
public void shouldHandleInvalidDescribeConfig() throws Exception
{
k3po.finish();
- output.expect(Pattern.compile("test.app0 - \\[[^\\]]+\\] API_VERSION_REJECTED 32 0\n"));
}
public static String supplyInstanceId()
diff --git a/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventContext.java b/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventContext.java
index 7159725444..981c7bf6e3 100644
--- a/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventContext.java
+++ b/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventContext.java
@@ -15,13 +15,16 @@
*/
package io.aklivity.zilla.runtime.binding.tcp.internal;
+import static io.aklivity.zilla.runtime.binding.tcp.internal.types.event.TcpEventType.DNS_FAILED;
+
import java.nio.ByteBuffer;
import java.time.Clock;
-import org.agrona.MutableDirectBuffer;
+import org.agrona.concurrent.AtomicBuffer;
import org.agrona.concurrent.UnsafeBuffer;
-import io.aklivity.zilla.runtime.binding.tcp.internal.types.event.TcpEventFW;
+import io.aklivity.zilla.runtime.binding.tcp.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.binding.tcp.internal.types.event.TcpEventExFW;
import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
@@ -29,8 +32,11 @@ public class TcpEventContext
{
private static final int EVENT_BUFFER_CAPACITY = 1024;
- private final TcpEventFW.Builder tcpEventRW = new TcpEventFW.Builder();
- private final MutableDirectBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer extensionBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final EventFW.Builder eventRW = new EventFW.Builder();
+ private final TcpEventExFW.Builder tcpEventExRW = new TcpEventExFW.Builder();
+
private final int tcpTypeId;
private final MessageConsumer eventWriter;
private final Clock clock;
@@ -48,15 +54,20 @@ public void dnsResolutionFailed(
long bindingId,
String address)
{
- TcpEventFW event = tcpEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ TcpEventExFW extension = tcpEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.dnsFailed(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(DNS_FAILED.value())
.address(address)
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(tcpTypeId, event.buffer(), event.offset(), event.limit());
}
}
diff --git a/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventFormatter.java b/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventFormatter.java
new file mode 100644
index 0000000000..5fd1716db2
--- /dev/null
+++ b/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventFormatter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.binding.tcp.internal;
+
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.binding.tcp.internal.types.StringFW;
+import io.aklivity.zilla.runtime.binding.tcp.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.binding.tcp.internal.types.event.TcpDnsFailedExFW;
+import io.aklivity.zilla.runtime.binding.tcp.internal.types.event.TcpEventExFW;
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;
+
+public final class TcpEventFormatter implements EventFormatterSpi
+{
+ private static final String DNS_FAILED_FORMAT = "DNS_FAILED %s";
+
+ private final EventFW eventRO = new EventFW();
+ private final TcpEventExFW tcpEventExRO = new TcpEventExFW();
+
+ TcpEventFormatter(
+ Configuration config)
+ {
+ }
+
+ public String format(
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ final TcpEventExFW extension = tcpEventExRO
+ .wrap(event.extension().buffer(), event.extension().offset(), event.extension().limit());
+ String result = null;
+ switch (extension.kind())
+ {
+ case DNS_FAILED:
+ {
+ final TcpDnsFailedExFW ex = extension.dnsFailed();
+ result = String.format(DNS_FAILED_FORMAT, asString(ex.address()));
+ break;
+ }
+ }
+ return result;
+ }
+
+ private static String asString(
+ StringFW stringFW)
+ {
+ String s = stringFW.asString();
+ return s == null ? "" : s;
+ }
+}
diff --git a/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventFormatterFactory.java b/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventFormatterFactory.java
new file mode 100644
index 0000000000..71ab9c3c70
--- /dev/null
+++ b/runtime/binding-tcp/src/main/java/io/aklivity/zilla/runtime/binding/tcp/internal/TcpEventFormatterFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.binding.tcp.internal;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
+
+public final class TcpEventFormatterFactory implements EventFormatterFactorySpi
+{
+ @Override
+ public TcpEventFormatter create(
+ Configuration config)
+ {
+ return new TcpEventFormatter(config);
+ }
+
+ @Override
+ public String type()
+ {
+ return TcpBinding.NAME;
+ }
+}
diff --git a/runtime/binding-tcp/src/main/moditect/module-info.java b/runtime/binding-tcp/src/main/moditect/module-info.java
index 103492b28c..8f1a1dcd4b 100644
--- a/runtime/binding-tcp/src/main/moditect/module-info.java
+++ b/runtime/binding-tcp/src/main/moditect/module-info.java
@@ -27,4 +27,7 @@
provides io.aklivity.zilla.runtime.engine.config.ConditionConfigAdapterSpi
with io.aklivity.zilla.runtime.binding.tcp.internal.config.TcpConditionConfigAdapter;
+
+ provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
+ with io.aklivity.zilla.runtime.binding.tcp.internal.TcpEventFormatterFactory;
}
diff --git a/runtime/binding-tcp/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi b/runtime/binding-tcp/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
new file mode 100644
index 0000000000..11c94b1f1a
--- /dev/null
+++ b/runtime/binding-tcp/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.binding.tcp.internal.TcpEventFormatterFactory
diff --git a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/TcpEventsIT.java b/runtime/binding-tcp/src/test/java/io/aklivity/zilla/runtime/binding/tcp/internal/streams/EventIT.java
similarity index 60%
rename from incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/TcpEventsIT.java
rename to runtime/binding-tcp/src/test/java/io/aklivity/zilla/runtime/binding/tcp/internal/streams/EventIT.java
index 989f89eb83..95917fb03a 100644
--- a/incubator/exporter-stdout/src/test/java/io/aklivity/zilla/runtime/exporter/stdout/internal/events/TcpEventsIT.java
+++ b/runtime/binding-tcp/src/test/java/io/aklivity/zilla/runtime/binding/tcp/internal/streams/EventIT.java
@@ -1,25 +1,25 @@
/*
- * Copyright 2021-2023 Aklivity Inc
+ * 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
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
*
- * https://www.aklivity.io/aklivity-community-license/
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*/
-package io.aklivity.zilla.runtime.exporter.stdout.internal.events;
+package io.aklivity.zilla.runtime.binding.tcp.internal.streams;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.rules.RuleChain.outerRule;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.regex.Pattern;
import org.junit.Rule;
import org.junit.Test;
@@ -33,7 +33,7 @@
import io.aklivity.zilla.runtime.engine.test.annotation.Configuration;
import io.aklivity.zilla.runtime.engine.test.annotation.Configure;
-public class TcpEventsIT
+public class EventIT
{
private final K3poRule k3po = new K3poRule()
.addScriptRoot("net", "io/aklivity/zilla/specs/binding/tcp/streams/network/rfc793")
@@ -47,24 +47,19 @@ public class TcpEventsIT
.configurationRoot("io/aklivity/zilla/specs/binding/tcp/config")
.clean();
- private final StdoutOutputRule output = new StdoutOutputRule();
-
@Rule
- public final TestRule chain = outerRule(output).around(engine).around(k3po).around(timeout);
+ public final TestRule chain = outerRule(engine).around(k3po).around(timeout);
@Test
- @Configuration("client.host.yaml")
+ @Configuration("client.event.yaml")
@Specification({
"${app}/connection.failed/client"
})
- @Configure(name = "zilla.exporter.stdout.output",
- value = "io.aklivity.zilla.runtime.exporter.stdout.internal.events.StdoutOutputRule.OUT")
@Configure(name = "zilla.engine.host.resolver",
- value = "io.aklivity.zilla.runtime.exporter.stdout.internal.events.TcpEventsIT::resolveHost")
+ value = "io.aklivity.zilla.runtime.binding.tcp.internal.streams.EventIT::resolveHost")
public void dnsResolutionFailed() throws Exception
{
k3po.finish();
- output.expect(Pattern.compile("test.app0 - \\[[^\\]]+\\] DNS_FAILED localhost\n"));
}
public static InetAddress[] resolveHost(
diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventContext.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventContext.java
index 22722224ea..ec7c2aa090 100644
--- a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventContext.java
+++ b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventContext.java
@@ -15,13 +15,20 @@
*/
package io.aklivity.zilla.runtime.binding.tls.internal;
+import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_FAILED;
+import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_HANDSHAKE_FAILED;
+import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_KEY_REJECTED;
+import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_PEER_NOT_VERIFIED;
+import static io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventType.TLS_PROTOCOL_REJECTED;
+
import java.nio.ByteBuffer;
import java.time.Clock;
-import org.agrona.MutableDirectBuffer;
+import org.agrona.concurrent.AtomicBuffer;
import org.agrona.concurrent.UnsafeBuffer;
-import io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventFW;
+import io.aklivity.zilla.runtime.binding.tls.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventExFW;
import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
@@ -29,8 +36,10 @@ public class TlsEventContext
{
private static final int EVENT_BUFFER_CAPACITY = 1024;
- private final TlsEventFW.Builder tlsEventRW = new TlsEventFW.Builder();
- private final MutableDirectBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer extensionBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final EventFW.Builder eventRW = new EventFW.Builder();
+ private final TlsEventExFW.Builder tlsEventExRW = new TlsEventExFW.Builder();
private final int tlsTypeId;
private final MessageConsumer eventWriter;
private final Clock clock;
@@ -47,14 +56,19 @@ public void tlsFailed(
long traceId,
long bindingId)
{
- TlsEventFW event = tlsEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ TlsEventExFW extension = tlsEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.tlsFailed(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(TLS_FAILED.value())
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(tlsTypeId, event.buffer(), event.offset(), event.limit());
}
@@ -62,14 +76,19 @@ public void tlsProtocolRejected(
long traceId,
long bindingId)
{
- TlsEventFW event = tlsEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ TlsEventExFW extension = tlsEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.tlsProtocolRejected(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(TLS_PROTOCOL_REJECTED.value())
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(tlsTypeId, event.buffer(), event.offset(), event.limit());
}
@@ -77,14 +96,19 @@ public void tlsKeyRejected(
long traceId,
long bindingId)
{
- TlsEventFW event = tlsEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ TlsEventExFW extension = tlsEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.tlsKeyRejected(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(TLS_KEY_REJECTED.value())
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(tlsTypeId, event.buffer(), event.offset(), event.limit());
}
@@ -92,14 +116,19 @@ public void tlsPeerNotVerified(
long traceId,
long bindingId)
{
- TlsEventFW event = tlsEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ TlsEventExFW extension = tlsEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.tlsPeerNotVerified(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(TLS_PEER_NOT_VERIFIED.value())
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(tlsTypeId, event.buffer(), event.offset(), event.limit());
}
@@ -107,14 +136,19 @@ public void tlsHandshakeFailed(
long traceId,
long bindingId)
{
- TlsEventFW event = tlsEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ TlsEventExFW extension = tlsEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.tlsHandshakeFailed(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(TLS_HANDSHAKE_FAILED.value())
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(tlsTypeId, event.buffer(), event.offset(), event.limit());
}
}
diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatter.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatter.java
new file mode 100644
index 0000000000..49a03c9cb5
--- /dev/null
+++ b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatter.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.binding.tls.internal;
+
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.binding.tls.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.binding.tls.internal.types.event.TlsEventExFW;
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;
+
+public final class TlsEventFormatter implements EventFormatterSpi
+{
+ private static final String TLS_FAILED_FORMAT = "TLS_FAILED";
+ private static final String PROTOCOL_REJECTED_FORMAT = "PROTOCOL_REJECTED";
+ private static final String KEY_REJECTED_FORMAT = "KEY_REJECTED";
+ private static final String PEER_NOT_VERIFIED_FORMAT = "PEER_NOT_VERIFIED";
+ private static final String HANDSHAKE_FAILED_FORMAT = "HANDSHAKE_FAILED";
+
+ private final EventFW eventRO = new EventFW();
+ private final TlsEventExFW tlsEventExRO = new TlsEventExFW();
+
+ TlsEventFormatter(
+ Configuration config)
+ {
+ }
+
+ public String format(
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ final TlsEventExFW extension = tlsEventExRO
+ .wrap(event.extension().buffer(), event.extension().offset(), event.extension().limit());
+ String result = null;
+ switch (extension.kind())
+ {
+ case TLS_FAILED:
+ {
+ result = TLS_FAILED_FORMAT;
+ break;
+ }
+ case TLS_PROTOCOL_REJECTED:
+ {
+ result = PROTOCOL_REJECTED_FORMAT;
+ break;
+ }
+ case TLS_KEY_REJECTED:
+ {
+ result = KEY_REJECTED_FORMAT;
+ break;
+ }
+ case TLS_PEER_NOT_VERIFIED:
+ {
+ result = PEER_NOT_VERIFIED_FORMAT;
+ break;
+ }
+ case TLS_HANDSHAKE_FAILED:
+ {
+ result = HANDSHAKE_FAILED_FORMAT;
+ break;
+ }
+ }
+ return result;
+ }
+}
diff --git a/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatterFactory.java b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatterFactory.java
new file mode 100644
index 0000000000..bd6a8996a2
--- /dev/null
+++ b/runtime/binding-tls/src/main/java/io/aklivity/zilla/runtime/binding/tls/internal/TlsEventFormatterFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.binding.tls.internal;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
+
+public final class TlsEventFormatterFactory implements EventFormatterFactorySpi
+{
+ @Override
+ public TlsEventFormatter create(
+ Configuration config)
+ {
+ return new TlsEventFormatter(config);
+ }
+
+ @Override
+ public String type()
+ {
+ return TlsBinding.NAME;
+ }
+}
diff --git a/runtime/binding-tls/src/main/moditect/module-info.java b/runtime/binding-tls/src/main/moditect/module-info.java
index 194599b35c..d63aacfe37 100644
--- a/runtime/binding-tls/src/main/moditect/module-info.java
+++ b/runtime/binding-tls/src/main/moditect/module-info.java
@@ -29,4 +29,7 @@
provides io.aklivity.zilla.runtime.engine.config.ConditionConfigAdapterSpi
with io.aklivity.zilla.runtime.binding.tls.internal.config.TlsConditionConfigAdapter;
+
+ provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
+ with io.aklivity.zilla.runtime.binding.tls.internal.TlsEventFormatterFactory;
}
diff --git a/runtime/binding-tls/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi b/runtime/binding-tls/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
new file mode 100644
index 0000000000..24e5306dcf
--- /dev/null
+++ b/runtime/binding-tls/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.binding.tls.internal.TlsEventFormatterFactory
diff --git a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ClientIT.java b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ClientIT.java
index 3273970d18..5014f76995 100644
--- a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ClientIT.java
+++ b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ClientIT.java
@@ -377,4 +377,15 @@ public void shouldTimeoutHandshake() throws Exception
{
k3po.finish();
}
+
+ @Test
+ @Configuration("client.event.yaml")
+ @Specification({
+ "${app}/client.handshake.timeout/client",
+ "${net}/client.handshake.timeout/server" })
+ @Configure(name = TlsConfigurationTest.TLS_HANDSHAKE_TIMEOUT_NAME, value = "1")
+ public void shouldLogHandshakeErrorEvent() throws Exception
+ {
+ k3po.finish();
+ }
}
diff --git a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ServerIT.java b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ServerIT.java
index f36f40709c..83c4a3b84d 100644
--- a/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ServerIT.java
+++ b/runtime/binding-tls/src/test/java/io/aklivity/zilla/runtime/binding/tls/internal/streams/ServerIT.java
@@ -318,4 +318,23 @@ public void shouldRejectWhenPortNotRouted() throws Exception
{
k3po.finish();
}
+
+ @Test
+ @Configuration("server.event.tls.failed.yaml")
+ @Specification({
+ "${net}/client.hello.malformed/client"})
+ public void shouldLogTlsFailedEvent() throws Exception
+ {
+ k3po.finish();
+ }
+
+ @Test
+ @Configuration("server.event.handshake.failed.yaml")
+ @Specification({
+ "${net}/server.handshake.timeout/client"})
+ @Configure(name = TlsConfigurationTest.TLS_HANDSHAKE_TIMEOUT_NAME, value = "1")
+ public void shouldLogHandshakeFailedEvent() throws Exception
+ {
+ k3po.finish();
+ }
}
diff --git a/runtime/engine/pom.xml b/runtime/engine/pom.xml
index ccea03c210..29b6d8b63c 100644
--- a/runtime/engine/pom.xml
+++ b/runtime/engine/pom.xml
@@ -253,6 +253,7 @@
io/aklivity/zilla/runtime/engine/test/internal/**/*.schema.patch.json
io/aklivity/zilla/runtime/engine/test/internal/binding/**/*.class
io/aklivity/zilla/runtime/engine/test/internal/catalog/**/*.class
+ io/aklivity/zilla/runtime/engine/test/internal/event/**/*.class
io/aklivity/zilla/runtime/engine/test/internal/exporter/**/*.class
io/aklivity/zilla/runtime/engine/test/internal/guard/**/*.class
io/aklivity/zilla/runtime/engine/test/internal/metrics/**/*.class
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/Engine.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/Engine.java
index b89c0bde13..3172979cf4 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/Engine.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/Engine.java
@@ -61,6 +61,7 @@
import io.aklivity.zilla.runtime.engine.binding.function.MessageReader;
import io.aklivity.zilla.runtime.engine.catalog.Catalog;
import io.aklivity.zilla.runtime.engine.config.KindConfig;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactory;
import io.aklivity.zilla.runtime.engine.exporter.Exporter;
import io.aklivity.zilla.runtime.engine.ext.EngineExtContext;
import io.aklivity.zilla.runtime.engine.ext.EngineExtSpi;
@@ -108,6 +109,7 @@ public final class Engine implements Collector, AutoCloseable
Collection vaults,
Collection catalogs,
Collection models,
+ EventFormatterFactory eventFormatterFactory,
ErrorHandler errorHandler,
Collection affinities,
boolean readonly)
@@ -161,9 +163,9 @@ public final class Engine implements Collector, AutoCloseable
for (int coreIndex = 0; coreIndex < workerCount; coreIndex++)
{
EngineWorker worker =
- new EngineWorker(config, tasks, labels, errorHandler, tuning::affinity,
- bindings, exporters, guards, vaults, catalogs, models, metricGroups,
- this, this::supplyEventReader, coreIndex, readonly);
+ new EngineWorker(config, tasks, labels, errorHandler, tuning::affinity, bindings, exporters,
+ guards, vaults, catalogs, models, metricGroups, this, this::supplyEventReader,
+ eventFormatterFactory, coreIndex, readonly);
workers.add(worker);
}
this.workers = workers;
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineBuilder.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineBuilder.java
index ae989060c0..3f05d5434f 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineBuilder.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineBuilder.java
@@ -27,6 +27,7 @@
import io.aklivity.zilla.runtime.engine.binding.BindingFactory;
import io.aklivity.zilla.runtime.engine.catalog.Catalog;
import io.aklivity.zilla.runtime.engine.catalog.CatalogFactory;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactory;
import io.aklivity.zilla.runtime.engine.exporter.Exporter;
import io.aklivity.zilla.runtime.engine.exporter.ExporterFactory;
import io.aklivity.zilla.runtime.engine.guard.Guard;
@@ -139,9 +140,11 @@ public Engine build()
models.add(model);
}
+ EventFormatterFactory eventFormatterFactory = EventFormatterFactory.instantiate();
+
final ErrorHandler errorHandler = requireNonNull(this.errorHandler, "errorHandler");
return new Engine(config, bindings, exporters, guards, metricGroups, vaults,
- catalogs, models, errorHandler, affinities, readonly);
+ catalogs, models, eventFormatterFactory, errorHandler, affinities, readonly);
}
}
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineContext.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineContext.java
index 0360890834..8129da8b20 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineContext.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineContext.java
@@ -34,6 +34,7 @@
import io.aklivity.zilla.runtime.engine.config.BindingConfig;
import io.aklivity.zilla.runtime.engine.config.ModelConfig;
import io.aklivity.zilla.runtime.engine.config.NamespaceConfig;
+import io.aklivity.zilla.runtime.engine.event.EventFormatter;
import io.aklivity.zilla.runtime.engine.guard.GuardHandler;
import io.aklivity.zilla.runtime.engine.metrics.Metric;
import io.aklivity.zilla.runtime.engine.model.ConverterHandler;
@@ -71,6 +72,8 @@ MessageConsumer supplySender(
MessageConsumer supplyReceiver(
long streamId);
+ EventFormatter supplyEventFormatter();
+
void detachSender(
long replyId);
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatter.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatter.java
new file mode 100644
index 0000000000..f8ffd8ccd8
--- /dev/null
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.event;
+
+import org.agrona.DirectBuffer;
+import org.agrona.collections.Long2ObjectHashMap;
+
+import io.aklivity.zilla.runtime.engine.factory.Factory;
+
+public final class EventFormatter extends Factory
+{
+ private final Long2ObjectHashMap formatters;
+
+ EventFormatter(
+ Long2ObjectHashMap formatters)
+ {
+ this.formatters = formatters;
+ }
+
+ public String format(
+ int msgTypeId,
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ EventFormatterSpi formatter = formatters.get(msgTypeId);
+ return formatter != null ? formatter.format(buffer, index, length) : null;
+ }
+}
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterFactory.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterFactory.java
new file mode 100644
index 0000000000..a4b083521a
--- /dev/null
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.event;
+
+import static java.util.ServiceLoader.load;
+
+import java.util.Map;
+
+import org.agrona.collections.Long2ObjectHashMap;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.factory.Factory;
+
+public final class EventFormatterFactory extends Factory
+{
+ private final Map factories;
+
+ public EventFormatter create(
+ Configuration config,
+ EngineContext context)
+ {
+ Long2ObjectHashMap formatters = new Long2ObjectHashMap<>();
+ for (Map.Entry entry : factories.entrySet())
+ {
+ String type = entry.getKey();
+ EventFormatterFactorySpi factory = entry.getValue();
+ EventFormatterSpi formatter = factory.create(config);
+ int typeId = context.supplyTypeId(type);
+ formatters.put(typeId, formatter);
+ }
+ return new EventFormatter(formatters);
+ }
+
+ public static EventFormatterFactory instantiate()
+ {
+ return instantiate(load(EventFormatterFactorySpi.class), EventFormatterFactory::new);
+ }
+
+ private EventFormatterFactory(
+ Map factories)
+ {
+ this.factories = factories;
+ }
+}
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterFactorySpi.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterFactorySpi.java
new file mode 100644
index 0000000000..4958f95153
--- /dev/null
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterFactorySpi.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.event;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.factory.FactorySpi;
+
+public interface EventFormatterFactorySpi extends FactorySpi
+{
+ EventFormatterSpi create(
+ Configuration config);
+}
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterSpi.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterSpi.java
new file mode 100644
index 0000000000..9bc5e24394
--- /dev/null
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/event/EventFormatterSpi.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.event;
+
+import org.agrona.DirectBuffer;
+
+public interface EventFormatterSpi
+{
+ String format(
+ DirectBuffer buffer,
+ int index,
+ int length);
+}
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineWorker.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineWorker.java
index f07bfe1a2f..0ff8dab4dc 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineWorker.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineWorker.java
@@ -99,6 +99,8 @@
import io.aklivity.zilla.runtime.engine.config.BindingConfig;
import io.aklivity.zilla.runtime.engine.config.ModelConfig;
import io.aklivity.zilla.runtime.engine.config.NamespaceConfig;
+import io.aklivity.zilla.runtime.engine.event.EventFormatter;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactory;
import io.aklivity.zilla.runtime.engine.exporter.Exporter;
import io.aklivity.zilla.runtime.engine.exporter.ExporterContext;
import io.aklivity.zilla.runtime.engine.exporter.ExporterHandler;
@@ -216,6 +218,7 @@ public class EngineWorker implements EngineContext, Agent
private final HistogramsLayout histogramsLayout;
private final EventsLayout eventsLayout;
private final Supplier supplyEventReader;
+ private final EventFormatter eventFormatter;
private long initialId;
private long promiseId;
private long traceId;
@@ -239,6 +242,7 @@ public EngineWorker(
Collection metricGroups,
Collector collector,
Supplier supplyEventReader,
+ EventFormatterFactory eventFormatterFactory,
int index,
boolean readonly)
{
@@ -420,6 +424,7 @@ public EngineWorker(
this.errorHandler = errorHandler;
this.exportersById = new Long2ObjectHashMap<>();
this.supplyEventReader = supplyEventReader;
+ this.eventFormatter = eventFormatterFactory.create(config, this);
}
public static int indexOfId(
@@ -1608,6 +1613,11 @@ public MessageReader supplyEventReader()
return supplyEventReader.get();
}
+ public EventFormatter supplyEventFormatter()
+ {
+ return this.eventFormatter;
+ }
+
private MessageConsumer supplyWriter(
int index)
{
diff --git a/runtime/engine/src/main/moditect/module-info.java b/runtime/engine/src/main/moditect/module-info.java
index 4c15cb57b3..529ca971b7 100644
--- a/runtime/engine/src/main/moditect/module-info.java
+++ b/runtime/engine/src/main/moditect/module-info.java
@@ -23,6 +23,7 @@
exports io.aklivity.zilla.runtime.engine.catalog;
exports io.aklivity.zilla.runtime.engine.model;
exports io.aklivity.zilla.runtime.engine.model.function;
+ exports io.aklivity.zilla.runtime.engine.event;
exports io.aklivity.zilla.runtime.engine.exporter;
exports io.aklivity.zilla.runtime.engine.factory;
exports io.aklivity.zilla.runtime.engine.guard;
@@ -61,6 +62,7 @@
uses io.aklivity.zilla.runtime.engine.binding.BindingFactorySpi;
uses io.aklivity.zilla.runtime.engine.catalog.CatalogFactorySpi;
uses io.aklivity.zilla.runtime.engine.model.ModelFactorySpi;
+ uses io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
uses io.aklivity.zilla.runtime.engine.exporter.ExporterFactorySpi;
uses io.aklivity.zilla.runtime.engine.guard.GuardFactorySpi;
uses io.aklivity.zilla.runtime.engine.metrics.MetricGroupFactorySpi;
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/EventIT.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/EventIT.java
new file mode 100644
index 0000000000..543bf5ea67
--- /dev/null
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/EventIT.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.test;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.rules.RuleChain.outerRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.DisableOnDebug;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.kaazing.k3po.junit.annotation.Specification;
+import org.kaazing.k3po.junit.rules.K3poRule;
+
+import io.aklivity.zilla.runtime.engine.test.annotation.Configuration;
+
+public class EventIT
+{
+ private final K3poRule k3po = new K3poRule()
+ .addScriptRoot("net", "io/aklivity/zilla/specs/engine/streams/network")
+ .addScriptRoot("app", "io/aklivity/zilla/specs/engine/streams/application");
+
+ private final TestRule timeout = new DisableOnDebug(new Timeout(5, SECONDS));
+
+ private final EngineRule engine = new EngineRule()
+ .directory("target/zilla-itests")
+ .countersBufferCapacity(4096)
+ .configurationRoot("io/aklivity/zilla/specs/engine/config")
+ .external("app0")
+ .clean();
+
+ @Rule
+ public final TestRule chain = outerRule(engine).around(k3po).around(timeout);
+
+ @Test
+ @Configuration("server.event.yaml")
+ @Specification({
+ "${net}/event/client",
+ "${app}/event/server"
+ })
+ public void shouldLogEvents() throws Exception
+ {
+ k3po.finish();
+ }
+}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBinding.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBinding.java
index 662111251d..98c509264a 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBinding.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBinding.java
@@ -23,6 +23,8 @@
public final class TestBinding implements Binding
{
+ public static final String NAME = "test";
+
TestBinding(
Configuration config)
{
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBindingFactory.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBindingFactory.java
index 3765997399..a56b723aff 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBindingFactory.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/TestBindingFactory.java
@@ -15,6 +15,9 @@
*/
package io.aklivity.zilla.runtime.engine.test.internal.binding;
+import java.util.LinkedList;
+import java.util.List;
+
import org.agrona.DirectBuffer;
import org.agrona.MutableDirectBuffer;
import org.agrona.collections.Long2LongHashMap;
@@ -22,8 +25,13 @@
import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.binding.BindingHandler;
import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler;
import io.aklivity.zilla.runtime.engine.config.BindingConfig;
import io.aklivity.zilla.runtime.engine.config.RouteConfig;
+import io.aklivity.zilla.runtime.engine.guard.GuardHandler;
+import io.aklivity.zilla.runtime.engine.namespace.NamespacedId;
+import io.aklivity.zilla.runtime.engine.test.internal.binding.config.TestBindingOptionsConfig;
+import io.aklivity.zilla.runtime.engine.test.internal.event.TestEventContext;
import io.aklivity.zilla.runtime.engine.test.internal.k3po.ext.types.OctetsFW;
import io.aklivity.zilla.runtime.engine.test.internal.k3po.ext.types.stream.AbortFW;
import io.aklivity.zilla.runtime.engine.test.internal.k3po.ext.types.stream.BeginFW;
@@ -62,12 +70,20 @@ final class TestBindingFactory implements BindingHandler
private final EngineContext context;
private final Long2LongHashMap router;
+ private final TestEventContext event;
+
+ private List catalogs;
+ private GuardHandler guard;
+ private String credentials;
+ private List events;
+ private int eventIndex;
TestBindingFactory(
EngineContext context)
{
this.context = context;
this.router = new Long2LongHashMap(-1L);
+ this.event = new TestEventContext(context);
}
public void attach(
@@ -82,6 +98,29 @@ public void attach(
{
router.put(binding.id, exit.id);
}
+
+ TestBindingOptionsConfig options = (TestBindingOptionsConfig) binding.options;
+ if (options != null)
+ {
+ if (options.catalogs != null)
+ {
+ this.catalogs = new LinkedList<>();
+ for (String catalog : options.catalogs)
+ {
+ int namespaceId = context.supplyTypeId(binding.namespace);
+ int catalogId = context.supplyTypeId(catalog);
+ catalogs.add(context.supplyCatalog(NamespacedId.id(namespaceId, catalogId)));
+ }
+ }
+ if (options.authorization != null)
+ {
+ int namespaceId = context.supplyTypeId(binding.namespace);
+ int guardId = context.supplyTypeId(options.authorization.name);
+ this.guard = context.supplyGuard(NamespacedId.id(namespaceId, guardId));
+ this.credentials = options.authorization.credentials;
+ }
+ this.events = options.events;
+ }
}
public void detach(
@@ -204,6 +243,24 @@ private void onInitialBegin(
long traceId = begin.traceId();
target.doInitialBegin(traceId);
+
+ if (catalogs != null)
+ {
+ for (CatalogHandler catalog : catalogs)
+ {
+ catalog.resolve(0);
+ }
+ }
+ if (guard != null)
+ {
+ guard.reauthorize(traceId, routedId, 0, credentials);
+ }
+ while (events != null && eventIndex < events.size())
+ {
+ TestBindingOptionsConfig.Event e = events.get(eventIndex);
+ event.connected(traceId, routedId, e.timestamp, e.message);
+ eventIndex++;
+ }
}
private void onInitialData(
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestAuthorizationConfig.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestAuthorizationConfig.java
new file mode 100644
index 0000000000..6d8069074d
--- /dev/null
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestAuthorizationConfig.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.test.internal.binding.config;
+
+public final class TestAuthorizationConfig
+{
+ public final String name;
+ public final String credentials;
+
+ public TestAuthorizationConfig(
+ String name,
+ String credentials)
+ {
+ this.name = name;
+ this.credentials = credentials;
+ }
+}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfig.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfig.java
index b40a76ec60..96e006b403 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfig.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfig.java
@@ -15,6 +15,7 @@
*/
package io.aklivity.zilla.runtime.engine.test.internal.binding.config;
+import java.util.List;
import java.util.function.Function;
import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
@@ -22,6 +23,9 @@
public final class TestBindingOptionsConfig extends OptionsConfig
{
public final String mode;
+ public final TestAuthorizationConfig authorization;
+ public final List catalogs;
+ public final List events;
public static TestBindingOptionsConfigBuilder builder()
{
@@ -35,8 +39,28 @@ public static TestBindingOptionsConfigBuilder builder(
}
TestBindingOptionsConfig(
- String mode)
+ String mode,
+ TestAuthorizationConfig authorization,
+ List catalogs,
+ List events)
{
this.mode = mode;
+ this.authorization = authorization;
+ this.catalogs = catalogs;
+ this.events = events;
+ }
+
+ public static final class Event
+ {
+ public final long timestamp;
+ public final String message;
+
+ public Event(
+ long timestamp,
+ String message)
+ {
+ this.timestamp = timestamp;
+ this.message = message;
+ }
}
}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigAdapter.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigAdapter.java
index e4b2b09630..6a0b4878d1 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigAdapter.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigAdapter.java
@@ -16,8 +16,12 @@
package io.aklivity.zilla.runtime.engine.test.internal.binding.config;
import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonArrayBuilder;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
import io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi;
@@ -25,6 +29,12 @@
public final class TestBindingOptionsConfigAdapter implements OptionsConfigAdapterSpi
{
private static final String MODE_NAME = "mode";
+ private static final String CATALOGS_NAME = "catalogs";
+ private static final String AUTHORIZATION_NAME = "authorization";
+ private static final String CREDENTIALS_NAME = "credentials";
+ private static final String EVENTS_NAME = "events";
+ private static final String TIMESTAMP_NAME = "timestamp";
+ private static final String MESSAGE_NAME = "message";
@Override
public Kind kind()
@@ -46,7 +56,39 @@ public JsonObject adaptToJson(
JsonObjectBuilder object = Json.createObjectBuilder();
- object.add(MODE_NAME, testOptions.mode);
+ if (testOptions.mode != null)
+ {
+ object.add(MODE_NAME, testOptions.mode);
+ }
+ if (testOptions.catalogs != null)
+ {
+ JsonArrayBuilder catalogs = Json.createArrayBuilder();
+ for (String catalog : testOptions.catalogs)
+ {
+ catalogs.add(catalog);
+ }
+ object.add(CATALOGS_NAME, catalogs);
+ }
+ if (testOptions.authorization != null)
+ {
+ JsonObjectBuilder credentials = Json.createObjectBuilder();
+ credentials.add(CREDENTIALS_NAME, testOptions.authorization.credentials);
+ JsonObjectBuilder authorization = Json.createObjectBuilder();
+ authorization.add(testOptions.authorization.name, credentials);
+ object.add(AUTHORIZATION_NAME, authorization);
+ }
+ if (testOptions.events != null)
+ {
+ JsonArrayBuilder events = Json.createArrayBuilder();
+ for (TestBindingOptionsConfig.Event e : testOptions.events)
+ {
+ JsonObjectBuilder event = Json.createObjectBuilder();
+ event.add(TIMESTAMP_NAME, e.timestamp);
+ event.add(MESSAGE_NAME, e.message);
+ events.add(event);
+ }
+ object.add(EVENTS_NAME, events);
+ }
return object.build();
}
@@ -63,6 +105,40 @@ public OptionsConfig adaptFromJson(
{
testOptions.mode(object.getString(MODE_NAME));
}
+ if (object.containsKey(CATALOGS_NAME))
+ {
+ JsonArray catalogs = object.getJsonArray(CATALOGS_NAME);
+ for (JsonValue catalog : catalogs)
+ {
+ testOptions.catalog(((JsonString) catalog).getString());
+ }
+ }
+ if (object.containsKey(AUTHORIZATION_NAME))
+ {
+ JsonObject authorization = object.getJsonObject(AUTHORIZATION_NAME);
+ String name = authorization.keySet().stream().findFirst().orElse(null);
+ if (name != null)
+ {
+ JsonObject guard = authorization.getJsonObject(name);
+ if (guard.containsKey(CREDENTIALS_NAME))
+ {
+ String credentials = guard.getString(CREDENTIALS_NAME);
+ testOptions.authorization(name, credentials);
+ }
+ }
+ }
+ if (object.containsKey(EVENTS_NAME))
+ {
+ JsonArray events = object.getJsonArray(EVENTS_NAME);
+ for (JsonValue e : events)
+ {
+ JsonObject e0 = e.asJsonObject();
+ if (e0.containsKey(TIMESTAMP_NAME) && e0.containsKey(MESSAGE_NAME))
+ {
+ testOptions.event(e0.getInt(TIMESTAMP_NAME), e0.getString(MESSAGE_NAME));
+ }
+ }
+ }
}
return testOptions.build();
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigBuilder.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigBuilder.java
index b8ecf148aa..dadfe4a81f 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigBuilder.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/binding/config/TestBindingOptionsConfigBuilder.java
@@ -15,6 +15,8 @@
*/
package io.aklivity.zilla.runtime.engine.test.internal.binding.config;
+import java.util.LinkedList;
+import java.util.List;
import java.util.function.Function;
import io.aklivity.zilla.runtime.engine.config.ConfigBuilder;
@@ -25,6 +27,9 @@ public final class TestBindingOptionsConfigBuilder extends ConfigBuilder mapper;
private String mode;
+ private TestAuthorizationConfig authorization;
+ private List catalogs;
+ private List events;
TestBindingOptionsConfigBuilder(
Function mapper)
@@ -46,9 +51,40 @@ public TestBindingOptionsConfigBuilder mode(
return this;
}
+ public TestBindingOptionsConfigBuilder catalog(
+ String catalog)
+ {
+ if (this.catalogs == null)
+ {
+ this.catalogs = new LinkedList<>();
+ }
+ this.catalogs.add(catalog);
+ return this;
+ }
+
+ public TestBindingOptionsConfigBuilder authorization(
+ String name,
+ String credentials)
+ {
+ this.authorization = new TestAuthorizationConfig(name, credentials);
+ return this;
+ }
+
+ public TestBindingOptionsConfigBuilder event(
+ long timestamp,
+ String message)
+ {
+ if (this.events == null)
+ {
+ this.events = new LinkedList<>();
+ }
+ this.events.add(new TestBindingOptionsConfig.Event(timestamp, message));
+ return this;
+ }
+
@Override
public T build()
{
- return mapper.apply(new TestBindingOptionsConfig(mode));
+ return mapper.apply(new TestBindingOptionsConfig(mode, authorization, catalogs, events));
}
}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventContext.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventContext.java
new file mode 100644
index 0000000000..957bbdcd84
--- /dev/null
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventContext.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.test.internal.event;
+
+import java.nio.ByteBuffer;
+import java.time.Clock;
+
+import org.agrona.concurrent.AtomicBuffer;
+import org.agrona.concurrent.UnsafeBuffer;
+
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
+import io.aklivity.zilla.runtime.engine.internal.types.String8FW;
+import io.aklivity.zilla.runtime.engine.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.engine.test.internal.binding.TestBinding;
+
+public class TestEventContext
+{
+ private static final int EVENT_BUFFER_CAPACITY = 2048;
+
+ private final AtomicBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final EventFW.Builder eventRW = new EventFW.Builder();
+ private final int testTypeId;
+ private final MessageConsumer eventWriter;
+ private final Clock clock;
+
+ public TestEventContext(
+ EngineContext context)
+ {
+ this.testTypeId = context.supplyTypeId(TestBinding.NAME);
+ this.eventWriter = context.supplyEventWriter();
+ this.clock = context.clock();
+ }
+
+ public void connected(
+ long traceId,
+ long bindingId,
+ long timestamp,
+ String message)
+ {
+ String8FW extension = new String8FW(message);
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(timestamp)
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
+ eventWriter.accept(testTypeId, event.buffer(), event.offset(), event.limit());
+ }
+}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventFormatter.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventFormatter.java
new file mode 100644
index 0000000000..55a02b0111
--- /dev/null
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventFormatter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.test.internal.event;
+
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;
+import io.aklivity.zilla.runtime.engine.internal.types.String8FW;
+import io.aklivity.zilla.runtime.engine.internal.types.event.EventFW;
+
+public final class TestEventFormatter implements EventFormatterSpi
+{
+ private final EventFW eventRO = new EventFW();
+ private final String8FW extensionRO = new String8FW();
+
+ TestEventFormatter(
+ Configuration config)
+ {
+ }
+
+ @Override
+ public String format(
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ String8FW extension = extensionRO.wrap(event.extension().buffer(), event.extension().offset(), event.extension().limit());
+ return extension.asString();
+ }
+}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventFormatterFactory.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventFormatterFactory.java
new file mode 100644
index 0000000000..7f026f5c27
--- /dev/null
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/event/TestEventFormatterFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc.
+ *
+ * Aklivity licenses this file to you under the Apache License,
+ * version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package io.aklivity.zilla.runtime.engine.test.internal.event;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
+import io.aklivity.zilla.runtime.engine.test.internal.binding.TestBinding;
+
+public class TestEventFormatterFactory implements EventFormatterFactorySpi
+{
+ @Override
+ public TestEventFormatter create(
+ Configuration config)
+ {
+ return new TestEventFormatter(config);
+ }
+
+ @Override
+ public String type()
+ {
+ return TestBinding.NAME;
+ }
+}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporter.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporter.java
index c156ad5a20..dfe1576f86 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporter.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporter.java
@@ -45,6 +45,6 @@ public URL type()
public ExporterContext supply(
EngineContext context)
{
- return new TestExporterContext();
+ return new TestExporterContext(context);
}
}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporterContext.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporterContext.java
index 8c87e79390..eb8b353a38 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporterContext.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporterContext.java
@@ -18,6 +18,7 @@
import java.util.List;
import java.util.function.LongFunction;
+import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.config.AttributeConfig;
import io.aklivity.zilla.runtime.engine.config.ExporterConfig;
import io.aklivity.zilla.runtime.engine.config.KindConfig;
@@ -27,14 +28,22 @@
public class TestExporterContext implements ExporterContext
{
+ private final EngineContext context;
+
+ public TestExporterContext(
+ EngineContext context)
+ {
+ this.context = context;
+ }
+
@Override
public ExporterHandler attach(
- ExporterConfig config,
+ ExporterConfig exporter,
List attributes,
Collector collector,
LongFunction resolveKind)
{
- return new TestExporterHandler();
+ return new TestExporterHandler(context, exporter);
}
@Override
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporterHandler.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporterHandler.java
index abcca20fd9..d8aa76d1c4 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporterHandler.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/TestExporterHandler.java
@@ -15,10 +15,36 @@
*/
package io.aklivity.zilla.runtime.engine.test.internal.exporter;
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.binding.function.MessageReader;
+import io.aklivity.zilla.runtime.engine.config.ExporterConfig;
+import io.aklivity.zilla.runtime.engine.event.EventFormatter;
import io.aklivity.zilla.runtime.engine.exporter.ExporterHandler;
+import io.aklivity.zilla.runtime.engine.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.engine.test.internal.exporter.config.TestExporterOptionsConfig;
class TestExporterHandler implements ExporterHandler
{
+ private final EngineContext context;
+ private final TestExporterOptionsConfig options;
+ private final MessageReader readEvent;
+ private final EventFormatter formatter;
+ private final EventFW eventRO = new EventFW();
+
+ private int eventIndex;
+
+ TestExporterHandler(
+ EngineContext context,
+ ExporterConfig exporter)
+ {
+ this.context = context;
+ this.readEvent = context.supplyEventReader();
+ this.formatter = context.supplyEventFormatter();
+ this.options = (TestExporterOptionsConfig) exporter.options;
+ }
+
@Override
public void start()
{
@@ -27,11 +53,32 @@ public void start()
@Override
public int export()
{
- return 0;
+ return readEvent.read(this::handleEvent, 1);
}
@Override
public void stop()
{
}
+
+ private void handleEvent(
+ int msgTypeId,
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ String qname = context.supplyQName(event.namespacedId());
+ String message = formatter.format(msgTypeId, buffer, index, length);
+ if (options.events != null && eventIndex < options.events.size())
+ {
+ TestExporterOptionsConfig.Event e = options.events.get(eventIndex);
+ if (!e.qName.equals(qname) || !e.message.equals(message))
+ {
+ throw new IllegalStateException(String.format("event mismatch, expected: %s %s, got: %s %s",
+ e.qName, e.message, qname, message));
+ }
+ eventIndex++;
+ }
+ }
}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfig.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfig.java
index 989b155ed7..1ca1597582 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfig.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfig.java
@@ -15,6 +15,7 @@
*/
package io.aklivity.zilla.runtime.engine.test.internal.exporter.config;
+import java.util.List;
import java.util.function.Function;
import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
@@ -22,6 +23,7 @@
public final class TestExporterOptionsConfig extends OptionsConfig
{
public final String mode;
+ public final List events;
public static TestExporterOptionsConfigBuilder builder()
{
@@ -35,8 +37,24 @@ public static TestExporterOptionsConfigBuilder builder(
}
TestExporterOptionsConfig(
- String mode)
+ String mode,
+ List events)
{
this.mode = mode;
+ this.events = events;
+ }
+
+ public static final class Event
+ {
+ public final String qName;
+ public final String message;
+
+ public Event(
+ String qName,
+ String message)
+ {
+ this.qName = qName;
+ this.message = message;
+ }
}
}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfigAdapter.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfigAdapter.java
index 8694215761..3c31073a31 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfigAdapter.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfigAdapter.java
@@ -18,8 +18,11 @@
import static java.util.function.Function.identity;
import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonArrayBuilder;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonValue;
import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
import io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi;
@@ -27,6 +30,9 @@
public final class TestExporterOptionsConfigAdapter implements OptionsConfigAdapterSpi
{
private static final String MODE_NAME = "mode";
+ private static final String EVENTS_NAME = "events";
+ private static final String QNAME_NAME = "qname";
+ private static final String MESSAGE_NAME = "message";
@Override
public Kind kind()
@@ -48,7 +54,23 @@ public JsonObject adaptToJson(
JsonObjectBuilder object = Json.createObjectBuilder();
- object.add(MODE_NAME, testOptions.mode);
+ if (testOptions.mode != null)
+ {
+ object.add(MODE_NAME, testOptions.mode);
+ }
+
+ if (testOptions.events != null)
+ {
+ JsonArrayBuilder events = Json.createArrayBuilder();
+ for (TestExporterOptionsConfig.Event e : testOptions.events)
+ {
+ JsonObjectBuilder event = Json.createObjectBuilder();
+ event.add(QNAME_NAME, e.qName);
+ event.add(MESSAGE_NAME, e.message);
+ events.add(event);
+ }
+ object.add(EVENTS_NAME, events);
+ }
return object.build();
}
@@ -66,6 +88,18 @@ public OptionsConfig adaptFromJson(
{
testOptions.mode(object.getString(MODE_NAME));
}
+ if (object.containsKey(EVENTS_NAME))
+ {
+ JsonArray events = object.getJsonArray(EVENTS_NAME);
+ for (JsonValue e : events)
+ {
+ JsonObject e0 = e.asJsonObject();
+ if (e0.containsKey(QNAME_NAME) && e0.containsKey(MESSAGE_NAME))
+ {
+ testOptions.event(e0.getString(QNAME_NAME), e0.getString(MESSAGE_NAME));
+ }
+ }
+ }
}
return testOptions.build();
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfigBuilder.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfigBuilder.java
index 27abc1cbca..db8432cf1d 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfigBuilder.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/exporter/config/TestExporterOptionsConfigBuilder.java
@@ -15,6 +15,8 @@
*/
package io.aklivity.zilla.runtime.engine.test.internal.exporter.config;
+import java.util.LinkedList;
+import java.util.List;
import java.util.function.Function;
import io.aklivity.zilla.runtime.engine.config.ConfigBuilder;
@@ -25,6 +27,7 @@ public final class TestExporterOptionsConfigBuilder extends ConfigBuilder mapper;
private String mode;
+ private List events;
TestExporterOptionsConfigBuilder(
Function mapper)
@@ -46,9 +49,21 @@ public TestExporterOptionsConfigBuilder mode(
return this;
}
+ public TestExporterOptionsConfigBuilder event(
+ String qName,
+ String message)
+ {
+ if (this.events == null)
+ {
+ this.events = new LinkedList<>();
+ }
+ this.events.add(new TestExporterOptionsConfig.Event(qName, message));
+ return this;
+ }
+
@Override
public T build()
{
- return mapper.apply(new TestExporterOptionsConfig(mode));
+ return mapper.apply(new TestExporterOptionsConfig(mode, events));
}
}
diff --git a/runtime/engine/src/test/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi b/runtime/engine/src/test/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
new file mode 100644
index 0000000000..1bb290c506
--- /dev/null
+++ b/runtime/engine/src/test/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.engine.test.internal.event.TestEventFormatterFactory
diff --git a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventContext.java b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventContext.java
index 99d0fa6146..3eb93da4f0 100644
--- a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventContext.java
+++ b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventContext.java
@@ -14,22 +14,27 @@
*/
package io.aklivity.zilla.runtime.guard.jwt.internal;
+import static io.aklivity.zilla.runtime.guard.jwt.internal.types.event.JwtEventType.AUTHORIZATION_FAILED;
+
import java.nio.ByteBuffer;
import java.time.Clock;
-import org.agrona.MutableDirectBuffer;
+import org.agrona.concurrent.AtomicBuffer;
import org.agrona.concurrent.UnsafeBuffer;
import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
-import io.aklivity.zilla.runtime.guard.jwt.internal.types.event.JwtEventFW;
+import io.aklivity.zilla.runtime.guard.jwt.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.guard.jwt.internal.types.event.JwtEventExFW;
public class JwtEventContext
{
private static final int EVENT_BUFFER_CAPACITY = 1024;
- private final JwtEventFW.Builder jwtEventRW = new JwtEventFW.Builder();
- private final MutableDirectBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final AtomicBuffer extensionBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final EventFW.Builder eventRW = new EventFW.Builder();
+ private final JwtEventExFW.Builder jwtEventExRW = new JwtEventExFW.Builder();
private final int jwtTypeId;
private final MessageConsumer eventWriter;
private final Clock clock;
@@ -47,15 +52,20 @@ public void authorizationFailed(
long bindingId,
String identity)
{
- JwtEventFW event = jwtEventRW
- .wrap(eventBuffer, 0, eventBuffer.capacity())
+ JwtEventExFW extension = jwtEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
.authorizationFailed(e -> e
- .timestamp(clock.millis())
- .traceId(traceId)
- .namespacedId(bindingId)
+ .typeId(AUTHORIZATION_FAILED.value())
.identity(identity)
)
.build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .timestamp(clock.millis())
+ .traceId(traceId)
+ .namespacedId(bindingId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
eventWriter.accept(jwtTypeId, event.buffer(), event.offset(), event.limit());
}
}
diff --git a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventFormatter.java b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventFormatter.java
new file mode 100644
index 0000000000..36282d3a48
--- /dev/null
+++ b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventFormatter.java
@@ -0,0 +1,65 @@
+/*
+ * 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.guard.jwt.internal;
+
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;
+import io.aklivity.zilla.runtime.guard.jwt.internal.types.StringFW;
+import io.aklivity.zilla.runtime.guard.jwt.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.guard.jwt.internal.types.event.JwtAuthorizationFailedExFW;
+import io.aklivity.zilla.runtime.guard.jwt.internal.types.event.JwtEventExFW;
+
+public final class JwtEventFormatter implements EventFormatterSpi
+{
+ private static final String AUTHORIZATION_FAILED_FORMAT = "AUTHORIZATION_FAILED %s";
+
+ private final EventFW eventRO = new EventFW();
+ private final JwtEventExFW jwtEventExRO = new JwtEventExFW();
+
+ JwtEventFormatter(
+ Configuration config)
+ {
+ }
+
+ public String format(
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ final JwtEventExFW extension = jwtEventExRO
+ .wrap(event.extension().buffer(), event.extension().offset(), event.extension().limit());
+ String result = null;
+ switch (extension.kind())
+ {
+ case AUTHORIZATION_FAILED:
+ {
+ JwtAuthorizationFailedExFW ex = extension.authorizationFailed();
+ result = String.format(AUTHORIZATION_FAILED_FORMAT, identity(ex.identity()));
+ break;
+ }
+ }
+ return result;
+ }
+
+ private static String identity(
+ StringFW identity)
+ {
+ int length = identity.length();
+ return length <= 0 ? "-" : identity.asString();
+ }
+}
diff --git a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventFormatterFactory.java b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventFormatterFactory.java
new file mode 100644
index 0000000000..264f316173
--- /dev/null
+++ b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtEventFormatterFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.runtime.guard.jwt.internal;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
+
+public final class JwtEventFormatterFactory implements EventFormatterFactorySpi
+{
+ @Override
+ public JwtEventFormatter create(
+ Configuration config)
+ {
+ return new JwtEventFormatter(config);
+ }
+
+ @Override
+ public String type()
+ {
+ return JwtGuard.NAME;
+ }
+}
diff --git a/runtime/guard-jwt/src/main/moditect/module-info.java b/runtime/guard-jwt/src/main/moditect/module-info.java
index 0d9410c4d4..e49b3bc5cf 100644
--- a/runtime/guard-jwt/src/main/moditect/module-info.java
+++ b/runtime/guard-jwt/src/main/moditect/module-info.java
@@ -24,4 +24,7 @@
provides io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi
with io.aklivity.zilla.runtime.guard.jwt.internal.config.JwtOptionsConfigAdapter;
+
+ provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
+ with io.aklivity.zilla.runtime.guard.jwt.internal.JwtEventFormatterFactory;
}
diff --git a/runtime/guard-jwt/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi b/runtime/guard-jwt/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
new file mode 100644
index 0000000000..0ff19451b8
--- /dev/null
+++ b/runtime/guard-jwt/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.guard.jwt.internal.JwtEventFormatterFactory
diff --git a/runtime/guard-jwt/src/test/java/io/aklivity/zilla/runtime/guard/jwt/internal/EventIT.java b/runtime/guard-jwt/src/test/java/io/aklivity/zilla/runtime/guard/jwt/internal/EventIT.java
new file mode 100644
index 0000000000..d6dc34cf9c
--- /dev/null
+++ b/runtime/guard-jwt/src/test/java/io/aklivity/zilla/runtime/guard/jwt/internal/EventIT.java
@@ -0,0 +1,59 @@
+/*
+ * 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.guard.jwt.internal;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.rules.RuleChain.outerRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.DisableOnDebug;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.kaazing.k3po.junit.annotation.Specification;
+import org.kaazing.k3po.junit.rules.K3poRule;
+
+import io.aklivity.zilla.runtime.engine.test.EngineRule;
+import io.aklivity.zilla.runtime.engine.test.annotation.Configuration;
+
+public class EventIT
+{
+ private final K3poRule k3po = new K3poRule()
+ .addScriptRoot("net", "io/aklivity/zilla/specs/engine/streams/network")
+ .addScriptRoot("app", "io/aklivity/zilla/specs/engine/streams/application");
+
+ private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS));
+
+ private final EngineRule engine = new EngineRule()
+ .directory("target/zilla-itests")
+ .countersBufferCapacity(4096)
+ .configurationRoot("io/aklivity/zilla/specs/guard/jwt/config")
+ .external("app0")
+ .clean();
+
+ @Rule
+ public final TestRule chain = outerRule(engine).around(k3po).around(timeout);
+
+ @Test
+ @Configuration("event.yaml")
+ @Specification({
+ "${net}/event/client",
+ "${app}/event/server"
+ })
+ public void shouldLogEvents() throws Exception
+ {
+ k3po.finish();
+ }
+}
diff --git a/specs/binding-http.spec/src/main/resources/META-INF/zilla/http.idl b/specs/binding-http.spec/src/main/resources/META-INF/zilla/http.idl
index 5bffe232f1..ee3d167cfc 100644
--- a/specs/binding-http.spec/src/main/resources/META-INF/zilla/http.idl
+++ b/specs/binding-http.spec/src/main/resources/META-INF/zilla/http.idl
@@ -57,7 +57,7 @@ scope http
REQUEST_ACCEPTED (1)
}
- struct HttpRequestAccepted extends core::event::Event
+ struct HttpRequestAcceptedEx extends core::stream::Extension
{
string8 identity;
string8 scheme;
@@ -66,9 +66,9 @@ scope http
string16 path;
}
- union HttpEvent switch (HttpEventType)
+ union HttpEventEx switch (HttpEventType)
{
- case REQUEST_ACCEPTED: HttpRequestAccepted requestAccepted;
+ case REQUEST_ACCEPTED: HttpRequestAcceptedEx requestAccepted;
}
}
}
diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.event.yaml b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.event.yaml
new file mode 100644
index 0000000000..7f3236d01b
--- /dev/null
+++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v1.1/server.event.yaml
@@ -0,0 +1,38 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.net0
+ message: REQUEST_ACCEPTED - http GET localhost:8080 /
+bindings:
+ net0:
+ type: http
+ kind: server
+ options:
+ versions:
+ - http/1.1
+ routes:
+ - exit: app0
+ when:
+ - headers:
+ :authority: localhost:8080
diff --git a/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.event.yaml b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.event.yaml
new file mode 100644
index 0000000000..8ee2f34140
--- /dev/null
+++ b/specs/binding-http.spec/src/main/scripts/io/aklivity/zilla/specs/binding/http/config/v2/server.event.yaml
@@ -0,0 +1,38 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.net0
+ message: REQUEST_ACCEPTED - http GET localhost:8080 /
+bindings:
+ net0:
+ type: http
+ kind: server
+ options:
+ versions:
+ - h2
+ routes:
+ - exit: app0
+ when:
+ - headers:
+ :authority: localhost:8080
diff --git a/specs/binding-kafka.spec/src/main/resources/META-INF/zilla/kafka.idl b/specs/binding-kafka.spec/src/main/resources/META-INF/zilla/kafka.idl
index 5c66e319b4..0377305825 100644
--- a/specs/binding-kafka.spec/src/main/resources/META-INF/zilla/kafka.idl
+++ b/specs/binding-kafka.spec/src/main/resources/META-INF/zilla/kafka.idl
@@ -542,16 +542,21 @@ scope kafka
API_VERSION_REJECTED (2)
}
- struct KafkaApiVersionRejected extends core::event::Event
+ struct KafkaAuthorizationFailedEx extends core::stream::Extension
+ {
+ string8 identity;
+ }
+
+ struct KafkaApiVersionRejectedEx extends core::stream::Extension
{
int32 apiKey;
int32 apiVersion;
}
- union KafkaEvent switch (KafkaEventType)
+ union KafkaEventEx switch (KafkaEventType)
{
- case AUTHORIZATION_FAILED: core::event::Event authorizationFailed;
- case API_VERSION_REJECTED: KafkaApiVersionRejected apiVersionRejected;
+ case AUTHORIZATION_FAILED: KafkaAuthorizationFailedEx authorizationFailed;
+ case API_VERSION_REJECTED: KafkaApiVersionRejectedEx apiVersionRejected;
}
}
}
diff --git a/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/config/client.event.yaml b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/config/client.event.yaml
new file mode 100644
index 0000000000..5b2129098a
--- /dev/null
+++ b/specs/binding-kafka.spec/src/main/scripts/io/aklivity/zilla/specs/binding/kafka/config/client.event.yaml
@@ -0,0 +1,31 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.app0
+ message: API_VERSION_REJECTED 32 0
+bindings:
+ app0:
+ type: kafka
+ kind: client
+ exit: net0
diff --git a/specs/binding-tcp.spec/src/main/resources/META-INF/zilla/tcp.idl b/specs/binding-tcp.spec/src/main/resources/META-INF/zilla/tcp.idl
index a796c117f5..13dcdfe173 100644
--- a/specs/binding-tcp.spec/src/main/resources/META-INF/zilla/tcp.idl
+++ b/specs/binding-tcp.spec/src/main/resources/META-INF/zilla/tcp.idl
@@ -22,14 +22,14 @@ scope tcp
DNS_FAILED (1)
}
- struct TcpDnsFailed extends core::event::Event
+ struct TcpDnsFailedEx extends core::stream::Extension
{
string16 address;
}
- union TcpEvent switch (TcpEventType)
+ union TcpEventEx switch (TcpEventType)
{
- case DNS_FAILED: TcpDnsFailed dnsFailed;
+ case DNS_FAILED: TcpDnsFailedEx dnsFailed;
}
}
}
diff --git a/specs/binding-tcp.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tcp/config/client.event.yaml b/specs/binding-tcp.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tcp/config/client.event.yaml
new file mode 100644
index 0000000000..9144628d29
--- /dev/null
+++ b/specs/binding-tcp.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tcp/config/client.event.yaml
@@ -0,0 +1,33 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.app0
+ message: DNS_FAILED localhost
+bindings:
+ app0:
+ type: tcp
+ kind: client
+ options:
+ host: localhost
+ port: 8080
diff --git a/specs/binding-tls.spec/src/main/resources/META-INF/zilla/tls.idl b/specs/binding-tls.spec/src/main/resources/META-INF/zilla/tls.idl
index c81e96e2c7..baa53655f6 100644
--- a/specs/binding-tls.spec/src/main/resources/META-INF/zilla/tls.idl
+++ b/specs/binding-tls.spec/src/main/resources/META-INF/zilla/tls.idl
@@ -26,13 +26,13 @@ scope tls
TLS_HANDSHAKE_FAILED (5)
}
- union TlsEvent switch (TlsEventType)
+ union TlsEventEx switch (TlsEventType)
{
- case TLS_FAILED: core::event::Event tlsFailed;
- case TLS_PROTOCOL_REJECTED: core::event::Event tlsProtocolRejected;
- case TLS_KEY_REJECTED: core::event::Event tlsKeyRejected;
- case TLS_PEER_NOT_VERIFIED: core::event::Event tlsPeerNotVerified;
- case TLS_HANDSHAKE_FAILED: core::event::Event tlsHandshakeFailed;
+ case TLS_FAILED: core::stream::Extension tlsFailed;
+ case TLS_PROTOCOL_REJECTED: core::stream::Extension tlsProtocolRejected;
+ case TLS_KEY_REJECTED: core::stream::Extension tlsKeyRejected;
+ case TLS_PEER_NOT_VERIFIED: core::stream::Extension tlsPeerNotVerified;
+ case TLS_HANDSHAKE_FAILED: core::stream::Extension tlsHandshakeFailed;
}
}
}
diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.event.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.event.yaml
new file mode 100644
index 0000000000..82acb65425
--- /dev/null
+++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/client.event.yaml
@@ -0,0 +1,43 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.app0
+ message: HANDSHAKE_FAILED
+vaults:
+ client:
+ type: filesystem
+ options:
+ trust:
+ store: stores/client/trust
+ type: pkcs12
+ password: generated
+bindings:
+ app0:
+ type: tls
+ kind: client
+ vault: client
+ options:
+ trust:
+ - serverca
+ exit: net0
diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.handshake.failed.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.handshake.failed.yaml
new file mode 100644
index 0000000000..ddc6fd50a3
--- /dev/null
+++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.handshake.failed.yaml
@@ -0,0 +1,43 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.net0
+ message: HANDSHAKE_FAILED
+vaults:
+ server:
+ type: filesystem
+ options:
+ keys:
+ store: stores/server/keys
+ type: pkcs12
+ password: generated
+bindings:
+ net0:
+ type: tls
+ kind: server
+ vault: server
+ options:
+ keys:
+ - localhost
+ exit: app0
diff --git a/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.tls.failed.yaml b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.tls.failed.yaml
new file mode 100644
index 0000000000..3057400b82
--- /dev/null
+++ b/specs/binding-tls.spec/src/main/scripts/io/aklivity/zilla/specs/binding/tls/config/server.event.tls.failed.yaml
@@ -0,0 +1,43 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.net0
+ message: TLS_FAILED
+vaults:
+ server:
+ type: filesystem
+ options:
+ keys:
+ store: stores/server/keys
+ type: pkcs12
+ password: generated
+bindings:
+ net0:
+ type: tls
+ kind: server
+ vault: server
+ options:
+ keys:
+ - localhost
+ exit: app0
diff --git a/specs/engine.spec/src/main/resources/META-INF/zilla/core.idl b/specs/engine.spec/src/main/resources/META-INF/zilla/core.idl
index 05dfc800aa..e64e934b69 100644
--- a/specs/engine.spec/src/main/resources/META-INF/zilla/core.idl
+++ b/specs/engine.spec/src/main/resources/META-INF/zilla/core.idl
@@ -108,6 +108,7 @@ scope core
int64 timestamp;
int64 traceId;
int64 namespacedId;
+ octets extension;
}
}
}
diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/config/server.event.yaml b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/config/server.event.yaml
new file mode 100644
index 0000000000..1ff1010393
--- /dev/null
+++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/config/server.event.yaml
@@ -0,0 +1,35 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.net0
+ message: test event message
+bindings:
+ net0:
+ type: test
+ kind: server
+ options:
+ events:
+ - timestamp: 42
+ message: test event message
+ exit: app0
diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/binding/test.schema.patch.json b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/binding/test.schema.patch.json
index 069578e870..e5166b771e 100644
--- a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/binding/test.schema.patch.json
+++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/binding/test.schema.patch.json
@@ -70,6 +70,55 @@
}
}
]
+ },
+ "catalogs":
+ {
+ "type": "array",
+ "items":
+ {
+ "type": "string"
+ }
+ },
+ "authorization":
+ {
+ "type": "object",
+ "properties":
+ {
+ "type": "object",
+ "patternProperties":
+ {
+ "^[a-zA-Z]+[a-zA-Z0-9\\._\\-]*$":
+ {
+ "type": "object",
+ "properties":
+ {
+ "credentials":
+ {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "events":
+ {
+ "type": "array",
+ "items":
+ {
+ "type": "object",
+ "properties":
+ {
+ "timestamp":
+ {
+ "type": "integer"
+ },
+ "message":
+ {
+ "type": "string"
+ }
+ }
+ }
}
},
"additionalProperties": false
diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/exporter/test.schema.patch.json b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/exporter/test.schema.patch.json
index 44e3271eda..0f6644dafe 100644
--- a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/exporter/test.schema.patch.json
+++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/schema/exporter/test.schema.patch.json
@@ -26,8 +26,35 @@
"type":
{
"const": "test"
+ },
+ "options":
+ {
+ "type": "object",
+ "properties":
+ {
+ "events":
+ {
+ "type": "array",
+ "items":
+ {
+ "type": "object",
+ "properties":
+ {
+ "timestamp":
+ {
+ "type": "integer"
+ },
+ "message":
+ {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
}
- }
+ },
+ "additionalProperties": false
}
}
}
diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/application/event/client.rpt b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/application/event/client.rpt
new file mode 100644
index 0000000000..500aa3c174
--- /dev/null
+++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/application/event/client.rpt
@@ -0,0 +1,20 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+connect "zilla://streams/app0"
+ option zilla:window 8192
+
+connected
diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/application/event/server.rpt b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/application/event/server.rpt
new file mode 100644
index 0000000000..e50a264e14
--- /dev/null
+++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/application/event/server.rpt
@@ -0,0 +1,21 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+accept "zilla://streams/app0"
+ option zilla:window 8192
+
+accepted
+connected
diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/network/event/client.rpt b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/network/event/client.rpt
new file mode 100644
index 0000000000..73deb25750
--- /dev/null
+++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/network/event/client.rpt
@@ -0,0 +1,20 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+connect "zilla://streams/net0"
+ option zilla:window 8192
+
+connected
diff --git a/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/network/event/server.rpt b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/network/event/server.rpt
new file mode 100644
index 0000000000..f48bc644a1
--- /dev/null
+++ b/specs/engine.spec/src/main/scripts/io/aklivity/zilla/specs/engine/streams/network/event/server.rpt
@@ -0,0 +1,21 @@
+#
+# Copyright 2021-2023 Aklivity Inc.
+#
+# Aklivity licenses this file to you under the Apache License,
+# version 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+
+accept "zilla://streams/net0"
+ option zilla:window 8192
+
+accepted
+connected
diff --git a/specs/engine.spec/src/test/java/io/aklivity/zilla/specs/engine/streams/ApplicationIT.java b/specs/engine.spec/src/test/java/io/aklivity/zilla/specs/engine/streams/ApplicationIT.java
index 65c49ae5a6..e079e617ce 100644
--- a/specs/engine.spec/src/test/java/io/aklivity/zilla/specs/engine/streams/ApplicationIT.java
+++ b/specs/engine.spec/src/test/java/io/aklivity/zilla/specs/engine/streams/ApplicationIT.java
@@ -128,4 +128,14 @@ public void shouldNotReconfigureWhen500Returned() throws Exception
{
k3po.finish();
}
+
+ @Test
+ @Specification({
+ "${app}/event/server",
+ "${app}/event/client",
+ })
+ public void shouldConnect() throws Exception
+ {
+ k3po.finish();
+ }
}
diff --git a/specs/engine.spec/src/test/java/io/aklivity/zilla/specs/engine/streams/NetworkIT.java b/specs/engine.spec/src/test/java/io/aklivity/zilla/specs/engine/streams/NetworkIT.java
index ff59b85799..4837938048 100644
--- a/specs/engine.spec/src/test/java/io/aklivity/zilla/specs/engine/streams/NetworkIT.java
+++ b/specs/engine.spec/src/test/java/io/aklivity/zilla/specs/engine/streams/NetworkIT.java
@@ -128,4 +128,14 @@ public void shouldNotReconfigureWhen500Returned() throws Exception
{
k3po.finish();
}
+
+ @Test
+ @Specification({
+ "${net}/event/server",
+ "${net}/event/client"
+ })
+ public void shouldConnect() throws Exception
+ {
+ k3po.finish();
+ }
}
diff --git a/specs/guard-jwt.spec/src/main/resources/META-INF/zilla/jwt.idl b/specs/guard-jwt.spec/src/main/resources/META-INF/zilla/jwt.idl
index 997f9bf859..937f7f2cf7 100644
--- a/specs/guard-jwt.spec/src/main/resources/META-INF/zilla/jwt.idl
+++ b/specs/guard-jwt.spec/src/main/resources/META-INF/zilla/jwt.idl
@@ -21,14 +21,14 @@ scope jwt
AUTHORIZATION_FAILED (1)
}
- struct JwtAuthorizationFailed extends core::event::Event
+ struct JwtAuthorizationFailedEx extends core::stream::Extension
{
string8 identity;
}
- union JwtEvent switch (JwtEventType)
+ union JwtEventEx switch (JwtEventType)
{
- case AUTHORIZATION_FAILED: JwtAuthorizationFailed authorizationFailed;
+ case AUTHORIZATION_FAILED: JwtAuthorizationFailedEx authorizationFailed;
}
}
}
diff --git a/specs/guard-jwt.spec/src/main/scripts/io/aklivity/zilla/specs/guard/jwt/config/event.yaml b/specs/guard-jwt.spec/src/main/scripts/io/aklivity/zilla/specs/guard/jwt/config/event.yaml
new file mode 100644
index 0000000000..eed8bb3001
--- /dev/null
+++ b/specs/guard-jwt.spec/src/main/scripts/io/aklivity/zilla/specs/guard/jwt/config/event.yaml
@@ -0,0 +1,46 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.net0
+ message: AUTHORIZATION_FAILED user
+guards:
+ jwt0:
+ type: jwt
+ options:
+ issuer: https://auth.example.com
+ audience: https://api.example.com
+ keys:
+ - kty: RSA
+ n: qqEu50hX+43Bx4W1UYWnAVKwFm+vDbP0kuIOSLVNa+HKQdHTf+3Sei5UCnkskn796izA29D0DdCy3ET9oaKRHIJyKbqFl0rv6f516QzOoXKC6N01sXBHBE/ovs0wwDvlaW+gFGPgkzdcfUlyrWLDnLV7LcuQymhTND2uH0oR3wJnNENN/OFgM1KGPPDOe19YsIKdLqARgxrhZVsh06OurEviZTXOBFI5r+yac7haDwOQhLHXNv+Y9MNvxs5QLWPFIM3bNUWfYrJnLrs4hGJS+y/KDM9Si+HL30QAFXy4YNO33J8DHjZ7ddG5n8/FqplOKvRtUgjcKWlxoGY4VdVaDQ==
+ e: AQAB
+ alg: RS256
+ kid: example
+bindings:
+ net0:
+ type: test
+ kind: server
+ options:
+ authorization:
+ jwt0:
+ credentials: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImV4YW1wbGUifQ.eyJhdWQiOiJodHRwczovL2FwaS5leGFtcGxlLmNvbSIsImV4cCI6MTcwODk0MDQ0MCwiaXNzIjoiaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tIiwic3ViIjoidXNlciJ9.KwZt_rDTDEOQ33URwZ8Gd1WqQjAIJESbt5Et309Yz7AJm1wWWyFhWm7AV6lt1rkX-eD-jVh0wHAsy7L4kdzBOErCdwFcdaB4u2jFDGn_9IK28lCedxIYmYtI4qn6eY916IIqRpwZcqzw08OEljfYUKo4UeX7JPAtha0GQmfZY1-NNcncg06xw3xkKSZ1SnIh9MZM1FNH_5QPZPL4NHP7DRXtaMn2w6YpO7n695Sc_3LuSDlfDDMVIUWuEreOzOXem6jheGIbJ-eDKhIXXPrOz1NBAJmvizbugMR7m_bodiEzzqt5ttKDs1974alrR_sYP8OYmR_rCqXc5N3lp_SW3A
+ exit: app0