diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e3e55fa74..dd317720c5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,23 @@
## [Unreleased](https://github.com/aklivity/zilla/tree/HEAD)
-[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.95...HEAD)
+[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.96...HEAD)
+
+**Implemented enhancements:**
+
+- Support `jwt` guarded identity via custom token claim [\#1276](https://github.com/aklivity/zilla/issues/1276)
+- Support `insert into` to seed `kafka` messages via `risingwave` binding [\#1274](https://github.com/aklivity/zilla/issues/1274)
+
+**Merged pull requests:**
+
+- `pgsql` DROP TOPIC command to KafkaDeleteTopicsBeginEx plus catalog unregister subject [\#1280](https://github.com/aklivity/zilla/pull/1280) ([akrambek](https://github.com/akrambek))
+- external udf - python support [\#1278](https://github.com/aklivity/zilla/pull/1278) ([ankitk-me](https://github.com/ankitk-me))
+- Support jwt guarded identity via custom token claim [\#1277](https://github.com/aklivity/zilla/pull/1277) ([akrambek](https://github.com/akrambek))
+- Support insert into to seed kafka messages via risingwave binding [\#1275](https://github.com/aklivity/zilla/pull/1275) ([akrambek](https://github.com/akrambek))
+
+## [0.9.96](https://github.com/aklivity/zilla/tree/0.9.96) (2024-10-01)
+
+[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.95...0.9.96)
**Implemented enhancements:**
diff --git a/build/flyweight-maven-plugin/pom.xml b/build/flyweight-maven-plugin/pom.xml
index 4e51fb4fee..5140899057 100644
--- a/build/flyweight-maven-plugin/pom.xml
+++ b/build/flyweight-maven-plugin/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
build
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/build/pom.xml b/build/pom.xml
index 2d5bf2e334..a4359bad5f 100644
--- a/build/pom.xml
+++ b/build/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/cloud/docker-image/pom.xml b/cloud/docker-image/pom.xml
index 6c3c548e79..a2c2c42c56 100644
--- a/cloud/docker-image/pom.xml
+++ b/cloud/docker-image/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
cloud
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/cloud/helm-chart/pom.xml b/cloud/helm-chart/pom.xml
index 410695b422..115cd8cb0b 100644
--- a/cloud/helm-chart/pom.xml
+++ b/cloud/helm-chart/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
cloud
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/cloud/pom.xml b/cloud/pom.xml
index d599c6d64e..26b086946b 100644
--- a/cloud/pom.xml
+++ b/cloud/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/conf/pom.xml b/conf/pom.xml
index 588f98f17b..5fce2b92a4 100644
--- a/conf/pom.xml
+++ b/conf/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-amqp.spec/pom.xml b/incubator/binding-amqp.spec/pom.xml
index 06b01a3747..afe79e85d9 100644
--- a/incubator/binding-amqp.spec/pom.xml
+++ b/incubator/binding-amqp.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-amqp/pom.xml b/incubator/binding-amqp/pom.xml
index e506f51ec4..6069e0f7ed 100644
--- a/incubator/binding-amqp/pom.xml
+++ b/incubator/binding-amqp/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-pgsql-kafka.spec/pom.xml b/incubator/binding-pgsql-kafka.spec/pom.xml
index 01d0dd98b6..dbf159e5a9 100644
--- a/incubator/binding-pgsql-kafka.spec/pom.xml
+++ b/incubator/binding-pgsql-kafka.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-pgsql-kafka/pom.xml b/incubator/binding-pgsql-kafka/pom.xml
index 4177ed2bba..d2f24cac6d 100644
--- a/incubator/binding-pgsql-kafka/pom.xml
+++ b/incubator/binding-pgsql-kafka/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaCommandType.java b/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaCommandType.java
index 60ca9fd8b7..e7f4f22c7e 100644
--- a/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaCommandType.java
+++ b/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaCommandType.java
@@ -22,6 +22,7 @@
public enum PgsqlKafkaCommandType
{
CREATE_TOPIC_COMMAND("CREATE TOPIC".getBytes()),
+ DROP_TOPIC_COMMAND("DROP TOPIC".getBytes()),
UNKNOWN_COMMAND("UNKNOWN".getBytes());
private final byte[] value;
diff --git a/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaCompletionCommand.java b/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaCompletionCommand.java
index c1d7352a22..085b7ea29a 100644
--- a/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaCompletionCommand.java
+++ b/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaCompletionCommand.java
@@ -17,6 +17,7 @@
public enum PgsqlKafkaCompletionCommand
{
CREATE_TOPIC_COMMAND("CREATE_TOPIC".getBytes()),
+ DROP_TOPIC_COMMAND("DROP_TOPIC".getBytes()),
UNKNOWN_COMMAND("UNKNOWN".getBytes());
private final byte[] value;
diff --git a/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaProxyFactory.java b/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaProxyFactory.java
index d7ca9e8180..6461b89336 100644
--- a/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaProxyFactory.java
+++ b/incubator/binding-pgsql-kafka/src/main/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/PgsqlKafkaProxyFactory.java
@@ -16,6 +16,7 @@
import static io.aklivity.zilla.runtime.engine.buffer.BufferPool.NO_SLOT;
import static io.aklivity.zilla.runtime.engine.catalog.CatalogHandler.NO_VERSION_ID;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import java.io.InputStreamReader;
@@ -64,6 +65,7 @@
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.create.table.CreateTable;
+import net.sf.jsqlparser.statement.drop.Drop;
public final class PgsqlKafkaProxyFactory implements PgsqlKafkaStreamFactory
{
@@ -143,6 +145,7 @@ public final class PgsqlKafkaProxyFactory implements PgsqlKafkaStreamFactory
Object2ObjectHashMap pgsqlDecoder =
new Object2ObjectHashMap<>();
pgsqlDecoder.put(PgsqlKafkaCommandType.CREATE_TOPIC_COMMAND, this::decodeCreateTopicCommand);
+ pgsqlDecoder.put(PgsqlKafkaCommandType.DROP_TOPIC_COMMAND, this::decodeDropTopicCommand);
pgsqlDecoder.put(PgsqlKafkaCommandType.UNKNOWN_COMMAND, this::decodeUnknownCommand);
this.pgsqlDecoder = pgsqlDecoder;
}
@@ -232,6 +235,7 @@ private final class PgsqlProxy
private final String database;
private final PgsqlKafkaBindingConfig binding;
private final KafkaCreateTopicsProxy createTopicsProxy;
+ private final KafkaDeleteTopicsProxy deleteTopicsProxy;
private final IntArrayQueue queries;
@@ -281,6 +285,7 @@ private PgsqlProxy(
this.queries = new IntArrayQueue();
this.createTopicsProxy = new KafkaCreateTopicsProxy(routedId, resolvedId, this);
+ this.deleteTopicsProxy = new KafkaDeleteTopicsProxy(routedId, resolvedId, this);
}
private void onAppMessage(
@@ -488,7 +493,7 @@ private void onCommandCompleted(
doAppWindow(traceId, authorization);
}
- public void onKafkaCreateTopicsBegin(
+ public void onKafkaBegin(
long traceId,
long authorization)
{
@@ -1018,7 +1023,81 @@ protected void onKafkaBegin(
if (!errorExits)
{
- delegate.onKafkaCreateTopicsBegin(traceId, authorization);
+ delegate.onKafkaBegin(traceId, authorization);
+
+ doKafkaWindow(traceId, authorization);
+ doKafkaEnd(traceId, authorization);
+ }
+ else
+ {
+ delegate.cleanup(traceId, authorization);
+ }
+ }
+ }
+
+ private final class KafkaDeleteTopicsProxy extends KafkaProxy
+ {
+ private KafkaDeleteTopicsProxy(
+ long originId,
+ long routedId,
+ PgsqlProxy delegate)
+ {
+ super(originId, routedId, delegate);
+ }
+
+ private void doKafkaBegin(
+ long traceId,
+ long authorization,
+ List topics)
+ {
+ initialSeq = delegate.initialSeq;
+ initialAck = delegate.initialAck;
+ initialMax = delegate.initialMax;
+ state = PgsqlKafkaState.openingInitial(state);
+
+ final KafkaBeginExFW kafkaBeginEx =
+ kafkaBeginExRW.wrap(extBuffer, 0, extBuffer.capacity())
+ .typeId(kafkaTypeId)
+ .request(r -> r
+ .deleteTopics(c -> c
+ .names(ct ->
+ topics.forEach(t -> ct.item(i -> i.set(t, UTF_8))))
+ .timeout(config.kafkaTopicRequestTimeoutMs())))
+ .build();
+
+ kafka = newKafkaConsumer(this::onKafkaMessage, originId, routedId, initialId, initialSeq, initialAck, initialMax,
+ traceId, authorization, 0, kafkaBeginEx);
+ }
+
+ @Override
+ protected void onKafkaBegin(
+ BeginFW begin)
+ {
+ final long sequence = begin.sequence();
+ final long acknowledge = begin.acknowledge();
+ final long traceId = begin.traceId();
+ final long authorization = begin.authorization();
+ final OctetsFW extension = begin.extension();
+
+ assert acknowledge <= sequence;
+ assert sequence >= replySeq;
+ assert acknowledge >= replyAck;
+
+ replySeq = sequence;
+ replyAck = acknowledge;
+ state = PgsqlKafkaState.openingReply(state);
+
+ assert replyAck <= replySeq;
+
+ final ExtensionFW beginEx = extension.get(extensionRO::tryWrap);
+ final KafkaBeginExFW kafkaBeginEx =
+ beginEx != null && beginEx.typeId() == kafkaTypeId ? extension.get(kafkaBeginExRO::tryWrap) : null;
+
+ boolean errorExits = kafkaBeginEx.response().deleteTopics().topics().anyMatch(t -> t.error() != 0);
+
+ if (!errorExits)
+ {
+ delegate.onKafkaBegin(traceId, authorization);
doKafkaWindow(traceId, authorization);
doKafkaEnd(traceId, authorization);
@@ -1292,6 +1371,35 @@ else if (server.commandsProcessed == 0)
}
}
+ private void decodeDropTopicCommand(
+ PgsqlProxy server,
+ long traceId,
+ long authorization,
+ DirectBuffer buffer,
+ int offset,
+ int length)
+ {
+ if (server.commandsProcessed == 1)
+ {
+ server.onCommandCompleted(traceId, authorization, length, PgsqlKafkaCompletionCommand.DROP_TOPIC_COMMAND);
+ }
+ else if (server.commandsProcessed == 0)
+ {
+ final Drop drop = (Drop) parseStatement(buffer, offset, length);
+ final String topic = drop.getName().getName();
+
+ final PgsqlKafkaBindingConfig binding = server.binding;
+ final String subjectKey = String.format("%s.%s-key", server.database, topic);
+ final String subjectValue = String.format("%s.%s-value", server.database, topic);
+
+ binding.catalog.unregister(subjectKey);
+ binding.catalog.unregister(subjectValue);
+
+ final KafkaDeleteTopicsProxy deleteTopicsProxy = server.deleteTopicsProxy;
+ deleteTopicsProxy.doKafkaBegin(traceId, authorization, List.of("%s.%s".formatted(server.database, topic)));
+ }
+ }
+
private void decodeUnknownCommand(
PgsqlProxy server,
long traceId,
@@ -1351,6 +1459,13 @@ private Statement parseStatement(
sql = sql.replace("CREATE TOPIC", "CREATE TABLE");
statement = parserManager.parse(new StringReader(sql));
}
+ if (decodeCommandType(buffer, offset, length).
+ equals(PgsqlKafkaCommandType.DROP_TOPIC_COMMAND))
+ {
+ String sql = buffer.getStringWithoutLengthUtf8(offset, length);
+ sql = sql.replace("DROP TOPIC", "DROP TABLE");
+ statement = parserManager.parse(new StringReader(sql));
+ }
else
{
inputStream.wrap(buffer, offset, length);
diff --git a/incubator/binding-pgsql-kafka/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/ProxyIT.java b/incubator/binding-pgsql-kafka/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/ProxyIT.java
index 58d08cba16..ea24574a15 100644
--- a/incubator/binding-pgsql-kafka/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/ProxyIT.java
+++ b/incubator/binding-pgsql-kafka/src/test/java/io/aklivity/zilla/runtime/binding/pgsql/kafka/internal/stream/ProxyIT.java
@@ -58,4 +58,15 @@ public void shouldCreateTopic() throws Exception
{
k3po.finish();
}
+
+ @Test
+ @Configuration("proxy.yaml")
+ @Specification({
+ "${pgsql}/drop.topic/client",
+ "${kafka}/drop.topic/server"
+ })
+ public void shouldDropTopic() throws Exception
+ {
+ k3po.finish();
+ }
}
diff --git a/incubator/binding-pgsql.spec/pom.xml b/incubator/binding-pgsql.spec/pom.xml
index d69d6e4fbd..157dc07223 100644
--- a/incubator/binding-pgsql.spec/pom.xml
+++ b/incubator/binding-pgsql.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-pgsql/pom.xml b/incubator/binding-pgsql/pom.xml
index bcef9a3453..08d7d298a0 100644
--- a/incubator/binding-pgsql/pom.xml
+++ b/incubator/binding-pgsql/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-risingwave.spec/pom.xml b/incubator/binding-risingwave.spec/pom.xml
index a3a65f9c09..de0d42a726 100644
--- a/incubator/binding-risingwave.spec/pom.xml
+++ b/incubator/binding-risingwave.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/config/proxy.function.yaml b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/config/proxy.function.yaml
index 4eb1dc5d79..1abafe32f1 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/config/proxy.function.yaml
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/config/proxy.function.yaml
@@ -22,4 +22,6 @@ bindings:
options:
udf:
- server: http://localhost:8815
+ - server: http://localhost:8816
+ language: python
exit: app1
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/schema/risingwave.schema.patch.json b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/schema/risingwave.schema.patch.json
index 1a58ec38b4..3b01fea130 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/schema/risingwave.schema.patch.json
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/schema/risingwave.schema.patch.json
@@ -80,13 +80,16 @@
"title": "Language",
"type": "string",
"default": "java",
- "const": "java"
+ "enum":
+ [
+ "java",
+ "python"
+ ]
}
},
"additionalProperties": false
},
- "minItems": 1,
- "maxItems": 1
+ "minItems": 1
}
},
"additionalProperties": false
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.embedded.python/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.embedded.python/client.rpt
new file mode 100644
index 0000000000..2c278d588e
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.embedded.python/client.rpt
@@ -0,0 +1,58 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+connect "zilla://streams/app1"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+write zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE FUNCTION gcd(a int, b int) RETURNS int LANGUAGE python AS $$\n"
+ "def gcd(a, b):\n"
+ " while b != 0:\n"
+ " a, b = b, a % b\n"
+ " return a\n"
+ "$$;"
+ [0x00]
+
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.embedded.python/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.embedded.python/server.rpt
new file mode 100644
index 0000000000..9d99f91c94
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.embedded.python/server.rpt
@@ -0,0 +1,58 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+accept "zilla://streams/app1"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+accepted
+
+read zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE FUNCTION gcd(a int, b int) RETURNS int LANGUAGE python AS $$\n"
+ "def gcd(a, b):\n"
+ " while b != 0:\n"
+ " a, b = b, a % b\n"
+ " return a\n"
+ "$$;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.python/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.python/client.rpt
new file mode 100644
index 0000000000..33ee75c8cb
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.python/client.rpt
@@ -0,0 +1,57 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+connect "zilla://streams/app1"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+write zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE FUNCTION gcd(int , int)\n"
+ "RETURNS int\n"
+ "AS gcd\n"
+ "LANGUAGE python\n"
+ "USING LINK 'http://localhost:8816';"
+ [0x00]
+
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.python/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.python/server.rpt
new file mode 100644
index 0000000000..7bda0b7335
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.python/server.rpt
@@ -0,0 +1,57 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+accept "zilla://streams/app1"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+accepted
+
+read zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE FUNCTION gcd(int , int)\n"
+ "RETURNS int\n"
+ "AS gcd\n"
+ "LANGUAGE python\n"
+ "USING LINK 'http://localhost:8816';"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.struct/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.struct/client.rpt
new file mode 100644
index 0000000000..6c81524818
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.struct/client.rpt
@@ -0,0 +1,57 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+connect "zilla://streams/app1"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+write zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE FUNCTION key_value(bytea)\n"
+ "RETURNS struct < key varchar , value varchar >\n"
+ "AS key_value\n"
+ "LANGUAGE python\n"
+ "USING LINK 'http://localhost:8816';"
+ [0x00]
+
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.struct/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.struct/server.rpt
new file mode 100644
index 0000000000..23335bb651
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.struct/server.rpt
@@ -0,0 +1,57 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+accept "zilla://streams/app1"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+accepted
+
+read zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE FUNCTION key_value(bytea)\n"
+ "RETURNS struct < key varchar , value varchar >\n"
+ "AS key_value\n"
+ "LANGUAGE python\n"
+ "USING LINK 'http://localhost:8816';"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.table/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.table/client.rpt
index e07f659466..ebcab805e4 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.table/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.table/client.rpt
@@ -33,7 +33,7 @@ write zilla:data.ext ${pgsql:dataEx()
.build()
.build()}
write "CREATE FUNCTION series(int)\n"
- "RETURNS TABLE (x int)\n"
+ "RETURNS TABLE ( x int )\n"
"AS series\n"
"LANGUAGE java\n"
"USING LINK 'http://localhost:8815';"
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.table/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.table/server.rpt
index 885d785192..ec7a49322a 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.table/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.function.return.table/server.rpt
@@ -35,7 +35,7 @@ read zilla:data.ext ${pgsql:dataEx()
.build()
.build()}
read "CREATE FUNCTION series(int)\n"
- "RETURNS TABLE (x int)\n"
+ "RETURNS TABLE ( x int )\n"
"AS series\n"
"LANGUAGE java\n"
"USING LINK 'http://localhost:8815';"
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.includes/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream.with.includes/client.rpt
similarity index 98%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.includes/client.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream.with.includes/client.rpt
index 10aa0d39ab..679a78508e 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.includes/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream.with.includes/client.rpt
@@ -34,8 +34,8 @@ write zilla:data.ext ${pgsql:dataEx()
.build()}
write "CREATE SOURCE IF NOT EXISTS weather (*)\n"
"INCLUDE header 'zilla:correlation-id' AS correlation_id\n"
+ "INCLUDE header 'zilla:identity' AS identity\n"
"INCLUDE timestamp AS timestamp\n"
- "INCLUDE header 'zilla:identity' AS owner_id\n"
"WITH (\n"
" connector='kafka',\n"
" properties.bootstrap.server='localhost:9092',\n"
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.includes/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream.with.includes/server.rpt
similarity index 98%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.includes/server.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream.with.includes/server.rpt
index ff8e4dec8c..9871eea900 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.includes/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream.with.includes/server.rpt
@@ -38,8 +38,8 @@ read zilla:data.ext ${pgsql:dataEx()
.build()}
read "CREATE SOURCE IF NOT EXISTS weather (*)\n"
"INCLUDE header 'zilla:correlation-id' AS correlation_id\n"
+ "INCLUDE header 'zilla:identity' AS identity\n"
"INCLUDE timestamp AS timestamp\n"
- "INCLUDE header 'zilla:identity' AS owner_id\n"
"WITH (\n"
" connector='kafka',\n"
" properties.bootstrap.server='localhost:9092',\n"
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream/client.rpt
similarity index 100%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table/client.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream/client.rpt
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream/server.rpt
similarity index 100%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table/server.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.stream/server.rpt
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.tables/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.streams/client.rpt
similarity index 100%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.tables/client.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.streams/client.rpt
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.tables/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.streams/server.rpt
similarity index 100%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.tables/server.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.streams/server.rpt
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key.and.includes/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key.and.includes/client.rpt
index f9451bc7bb..7c587a897b 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key.and.includes/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key.and.includes/client.rpt
@@ -32,14 +32,10 @@ write zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-write "CREATE TABLE IF NOT EXISTS cities (\n"
- " *,\n"
- " PRIMARY KEY (id)\n"
- ")\n"
- "INCLUDE KEY AS key\n"
- "INCLUDE header 'zilla:correlation-id' AS correlation_id\n"
+write "CREATE SOURCE IF NOT EXISTS cities_source (*)\n"
+ "INCLUDE header 'zilla:correlation-id' AS zilla_correlation_id_header\n"
+ "INCLUDE header 'zilla:identity' AS zilla_identity_header\n"
"INCLUDE timestamp AS timestamp\n"
- "INCLUDE header 'zilla:identity' AS owner_id\n"
"WITH (\n"
" connector='kafka',\n"
" properties.bootstrap.server='localhost:9092',\n"
@@ -50,7 +46,60 @@ write "CREATE TABLE IF NOT EXISTS cities (\n"
" schema.registry = 'http://localhost:8081'\n"
");"
[0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SOURCE")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE MATERIALIZED VIEW IF NOT EXISTS cities_view AS"
+ " SELECT id, name, description,"
+ " COALESCE(correlation_id, zilla_correlation_id_header::varchar) as correlation_id,"
+ " COALESCE(identity, zilla_identity_header::varchar) as identity,"
+ " timestamp"
+ " FROM cities_source;"
+ [0x00]
+write flush
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_MATERIALIZED_VIEW")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE TABLE IF NOT EXISTS cities"
+ " (id VARCHAR, name VARCHAR, description VARCHAR,"
+ " correlation_id VARCHAR, identity VARCHAR, timestamp TIMESTAMP,"
+ " PRIMARY KEY (id));"
+ [0x00]
write flush
read advised zilla:flush ${pgsql:flushEx()
@@ -67,12 +116,65 @@ read advised zilla:flush ${pgsql:flushEx()
.build()
.build()}
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE SINK cities_view_sink INTO cities FROM cities_view;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE SINK cities_sink\n"
+ "FROM cities\n"
+ "WITH (\n"
+ " connector='kafka',\n"
+ " properties.bootstrap.server='localhost:9092',\n"
+ " topic='dev.cities',\n"
+ " primary_key='id'\n"
+ ") FORMAT UPSERT ENCODE AVRO (\n"
+ " schema.registry='http://localhost:8081'\n"
+ ") KEY ENCODE TEXT;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
connect "zilla://streams/app2"
option zilla:window 8192
option zilla:transmission "duplex"
-
write zilla:begin.ext ${pgsql:beginEx()
.typeId(zilla:id("pgsql"))
.parameter("user", "root")
@@ -89,7 +191,9 @@ write zilla:data.ext ${pgsql:dataEx()
.build()
.build()}
write "CREATE TOPIC IF NOT EXISTS cities "
- "(id VARCHAR, name VARCHAR, description VARCHAR, PRIMARY KEY (id));"
+ "(id VARCHAR, name VARCHAR, description VARCHAR,"
+ " correlation_id VARCHAR, identity VARCHAR, timestamp TIMESTAMP,"
+ " PRIMARY KEY (id));"
[0x00]
write flush
@@ -106,4 +210,3 @@ read advised zilla:flush ${pgsql:flushEx()
.status("IDLE")
.build()
.build()}
-
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key.and.includes/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key.and.includes/server.rpt
index 189026d000..4bc34b76a3 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key.and.includes/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key.and.includes/server.rpt
@@ -36,29 +36,130 @@ read zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-read "CREATE TABLE IF NOT EXISTS cities (\n"
- " *,\n"
- " PRIMARY KEY (id)\n"
- ")\n"
- "INCLUDE KEY AS key\n"
- "INCLUDE header 'zilla:correlation-id' AS correlation_id\n"
- "INCLUDE timestamp AS timestamp\n"
- "INCLUDE header 'zilla:identity' AS owner_id\n"
+read "CREATE SOURCE IF NOT EXISTS cities_source (*)\n"
+ "INCLUDE header 'zilla:correlation-id' AS zilla_correlation_id_header\n"
+ "INCLUDE header 'zilla:identity' AS zilla_identity_header\n"
+ "INCLUDE timestamp AS timestamp\n"
+ "WITH (\n"
+ " connector='kafka',\n"
+ " properties.bootstrap.server='localhost:9092',\n"
+ " topic='dev.cities',\n"
+ " scan.startup.mode='latest',\n"
+ " scan.startup.timestamp.millis='140000000'\n"
+ ") FORMAT PLAIN ENCODE AVRO (\n"
+ " schema.registry = 'http://localhost:8081'\n"
+ ");"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SOURCE")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE MATERIALIZED VIEW IF NOT EXISTS cities_view AS"
+ " SELECT id, name, description,"
+ " COALESCE(correlation_id, zilla_correlation_id_header::varchar) as correlation_id,"
+ " COALESCE(identity, zilla_identity_header::varchar) as identity,"
+ " timestamp"
+ " FROM cities_source;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_MATERIALIZED_VIEW")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE TABLE IF NOT EXISTS cities"
+ " (id VARCHAR, name VARCHAR, description VARCHAR,"
+ " correlation_id VARCHAR, identity VARCHAR, timestamp TIMESTAMP,"
+ " PRIMARY KEY (id));"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_TABLE")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE SINK cities_view_sink INTO cities FROM cities_view;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE SINK cities_sink\n"
+ "FROM cities\n"
"WITH (\n"
" connector='kafka',\n"
" properties.bootstrap.server='localhost:9092',\n"
" topic='dev.cities',\n"
- " scan.startup.mode='latest',\n"
- " scan.startup.timestamp.millis='140000000'\n"
- ") FORMAT PLAIN ENCODE AVRO (\n"
- " schema.registry = 'http://localhost:8081'\n"
- ");"
+ " primary_key='id'\n"
+ ") FORMAT UPSERT ENCODE AVRO (\n"
+ " schema.registry='http://localhost:8081'\n"
+ ") KEY ENCODE TEXT;"
[0x00]
write advise zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_SINK")
.build()
.build()}
@@ -91,7 +192,9 @@ read zilla:data.ext ${pgsql:dataEx()
.build()
.build()}
read "CREATE TOPIC IF NOT EXISTS cities "
- "(id VARCHAR, name VARCHAR, description VARCHAR, PRIMARY KEY (id));"
+ "(id VARCHAR, name VARCHAR, description VARCHAR,"
+ " correlation_id VARCHAR, identity VARCHAR, timestamp TIMESTAMP,"
+ " PRIMARY KEY (id));"
[0x00]
write advise zilla:flush ${pgsql:flushEx()
@@ -109,5 +212,3 @@ write advise zilla:flush ${pgsql:flushEx()
.status("IDLE")
.build()
.build()}
-
-
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key/client.rpt
index be60e5fe79..b5829feab7 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key/client.rpt
@@ -32,11 +32,7 @@ write zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-write "CREATE TABLE IF NOT EXISTS cities (\n"
- " *,\n"
- " PRIMARY KEY (id)\n"
- ")\n"
- "INCLUDE KEY AS key\n"
+write "CREATE SOURCE IF NOT EXISTS cities_source (*)\n"
"WITH (\n"
" connector='kafka',\n"
" properties.bootstrap.server='localhost:9092',\n"
@@ -47,7 +43,53 @@ write "CREATE TABLE IF NOT EXISTS cities (\n"
" schema.registry = 'http://localhost:8081'\n"
");"
[0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SOURCE")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE MATERIALIZED VIEW IF NOT EXISTS cities_view AS SELECT * FROM cities_source;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_MATERIALIZED_VIEW")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE TABLE IF NOT EXISTS cities "
+ "(id VARCHAR, name VARCHAR, description VARCHAR, PRIMARY KEY (id));"
+ [0x00]
write flush
read advised zilla:flush ${pgsql:flushEx()
@@ -64,12 +106,65 @@ read advised zilla:flush ${pgsql:flushEx()
.build()
.build()}
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE SINK cities_view_sink INTO cities FROM cities_view;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE SINK cities_sink\n"
+ "FROM cities\n"
+ "WITH (\n"
+ " connector='kafka',\n"
+ " properties.bootstrap.server='localhost:9092',\n"
+ " topic='dev.cities',\n"
+ " primary_key='id'\n"
+ ") FORMAT UPSERT ENCODE AVRO (\n"
+ " schema.registry='http://localhost:8081'\n"
+ ") KEY ENCODE TEXT;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
connect "zilla://streams/app2"
option zilla:window 8192
option zilla:transmission "duplex"
-
write zilla:begin.ext ${pgsql:beginEx()
.typeId(zilla:id("pgsql"))
.parameter("user", "root")
@@ -103,4 +198,3 @@ read advised zilla:flush ${pgsql:flushEx()
.status("IDLE")
.build()
.build()}
-
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key/server.rpt
index 8d2121373d..11d987ffc1 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/create.table.with.primary.key/server.rpt
@@ -36,20 +36,61 @@ read zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-read "CREATE TABLE IF NOT EXISTS cities (\n"
- " *,\n"
- " PRIMARY KEY (id)\n"
- ")\n"
- "INCLUDE KEY AS key\n"
- "WITH (\n"
- " connector='kafka',\n"
- " properties.bootstrap.server='localhost:9092',\n"
- " topic='dev.cities',\n"
- " scan.startup.mode='latest',\n"
- " scan.startup.timestamp.millis='140000000'\n"
- ") FORMAT PLAIN ENCODE AVRO (\n"
- " schema.registry = 'http://localhost:8081'\n"
- ");"
+read "CREATE SOURCE IF NOT EXISTS cities_source (*)\n"
+ "WITH (\n"
+ " connector='kafka',\n"
+ " properties.bootstrap.server='localhost:9092',\n"
+ " topic='dev.cities',\n"
+ " scan.startup.mode='latest',\n"
+ " scan.startup.timestamp.millis='140000000'\n"
+ ") FORMAT PLAIN ENCODE AVRO (\n"
+ " schema.registry = 'http://localhost:8081'\n"
+ ");"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SOURCE")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE MATERIALIZED VIEW IF NOT EXISTS cities_view AS SELECT * FROM cities_source;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_MATERIALIZED_VIEW")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE TABLE IF NOT EXISTS cities "
+ "(id VARCHAR, name VARCHAR, description VARCHAR, PRIMARY KEY (id));"
[0x00]
write advise zilla:flush ${pgsql:flushEx()
@@ -66,6 +107,59 @@ write advise zilla:flush ${pgsql:flushEx()
.build()
.build()}
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE SINK cities_view_sink INTO cities FROM cities_view;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE SINK cities_sink\n"
+ "FROM cities\n"
+ "WITH (\n"
+ " connector='kafka',\n"
+ " properties.bootstrap.server='localhost:9092',\n"
+ " topic='dev.cities',\n"
+ " primary_key='id'\n"
+ ") FORMAT UPSERT ENCODE AVRO (\n"
+ " schema.registry='http://localhost:8081'\n"
+ ") KEY ENCODE TEXT;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
accept "zilla://streams/app2"
option zilla:window 8192
option zilla:transmission "duplex"
@@ -106,5 +200,3 @@ write advise zilla:flush ${pgsql:flushEx()
.status("IDLE")
.build()
.build()}
-
-
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/query.with.multiple.statements/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/query.with.multiple.statements/client.rpt
index ab484b7434..98a4b465ce 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/query.with.multiple.statements/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/query.with.multiple.statements/client.rpt
@@ -32,11 +32,7 @@ write zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-write "CREATE TABLE IF NOT EXISTS cities (\n"
- " *,\n"
- " PRIMARY KEY (id)\n"
- ")\n"
- "INCLUDE KEY AS key\n"
+write "CREATE SOURCE IF NOT EXISTS cities_source (*)\n"
"WITH (\n"
" connector='kafka',\n"
" properties.bootstrap.server='localhost:9092',\n"
@@ -49,6 +45,53 @@ write "CREATE TABLE IF NOT EXISTS cities (\n"
[0x00]
write flush
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SOURCE")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE MATERIALIZED VIEW IF NOT EXISTS cities_view AS SELECT * FROM cities_source;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_MATERIALIZED_VIEW")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE TABLE IF NOT EXISTS cities "
+ "(id VARCHAR, name VARCHAR, description VARCHAR, PRIMARY KEY (id));"
+ [0x00]
+write flush
+
read advised zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
@@ -63,6 +106,61 @@ read advised zilla:flush ${pgsql:flushEx()
.build()
.build()}
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE SINK cities_view_sink INTO cities FROM cities_view;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE SINK cities_sink\n"
+ "FROM cities\n"
+ "WITH (\n"
+ " connector='kafka',\n"
+ " properties.bootstrap.server='localhost:9092',\n"
+ " topic='dev.cities',\n"
+ " primary_key='id'\n"
+ ") FORMAT UPSERT ENCODE AVRO (\n"
+ " schema.registry='http://localhost:8081'\n"
+ ") KEY ENCODE TEXT;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
write zilla:data.ext ${pgsql:dataEx()
.typeId(zilla:id("pgsql"))
.query()
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/query.with.multiple.statements/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/query.with.multiple.statements/server.rpt
index 39350568c4..b3378e42e4 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/query.with.multiple.statements/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/effective/query.with.multiple.statements/server.rpt
@@ -36,20 +36,61 @@ read zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-read "CREATE TABLE IF NOT EXISTS cities (\n"
- " *,\n"
- " PRIMARY KEY (id)\n"
- ")\n"
- "INCLUDE KEY AS key\n"
- "WITH (\n"
- " connector='kafka',\n"
- " properties.bootstrap.server='localhost:9092',\n"
- " topic='dev.cities',\n"
- " scan.startup.mode='latest',\n"
- " scan.startup.timestamp.millis='140000000'\n"
- ") FORMAT PLAIN ENCODE AVRO (\n"
- " schema.registry = 'http://localhost:8081'\n"
- ");"
+read "CREATE SOURCE IF NOT EXISTS cities_source (*)\n"
+ "WITH (\n"
+ " connector='kafka',\n"
+ " properties.bootstrap.server='localhost:9092',\n"
+ " topic='dev.cities',\n"
+ " scan.startup.mode='latest',\n"
+ " scan.startup.timestamp.millis='140000000'\n"
+ ") FORMAT PLAIN ENCODE AVRO (\n"
+ " schema.registry = 'http://localhost:8081'\n"
+ ");"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SOURCE")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE MATERIALIZED VIEW IF NOT EXISTS cities_view AS SELECT * FROM cities_source;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_MATERIALIZED_VIEW")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE TABLE IF NOT EXISTS cities "
+ "(id VARCHAR, name VARCHAR, description VARCHAR, PRIMARY KEY (id));"
[0x00]
write advise zilla:flush ${pgsql:flushEx()
@@ -66,6 +107,59 @@ write advise zilla:flush ${pgsql:flushEx()
.build()
.build()}
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE SINK cities_view_sink INTO cities FROM cities_view;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE SINK cities_sink\n"
+ "FROM cities\n"
+ "WITH (\n"
+ " connector='kafka',\n"
+ " properties.bootstrap.server='localhost:9092',\n"
+ " topic='dev.cities',\n"
+ " primary_key='id'\n"
+ ") FORMAT UPSERT ENCODE AVRO (\n"
+ " schema.registry='http://localhost:8081'\n"
+ ") KEY ENCODE TEXT;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_SINK")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
read zilla:data.ext ${pgsql:dataEx()
.typeId(zilla:id("pgsql"))
.query()
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.embedded.python/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.embedded.python/client.rpt
new file mode 100644
index 0000000000..2d2c2095f1
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.embedded.python/client.rpt
@@ -0,0 +1,57 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+connect "zilla://streams/app0"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+write zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE FUNCTION gcd(a int, b int) RETURNS int LANGUAGE python AS $$\n"
+ "def gcd(a, b):\n"
+ " while b != 0:\n"
+ " a, b = b, a % b\n"
+ " return a\n"
+ "$$;"
+ [0x00]
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.embedded.python/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.embedded.python/server.rpt
new file mode 100644
index 0000000000..4db9600a78
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.embedded.python/server.rpt
@@ -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.
+#
+
+property serverAddress "zilla://streams/app0"
+
+accept ${serverAddress}
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+accepted
+
+read zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE FUNCTION gcd(a int, b int) RETURNS int LANGUAGE python AS $$\n"
+ "def gcd(a, b):\n"
+ " while b != 0:\n"
+ " a, b = b, a % b\n"
+ " return a\n"
+ "$$;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.python/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.python/client.rpt
new file mode 100644
index 0000000000..340e999227
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.python/client.rpt
@@ -0,0 +1,54 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+connect "zilla://streams/app0"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+write zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE FUNCTION gcd(int, int) RETURNS int "
+ "LANGUAGE python AS gcd;"
+ [0x00]
+
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.python/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.python/server.rpt
new file mode 100644
index 0000000000..20e83d8382
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.python/server.rpt
@@ -0,0 +1,55 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+property serverAddress "zilla://streams/app0"
+
+accept ${serverAddress}
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+accepted
+
+read zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE FUNCTION gcd(int, int) RETURNS int "
+ "LANGUAGE python AS gcd;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.return.struct/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.return.struct/client.rpt
new file mode 100644
index 0000000000..bf1030e822
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.return.struct/client.rpt
@@ -0,0 +1,54 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+connect "zilla://streams/app0"
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+write zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+write zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+write "CREATE FUNCTION key_value(bytea) RETURNS struct "
+ "LANGUAGE python AS key_value;"
+ [0x00]
+
+write flush
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+read advised zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
+
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.return.struct/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.return.struct/server.rpt
new file mode 100644
index 0000000000..05a9d55584
--- /dev/null
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.function.return.struct/server.rpt
@@ -0,0 +1,55 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+property serverAddress "zilla://streams/app0"
+
+accept ${serverAddress}
+ option zilla:window 8192
+ option zilla:transmission "duplex"
+
+accepted
+
+read zilla:begin.ext ${pgsql:beginEx()
+ .typeId(zilla:id("pgsql"))
+ .parameter("user", "root")
+ .parameter("database", "dev")
+ .parameter("application_name", "psql")
+ .parameter("client_encoding", "UTF8")
+ .build()}
+
+connected
+
+read zilla:data.ext ${pgsql:dataEx()
+ .typeId(zilla:id("pgsql"))
+ .query()
+ .build()
+ .build()}
+read "CREATE FUNCTION key_value(bytea) RETURNS struct "
+ "LANGUAGE python AS key_value;"
+ [0x00]
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .completion()
+ .tag("CREATE_FUNCTION")
+ .build()
+ .build()}
+
+write advise zilla:flush ${pgsql:flushEx()
+ .typeId(zilla:id("pgsql"))
+ .ready()
+ .status("IDLE")
+ .build()
+ .build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.includes/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream.with.includes/client.rpt
similarity index 93%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.includes/client.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream.with.includes/client.rpt
index 7529d60a4b..dbb1c245b7 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.includes/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream.with.includes/client.rpt
@@ -32,10 +32,10 @@ write zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-write "CREATE TABLE IF NOT EXISTS weather "
+write "CREATE STREAM IF NOT EXISTS weather "
"(city VARCHAR, temperature DOUBLE, date DATE)\n"
"INCLUDE zilla_correlation_id AS correlation_id\n"
- "INCLUDE zilla_identity AS owner_id\n"
+ "INCLUDE zilla_identity AS identity\n"
"INCLUDE timestamp as timestamp;"
[0x00]
@@ -44,7 +44,7 @@ write flush
read advised zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_STREAM")
.build()
.build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.includes/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream.with.includes/server.rpt
similarity index 93%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.includes/server.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream.with.includes/server.rpt
index bf70fb8462..19833142cf 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.includes/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream.with.includes/server.rpt
@@ -36,17 +36,17 @@ read zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-read "CREATE TABLE IF NOT EXISTS weather "
+read "CREATE STREAM IF NOT EXISTS weather "
"(city VARCHAR, temperature DOUBLE, date DATE)\n"
"INCLUDE zilla_correlation_id AS correlation_id\n"
- "INCLUDE zilla_identity AS owner_id\n"
+ "INCLUDE zilla_identity AS identity\n"
"INCLUDE timestamp as timestamp;"
[0x00]
write advise zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_STREAM")
.build()
.build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream/client.rpt
similarity index 94%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table/client.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream/client.rpt
index f13127bff9..245b79577a 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream/client.rpt
@@ -32,7 +32,7 @@ write zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-write "CREATE TABLE IF NOT EXISTS weather "
+write "CREATE STREAM IF NOT EXISTS weather "
"(city VARCHAR, temperature DOUBLE, date DATE);"
[0x00]
@@ -41,7 +41,7 @@ write flush
read advised zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_STREAM")
.build()
.build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream/server.rpt
similarity index 95%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table/server.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream/server.rpt
index 2e2cc77ca9..45dc55a0b7 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.stream/server.rpt
@@ -36,14 +36,14 @@ read zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-read "CREATE TABLE IF NOT EXISTS weather "
+read "CREATE STREAM IF NOT EXISTS weather "
"(city VARCHAR, temperature DOUBLE, date DATE);"
[0x00]
write advise zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_STREAM")
.build()
.build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.tables/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.streams/client.rpt
similarity index 92%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.tables/client.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.streams/client.rpt
index be9c1b188e..044b7660a5 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.tables/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.streams/client.rpt
@@ -32,7 +32,7 @@ write zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-write "CREATE TABLE IF NOT EXISTS weather_c "
+write "CREATE STREAM IF NOT EXISTS weather_c "
"(city VARCHAR, temperature DOUBLE, date DATE);"
[0x00]
@@ -41,7 +41,7 @@ write flush
read advised zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_STREAM")
.build()
.build()}
@@ -57,7 +57,7 @@ write zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-write "CREATE TABLE IF NOT EXISTS weather_f "
+write "CREATE STREAM IF NOT EXISTS weather_f "
"(city VARCHAR, temperature DOUBLE, date DATE);"
[0x00]
@@ -66,7 +66,7 @@ write flush
read advised zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_STREAM")
.build()
.build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.tables/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.streams/server.rpt
similarity index 92%
rename from incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.tables/server.rpt
rename to incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.streams/server.rpt
index 8ec0dc1570..f852dbdb84 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.tables/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.streams/server.rpt
@@ -36,14 +36,14 @@ read zilla:data.ext ${pgsql:dataEx()
.query()
.build()
.build()}
-read "CREATE TABLE IF NOT EXISTS weather_c "
+read "CREATE STREAM IF NOT EXISTS weather_c "
"(city VARCHAR, temperature DOUBLE, date DATE);"
[0x00]
write advise zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_STREAM")
.build()
.build()}
@@ -54,14 +54,14 @@ write advise zilla:flush ${pgsql:flushEx()
.build()
.build()}
-read "CREATE TABLE IF NOT EXISTS weather_f "
+read "CREATE STREAM IF NOT EXISTS weather_f "
"(city VARCHAR, temperature DOUBLE, date DATE);"
[0x00]
write advise zilla:flush ${pgsql:flushEx()
.typeId(zilla:id("pgsql"))
.completion()
- .tag("CREATE_TABLE")
+ .tag("CREATE_STREAM")
.build()
.build()}
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.primary.key.and.includes/client.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.primary.key.and.includes/client.rpt
index d7aab69d57..f40e1041f9 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.primary.key.and.includes/client.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.primary.key.and.includes/client.rpt
@@ -35,7 +35,7 @@ write zilla:data.ext ${pgsql:dataEx()
write "CREATE TABLE IF NOT EXISTS cities "
"(id VARCHAR, name VARCHAR, description VARCHAR, PRIMARY KEY (id))\n"
"INCLUDE zilla_correlation_id AS correlation_id\n"
- "INCLUDE zilla_identity AS owner_id\n"
+ "INCLUDE zilla_identity AS identity\n"
"INCLUDE timestamp as timestamp;"
[0x00]
diff --git a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.primary.key.and.includes/server.rpt b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.primary.key.and.includes/server.rpt
index 1b3abad6af..ed5fda502c 100644
--- a/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.primary.key.and.includes/server.rpt
+++ b/incubator/binding-risingwave.spec/src/main/scripts/io/aklivity/zilla/specs/binding/risingwave/streams/pgsql/create.table.with.primary.key.and.includes/server.rpt
@@ -39,7 +39,7 @@ read zilla:data.ext ${pgsql:dataEx()
read "CREATE TABLE IF NOT EXISTS cities "
"(id VARCHAR, name VARCHAR, description VARCHAR, PRIMARY KEY (id))\n"
"INCLUDE zilla_correlation_id AS correlation_id\n"
- "INCLUDE zilla_identity AS owner_id\n"
+ "INCLUDE zilla_identity AS identity\n"
"INCLUDE timestamp as timestamp;"
[0x00]
diff --git a/incubator/binding-risingwave.spec/src/test/java/io/aklivity/zilla/specs/binding/risingwave/streams/EffectiveIT.java b/incubator/binding-risingwave.spec/src/test/java/io/aklivity/zilla/specs/binding/risingwave/streams/EffectiveIT.java
index d1b671d511..96cd3a4e70 100644
--- a/incubator/binding-risingwave.spec/src/test/java/io/aklivity/zilla/specs/binding/risingwave/streams/EffectiveIT.java
+++ b/incubator/binding-risingwave.spec/src/test/java/io/aklivity/zilla/specs/binding/risingwave/streams/EffectiveIT.java
@@ -48,10 +48,10 @@ public void shouldCreateTableWithPrimaryKey() throws Exception
@Test
@Specification({
- "${app}/create.table/client",
- "${app}/create.table/server"
+ "${app}/create.stream/client",
+ "${app}/create.stream/server"
})
- public void shouldCreateTable() throws Exception
+ public void shouldCreateStream() throws Exception
{
k3po.finish();
}
@@ -86,6 +86,35 @@ public void shouldCreateFunction() throws Exception
k3po.finish();
}
+ @Test
+ @Specification({
+ "${app}/create.function.python/client",
+ "${app}/create.function.python/server"
+ })
+ public void shouldCreateFunctionPython() throws Exception
+ {
+ k3po.finish();
+ }
+
+ @Test
+ @Specification({
+ "${app}/create.function.embedded.python/client",
+ "${app}/create.function.embedded.python/server" })
+ public void shouldCreateFunctionEmbeddedPython() throws Exception
+ {
+ k3po.finish();
+ }
+
+ @Test
+ @Specification({
+ "${app}/create.function.return.struct/client",
+ "${app}/create.function.return.struct/server"
+ })
+ public void shouldCreateFunctionReturnStruct() throws Exception
+ {
+ k3po.finish();
+ }
+
@Test
@Specification({
"${app}/create.function.return.table/client",
@@ -107,9 +136,9 @@ public void shouldCreateFunctionEmbedded() throws Exception
@Test
@Specification({
- "${app}/create.table.with.includes/client",
- "${app}/create.table.with.includes/server" })
- public void shouldCreateTableWithIncludes() throws Exception
+ "${app}/create.stream.with.includes/client",
+ "${app}/create.stream.with.includes/server" })
+ public void shouldCreateStreamWithIncludes() throws Exception
{
k3po.finish();
}
@@ -134,9 +163,9 @@ public void shouldShowTablesWithNewline() throws Exception
@Test
@Specification({
- "${app}/create.tables/client",
- "${app}/create.tables/server" })
- public void shouldCreateTables() throws Exception
+ "${app}/create.streams/client",
+ "${app}/create.streams/server" })
+ public void shouldCreateStreams() throws Exception
{
k3po.finish();
}
diff --git a/incubator/binding-risingwave.spec/src/test/java/io/aklivity/zilla/specs/binding/risingwave/streams/PgsqlIT.java b/incubator/binding-risingwave.spec/src/test/java/io/aklivity/zilla/specs/binding/risingwave/streams/PgsqlIT.java
index 7227533b33..da1f54436f 100644
--- a/incubator/binding-risingwave.spec/src/test/java/io/aklivity/zilla/specs/binding/risingwave/streams/PgsqlIT.java
+++ b/incubator/binding-risingwave.spec/src/test/java/io/aklivity/zilla/specs/binding/risingwave/streams/PgsqlIT.java
@@ -48,10 +48,10 @@ public void shouldCreateTableWithPrimaryKey() throws Exception
@Test
@Specification({
- "${app}/create.table/client",
- "${app}/create.table/server"
+ "${app}/create.stream/client",
+ "${app}/create.stream/server"
})
- public void shouldCreateTable() throws Exception
+ public void shouldCreateStream() throws Exception
{
k3po.finish();
}
@@ -86,6 +86,35 @@ public void shouldCreateFunction() throws Exception
k3po.finish();
}
+ @Test
+ @Specification({
+ "${app}/create.function.python/client",
+ "${app}/create.function.python/server"
+ })
+ public void shouldCreateFunctionPython() throws Exception
+ {
+ k3po.finish();
+ }
+
+ @Test
+ @Specification({
+ "${app}/create.function.embedded.python/client",
+ "${app}/create.function.embedded.python/server" })
+ public void shouldCreateFunctionEmbeddedPython() throws Exception
+ {
+ k3po.finish();
+ }
+
+ @Test
+ @Specification({
+ "${app}/create.function.return.struct/client",
+ "${app}/create.function.return.struct/server"
+ })
+ public void shouldCreateFunctionReturnStruct() throws Exception
+ {
+ k3po.finish();
+ }
+
@Test
@Specification({
"${app}/create.function.return.table/client",
@@ -107,9 +136,9 @@ public void shouldCreateFunctionEmbedded() throws Exception
@Test
@Specification({
- "${app}/create.table.with.includes/client",
- "${app}/create.table.with.includes/server" })
- public void shouldCreateTableWithIncludes() throws Exception
+ "${app}/create.stream.with.includes/client",
+ "${app}/create.stream.with.includes/server" })
+ public void shouldCreateStreamWithIncludes() throws Exception
{
k3po.finish();
}
@@ -134,8 +163,8 @@ public void shouldShowTablesWithNewline() throws Exception
@Test
@Specification({
- "${app}/create.tables/client",
- "${app}/create.tables/server" })
+ "${app}/create.streams/client",
+ "${app}/create.streams/server" })
public void shouldCreateTables() throws Exception
{
k3po.finish();
diff --git a/incubator/binding-risingwave/pom.xml b/incubator/binding-risingwave/pom.xml
index ce688c194e..56beda2030 100644
--- a/incubator/binding-risingwave/pom.xml
+++ b/incubator/binding-risingwave/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/config/RisingwaveBindingConfig.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/config/RisingwaveBindingConfig.java
index 602e124808..43b23bba31 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/config/RisingwaveBindingConfig.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/config/RisingwaveBindingConfig.java
@@ -76,20 +76,14 @@ public RisingwaveBindingConfig(
location = catalogHandler.location();
}
- if (options.udfs != null)
- {
- udf = options.udfs.get(0);
- }
-
- this.createTable = new RisingwaveCreateTableTemplate(bootstrapServer,
- location, config.kafkaScanStartupTimestampMillis());
+ this.createTable = new RisingwaveCreateTableTemplate();
this.createSource = new RisingwaveCreateSourceTemplate(bootstrapServer,
location, config.kafkaScanStartupTimestampMillis());
this.createSink = new RisingwaveCreateSinkTemplate(bootstrapServer, location);
this.createTopic = new RisingwaveCreateTopicTemplate();
this.createView = new RisingwaveCreateMaterializedViewTemplate();
this.describeView = new RisingwaveDescribeTemplate();
- this.createFunction = new RisingwaveCreateFunctionTemplate(udf);
+ this.createFunction = new RisingwaveCreateFunctionTemplate(options.udfs);
}
public RisingwaveRouteConfig resolve(
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/config/RisingwaveCommandType.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/config/RisingwaveCommandType.java
index c0a0409270..1c16bea36e 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/config/RisingwaveCommandType.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/config/RisingwaveCommandType.java
@@ -20,6 +20,7 @@ public enum RisingwaveCommandType
{
CREATE_TOPIC_COMMAND("CREATE TOPIC".getBytes()),
CREATE_TABLE_COMMAND("CREATE TABLE".getBytes()),
+ CREATE_STREAM_COMMAND("CREATE STREAM".getBytes()),
CREATE_MATERIALIZED_VIEW_COMMAND("CREATE MATERIALIZED VIEW".getBytes()),
CREATE_FUNCTION_COMMAND("CREATE FUNCTION".getBytes()),
UNKNOWN_COMMAND("UNKNOWN".getBytes());
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCommandTemplate.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCommandTemplate.java
index d97fb34c48..bb65d54a24 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCommandTemplate.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCommandTemplate.java
@@ -15,6 +15,7 @@
package io.aklivity.zilla.runtime.binding.risingwave.internal.statement;
import java.io.StringReader;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -28,11 +29,11 @@
public abstract class RisingwaveCommandTemplate
{
private final CCJSqlParserManager parserManager = new CCJSqlParserManager();
- private final Map includeMap = new Object2ObjectHashMap<>();
+ private final Map includeMap = new LinkedHashMap<>();
+ protected final StringBuilder fieldBuilder = new StringBuilder();
protected final StringBuilder includeBuilder = new StringBuilder();
protected static final Map ZILLA_MAPPINGS = new Object2ObjectHashMap<>();
-
static
{
ZILLA_MAPPINGS.put("zilla_correlation_id", "INCLUDE header 'zilla:correlation-id' AS %s\n");
@@ -40,6 +41,14 @@ public abstract class RisingwaveCommandTemplate
ZILLA_MAPPINGS.put("timestamp", "INCLUDE timestamp AS %s\n");
}
+ protected static final Map ZILLA_INCLUDE_TYPE_MAPPINGS = new Object2ObjectHashMap<>();
+ static
+ {
+ ZILLA_INCLUDE_TYPE_MAPPINGS.put("zilla_correlation_id", "VARCHAR");
+ ZILLA_INCLUDE_TYPE_MAPPINGS.put("zilla_identity", "VARCHAR");
+ ZILLA_INCLUDE_TYPE_MAPPINGS.put("timestamp", "TIMESTAMP");
+ }
+
public String primaryKey(
CreateTable statement)
{
@@ -70,6 +79,7 @@ public RisingwaveCreateTableCommand parserCreateTable(
int length)
{
String query = buffer.getStringWithoutLengthUtf8(offset, length);
+ query = query.replaceAll("(?i)\\bCREATE\\s+STREAM\\b", "CREATE TABLE");
int includeIndex = query.indexOf("INCLUDE");
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateFunctionTemplate.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateFunctionTemplate.java
index 33cb6a958a..6c687b2e90 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateFunctionTemplate.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateFunctionTemplate.java
@@ -22,6 +22,7 @@
public class RisingwaveCreateFunctionTemplate extends RisingwaveCommandTemplate
{
+ private static final List KEYWORDS = List.of("LANGUAGE", "AS", "USING");
private final String sqlFormat = """
CREATE FUNCTION %s(%s)
RETURNS %s
@@ -29,12 +30,32 @@ public class RisingwaveCreateFunctionTemplate extends RisingwaveCommandTemplate
LANGUAGE %s
USING LINK '%s';\u0000""";
- private final RisingwaveUdfConfig udf;
+ private final String java;
+ private final String python;
public RisingwaveCreateFunctionTemplate(
- RisingwaveUdfConfig udf)
+ List udfs)
{
- this.udf = udf;
+ String javaServer = null;
+ String pythonServer = null;
+
+ if (udfs != null && !udfs.isEmpty())
+ {
+ for (RisingwaveUdfConfig udf : udfs)
+ {
+ if (udf.language.equalsIgnoreCase("java"))
+ {
+ javaServer = udf.server;
+ }
+ else if (udf.language.equalsIgnoreCase("python"))
+ {
+ pythonServer = udf.server;
+ }
+ }
+ }
+
+ this.java = javaServer;
+ this.python = pythonServer;
}
public String generate(
@@ -54,33 +75,37 @@ public String generate(
int returnsIndex = parts.indexOf("RETURNS");
String returnType = returnsIndex >= 0 ? parts.get(returnsIndex + 1) : "";
- if ("TABLE".equalsIgnoreCase(returnType))
+ if (returnsIndex >= 0)
{
- int tableStartIndex = -1;
- int tableEndIndex = -1;
- for (int i = returnsIndex; i < parts.size(); i++)
- {
- if (parts.get(i).equals("("))
- {
- tableStartIndex = i;
- }
- else if (parts.get(i).equals(")"))
- {
- tableEndIndex = i;
- break;
- }
- }
-
- if (tableStartIndex >= 0 && tableEndIndex > tableStartIndex)
- {
- String tableDefinition = String.join(" ", parts.subList(tableStartIndex + 1, tableEndIndex));
- returnType += " (" + tableDefinition + ")";
- }
+ int nextKeywordIndex = findNextKeywordIndex(parts, returnsIndex + 1);
+ returnType = nextKeywordIndex >= 0
+ ? String.join(" ", parts.subList(returnsIndex + 1, nextKeywordIndex))
+ : String.join(" ", parts.subList(returnsIndex + 1, parts.size()));
}
int asIndex = parts.indexOf("AS");
String body = asIndex >= 0 ? parts.get(asIndex + 1) : "";
- return sqlFormat.formatted(functionName, parameters, returnType, body, udf.language, udf.server);
+ int langIndex = parts.indexOf("LANGUAGE");
+ String language = langIndex >= 0 ? parts.get(langIndex + 1) : "java";
+
+ return sqlFormat.formatted(functionName, parameters, returnType.trim(), body, language,
+ "python".equalsIgnoreCase(language) ? python : java);
+ }
+
+ private int findNextKeywordIndex(
+ List parts,
+ int startIndex)
+ {
+ int endIndex = -1;
+ for (int index = startIndex; index < parts.size(); index++)
+ {
+ if (KEYWORDS.contains(parts.get(index).toUpperCase()))
+ {
+ endIndex = index;
+ break;
+ }
+ }
+ return endIndex;
}
}
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateMaterializedViewTemplate.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateMaterializedViewTemplate.java
index 17c227df3a..4a57891eb3 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateMaterializedViewTemplate.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateMaterializedViewTemplate.java
@@ -14,25 +14,60 @@
*/
package io.aklivity.zilla.runtime.binding.risingwave.internal.statement;
-import net.sf.jsqlparser.statement.Statement;
+import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.create.view.CreateView;
public class RisingwaveCreateMaterializedViewTemplate extends RisingwaveCommandTemplate
{
private final String sqlFormat = """
CREATE MATERIALIZED VIEW IF NOT EXISTS %s AS %s;\u0000""";
+ private final String fieldFormat = "%s, ";
+ private final String includeFormat = "COALESCE(%s, zilla_%s_header::varchar) as %s, ";
public RisingwaveCreateMaterializedViewTemplate()
{
}
public String generate(
- Statement statement)
+ CreateView createView)
{
- CreateView createView = (CreateView) statement;
String view = createView.getView().getName();
String select = createView.getSelect().toString();
return String.format(sqlFormat, view, select);
}
+
+ public String generate(
+ RisingwaveCreateTableCommand command)
+ {
+ CreateTable createTable = command.createTable;
+ String name = createTable.getTable().getName();
+
+ String select = "*";
+
+ if (command.includes != null)
+ {
+ fieldBuilder.setLength(0);
+
+ createTable.getColumnDefinitions()
+ .forEach(c -> fieldBuilder.append(
+ String.format(fieldFormat, c.getColumnName())));
+ command.includes.forEach((k, v) ->
+ {
+ if ("timestamp".equals(k))
+ {
+ fieldBuilder.append(String.format(fieldFormat, v));
+ }
+ else
+ {
+ fieldBuilder.append(String.format(includeFormat, v, v, v));
+ }
+ });
+
+ fieldBuilder.delete(fieldBuilder.length() - 2, fieldBuilder.length());
+ select = fieldBuilder.toString();
+ }
+
+ return String.format(sqlFormat, "%s_view".formatted(name), "SELECT %s FROM %s_source".formatted(select, name));
+ }
}
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateSinkTemplate.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateSinkTemplate.java
index d5133d2eaf..e30a55b5f3 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateSinkTemplate.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateSinkTemplate.java
@@ -17,12 +17,14 @@
import java.util.Map;
import java.util.Optional;
-import net.sf.jsqlparser.statement.Statement;
+import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.create.view.CreateView;
public class RisingwaveCreateSinkTemplate extends RisingwaveCommandTemplate
{
private final String sqlFormat = """
+ CREATE SINK %s_view_sink INTO %s FROM %s_view;\u0000""";
+ private final String sqlKafkaFormat = """
CREATE SINK %s_sink
FROM %s
WITH (
@@ -49,9 +51,8 @@ public RisingwaveCreateSinkTemplate(
public String generate(
String database,
Map columns,
- Statement statement)
+ CreateView createView)
{
- CreateView createView = (CreateView) statement;
String viewName = createView.getView().getName();
Optional> primaryKeyMatch = columns.entrySet().stream()
@@ -68,6 +69,25 @@ public String generate(
String textPrimaryKey = primaryKeyMatch.map(Map.Entry::getKey).orElse(null);
String primaryKey = textPrimaryKey != null ? primaryKeyFormat.formatted(textPrimaryKey) : "";
- return String.format(sqlFormat, viewName, viewName, bootstrapServer, database, viewName, primaryKey, schemaRegistry);
+ return String.format(sqlKafkaFormat, viewName, viewName, bootstrapServer, database, viewName, primaryKey, schemaRegistry);
+ }
+
+ public String generate(
+ String database,
+ String primaryKey,
+ CreateTable createTable)
+ {
+ String table = createTable.getTable().getName();
+
+ return String.format(sqlKafkaFormat, table, table, bootstrapServer, database, table,
+ primaryKeyFormat.formatted(primaryKey), schemaRegistry);
+ }
+
+ public String generate(
+ CreateTable createTable)
+ {
+ String table = createTable.getTable().getName();
+
+ return String.format(sqlFormat, table, table, table);
}
}
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateSourceTemplate.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateSourceTemplate.java
index da095da905..1e64e8456d 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateSourceTemplate.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateSourceTemplate.java
@@ -44,7 +44,7 @@ public RisingwaveCreateSourceTemplate(
this.scanStartupMil = scanStartupMil;
}
- public String generate(
+ public String generateStreamSource(
String database,
RisingwaveCreateTableCommand command)
{
@@ -61,4 +61,35 @@ public String generate(
return String.format(sqlFormat, table, includeBuilder, bootstrapServer, database, table, scanStartupMil, schemaRegistry);
}
+
+ public String generateTableSource(
+ String database,
+ RisingwaveCreateTableCommand command)
+ {
+ String table = command.createTable.getTable().getName();
+ String sourceName = "%s_source".formatted(table);
+
+ includeBuilder.setLength(0);
+ final Map includes = command.includes;
+ if (includes != null && !includes.isEmpty())
+ {
+ includeBuilder.append("\n");
+ includes.forEach((k, v) ->
+ {
+ if ("timestamp".equals(k))
+ {
+ includeBuilder.append(String.format(ZILLA_MAPPINGS.get(k), v));
+ }
+ else
+ {
+ includeBuilder.append(String.format(ZILLA_MAPPINGS.get(k), "zilla_%s_header".formatted(v)));
+ }
+
+ });
+ includeBuilder.delete(includeBuilder.length() - 1, includeBuilder.length());
+ }
+
+ return String.format(sqlFormat, sourceName, includeBuilder, bootstrapServer,
+ database, table, scanStartupMil, schemaRegistry);
+ }
}
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateTableTemplate.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateTableTemplate.java
index ac4d8507dc..9e8f98acf0 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateTableTemplate.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateTableTemplate.java
@@ -14,61 +14,41 @@
*/
package io.aklivity.zilla.runtime.binding.risingwave.internal.statement;
-import java.util.Map;
-
import net.sf.jsqlparser.statement.create.table.CreateTable;
public class RisingwaveCreateTableTemplate extends RisingwaveCommandTemplate
{
private final String sqlFormat = """
- CREATE TABLE IF NOT EXISTS %s (
- *,
- PRIMARY KEY (%s)
- )
- INCLUDE KEY AS key%s
- WITH (
- connector='kafka',
- properties.bootstrap.server='%s',
- topic='%s.%s',
- scan.startup.mode='latest',
- scan.startup.timestamp.millis='%d'
- ) FORMAT PLAIN ENCODE AVRO (
- schema.registry = '%s'
- );\u0000""";
-
- private final String bootstrapServer;
- private final String schemaRegistry;
- private final long scanStartupMil;
+ CREATE TABLE IF NOT EXISTS %s (%s%s);\u0000""";
+ private final String primaryKeyFormat = ", PRIMARY KEY (%s)";
+ private final String fieldFormat = "%s %s, ";
- public RisingwaveCreateTableTemplate(
- String bootstrapServer,
- String schemaRegistry,
- long scanStartupMil)
+ public RisingwaveCreateTableTemplate()
{
- this.bootstrapServer = bootstrapServer;
- this.schemaRegistry = schemaRegistry;
- this.scanStartupMil = scanStartupMil;
}
public String generate(
- String database,
RisingwaveCreateTableCommand command)
{
CreateTable createTable = command.createTable;
- String table = createTable.getTable().getName();
+ String topic = createTable.getTable().getName();
+ String primaryKeyField = primaryKey(createTable);
+ String primaryKey = primaryKeyField != null ? String.format(primaryKeyFormat, primaryKeyField) : "";
- String primaryKey = primaryKey(createTable);
+ fieldBuilder.setLength(0);
- includeBuilder.setLength(0);
- final Map includes = command.includes;
- if (includes != null && !includes.isEmpty())
+ createTable.getColumnDefinitions()
+ .forEach(c -> fieldBuilder.append(
+ String.format(fieldFormat, c.getColumnName(), c.getColDataType().getDataType())));
+
+ if (command.includes != null)
{
- includeBuilder.append("\n");
- includes.forEach((k, v) -> includeBuilder.append(String.format(ZILLA_MAPPINGS.get(k), v)));
- includeBuilder.delete(includeBuilder.length() - 1, includeBuilder.length());
+ command.includes.forEach((k, v) -> fieldBuilder.append(
+ String.format(fieldFormat, v, ZILLA_INCLUDE_TYPE_MAPPINGS.get(k))));
}
- return String.format(sqlFormat, table, primaryKey, includeBuilder, bootstrapServer, database,
- table, scanStartupMil, schemaRegistry);
+ fieldBuilder.delete(fieldBuilder.length() - 2, fieldBuilder.length());
+
+ return String.format(sqlFormat, topic, fieldBuilder, primaryKey);
}
}
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateTopicTemplate.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateTopicTemplate.java
index 9e2c627c56..f088a3111a 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateTopicTemplate.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveCreateTopicTemplate.java
@@ -45,6 +45,32 @@ public String generate(
createTable.getColumnDefinitions()
.forEach(c -> fieldBuilder.append(
String.format(fieldFormat, c.getColumnName(), c.getColDataType().getDataType())));
+
+ fieldBuilder.delete(fieldBuilder.length() - 2, fieldBuilder.length());
+
+ return String.format(sqlFormat, topic, fieldBuilder, primaryKey);
+ }
+
+ public String generate(
+ RisingwaveCreateTableCommand command)
+ {
+ CreateTable createTable = command.createTable;
+ String topic = createTable.getTable().getName();
+ String primaryKeyField = primaryKey(createTable);
+ String primaryKey = primaryKeyField != null ? String.format(primaryKeyFormat, primaryKeyField) : "";
+
+ fieldBuilder.setLength(0);
+
+ createTable.getColumnDefinitions()
+ .forEach(c -> fieldBuilder.append(
+ String.format(fieldFormat, c.getColumnName(), c.getColDataType().getDataType())));
+
+ if (command.includes != null)
+ {
+ command.includes.forEach((k, v) -> fieldBuilder.append(
+ String.format(fieldFormat, v, ZILLA_INCLUDE_TYPE_MAPPINGS.get(k))));
+ }
+
fieldBuilder.delete(fieldBuilder.length() - 2, fieldBuilder.length());
return String.format(sqlFormat, topic, fieldBuilder, primaryKey);
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveSqlCommandParser.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveSqlCommandParser.java
index 619a25ddfb..5fe8d3a60b 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveSqlCommandParser.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/statement/RisingwaveSqlCommandParser.java
@@ -27,7 +27,7 @@ public final class RisingwaveSqlCommandParser
private static final String SQL_COMMAND_PATTERN =
"(?i)\\b(CREATE FUNCTION)\\b.*?\\$\\$(.*?)\\$\\$\\s*;[\\x00\\n]*" +
"|\\b(CREATE FUNCTION)\\b.*?RETURNS .*?AS.*?;[\\x00\\n]*" +
- "|\\b(CREATE MATERIALIZED VIEW|CREATE SOURCE|CREATE SINK|CREATE INDEX" +
+ "|\\b(CREATE MATERIALIZED VIEW|CREATE SOURCE|CREATE SINK|CREATE INDEX|CREATE STREAM" +
"|CREATE VIEW|SHOW TABLES|DESCRIBE|SHOW)\\b.*?;[\\x00\\n]*" +
"|\\b(SELECT|INSERT|UPDATE|DELETE|ALTER|DROP|CREATE TABLE|CREATE SCHEMA|CREATE DATABASE)\\b.*?;[\\x00\\n]*";
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/RisingwaveCompletionCommand.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/RisingwaveCompletionCommand.java
index b80098e3e8..5c3204e749 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/RisingwaveCompletionCommand.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/RisingwaveCompletionCommand.java
@@ -19,6 +19,7 @@ public enum RisingwaveCompletionCommand
UNKNOWN_COMMAND("UNKNOWN".getBytes()),
CREATE_TABLE_COMMAND("CREATE_TABLE".getBytes()),
CREATE_MATERIALIZED_VIEW_COMMAND("CREATE_MATERIALIZED_VIEW".getBytes()),
+ CREATE_STREAM_COMMAND("CREATE_STREAM".getBytes()),
CREATE_FUNCTION_COMMAND("CREATE_FUNCTION".getBytes());
private final byte[] value;
diff --git a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/RisingwaveProxyFactory.java b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/RisingwaveProxyFactory.java
index 418a848edd..a4e1a31aee 100644
--- a/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/RisingwaveProxyFactory.java
+++ b/incubator/binding-risingwave/src/main/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/RisingwaveProxyFactory.java
@@ -144,6 +144,7 @@ public final class RisingwaveProxyFactory implements RisingwaveStreamFactory
Object2ObjectHashMap clientTransforms =
new Object2ObjectHashMap<>();
clientTransforms.put(RisingwaveCommandType.CREATE_TABLE_COMMAND, this::decodeCreateTableCommand);
+ clientTransforms.put(RisingwaveCommandType.CREATE_STREAM_COMMAND, this::decodeCreateStreamCommand);
clientTransforms.put(RisingwaveCommandType.CREATE_MATERIALIZED_VIEW_COMMAND, this::decodeCreateMaterializedViewCommand);
clientTransforms.put(RisingwaveCommandType.CREATE_FUNCTION_COMMAND, this::decodeCreateFunctionCommand);
clientTransforms.put(RisingwaveCommandType.UNKNOWN_COMMAND, this::decodeUnknownCommand);
@@ -1466,7 +1467,7 @@ private void decodeCreateTableCommand(
int offset,
int length)
{
- if (server.commandsProcessed == 2)
+ if (server.commandsProcessed == 6)
{
server.onCommandCompleted(traceId, authorization, length, RisingwaveCompletionCommand.CREATE_TABLE_COMMAND);
}
@@ -1481,15 +1482,68 @@ private void decodeCreateTableCommand(
if (server.commandsProcessed == 0)
{
- newStatement = binding.createTopic.generate(command.createTable);
+ newStatement = binding.createTopic.generate(command);
+ }
+ else if (server.commandsProcessed == 1)
+ {
+ newStatement = binding.createSource.generateTableSource(server.database, command);
+ }
+ else if (server.commandsProcessed == 2)
+ {
+ newStatement = binding.createView.generate(command);
+ }
+ else if (server.commandsProcessed == 3)
+ {
+ newStatement = binding.createTable.generate(command);
+ }
+ else if (server.commandsProcessed == 4)
+ {
+ newStatement = binding.createSink.generate(command.createTable);
+ }
+ else if (server.commandsProcessed == 5)
+ {
+ newStatement = binding.createSink.generate(server.database, primaryKey, command.createTable);
}
- else if (server.commandsProcessed == 1 && primaryKey != null)
+
+ statementBuffer.putBytes(progress, newStatement.getBytes());
+ progress += newStatement.length();
+
+ final RisingwaveRouteConfig route =
+ server.binding.resolve(authorization, statementBuffer, 0, progress);
+
+ final PgsqlClient client = server.streamsByRouteIds.get(route.id);
+ client.doPgsqlQuery(traceId, authorization, statementBuffer, 0, progress);
+ client.typeCommand = ignoreFlushCommand;
+ }
+ }
+
+ private void decodeCreateStreamCommand(
+ PgsqlServer server,
+ long traceId,
+ long authorization,
+ DirectBuffer buffer,
+ int offset,
+ int length)
+ {
+ if (server.commandsProcessed == 2)
+ {
+ server.onCommandCompleted(traceId, authorization, length, RisingwaveCompletionCommand.CREATE_STREAM_COMMAND);
+ }
+ else
+ {
+ final RisingwaveBindingConfig binding = server.binding;
+ final RisingwaveCreateTableCommand command = binding.createTable.parserCreateTable(buffer, offset, length);
+
+ String newStatement = "";
+ int progress = 0;
+
+ if (server.commandsProcessed == 0)
{
- newStatement = binding.createTable.generate(server.database, command);
+ newStatement = binding.createTopic.generate(command.createTable);
}
else if (server.commandsProcessed == 1)
{
- newStatement = binding.createSource.generate(server.database, command);
+ newStatement = binding.createSource.generateStreamSource(server.database, command);
}
statementBuffer.putBytes(progress, newStatement.getBytes());
diff --git a/incubator/binding-risingwave/src/test/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/ProxyIT.java b/incubator/binding-risingwave/src/test/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/ProxyIT.java
index 316ab6d996..0be2a80f18 100644
--- a/incubator/binding-risingwave/src/test/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/ProxyIT.java
+++ b/incubator/binding-risingwave/src/test/java/io/aklivity/zilla/runtime/binding/risingwave/internal/stream/ProxyIT.java
@@ -62,9 +62,9 @@ public void shouldCreateTableWithPrimaryKey() throws Exception
@Test
@Configuration("proxy.yaml")
@Specification({
- "${pgsql}/create.table/client",
- "${effective}/create.table/server" })
- public void shouldCreateTable() throws Exception
+ "${pgsql}/create.stream/client",
+ "${effective}/create.stream/server" })
+ public void shouldCreateStream() throws Exception
{
k3po.finish();
}
@@ -72,9 +72,9 @@ public void shouldCreateTable() throws Exception
@Test
@Configuration("proxy.yaml")
@Specification({
- "${pgsql}/create.tables/client",
- "${effective}/create.tables/server" })
- public void shouldCreateTables() throws Exception
+ "${pgsql}/create.streams/client",
+ "${effective}/create.streams/server" })
+ public void shouldCreateStreams() throws Exception
{
k3po.finish();
}
@@ -121,6 +121,36 @@ public void shouldCreateFunction() throws Exception
k3po.finish();
}
+ @Test
+ @Configuration("proxy.function.yaml")
+ @Specification({
+ "${pgsql}/create.function.python/client",
+ "${effective}/create.function.python/server" })
+ public void shouldCreateFunctionPython() throws Exception
+ {
+ k3po.finish();
+ }
+
+ @Test
+ @Configuration("proxy.function.yaml")
+ @Specification({
+ "${pgsql}/create.function.embedded.python/client",
+ "${effective}/create.function.embedded.python/server" })
+ public void shouldCreateFunctionEmbeddedPython() throws Exception
+ {
+ k3po.finish();
+ }
+
+ @Test
+ @Configuration("proxy.function.yaml")
+ @Specification({
+ "${pgsql}/create.function.return.struct/client",
+ "${effective}/create.function.return.struct/server" })
+ public void shouldCreateFunctionReturnStruct() throws Exception
+ {
+ k3po.finish();
+ }
+
@Test
@Configuration("proxy.function.yaml")
@Specification({
@@ -144,9 +174,9 @@ public void shouldCreateFunctionEmbedded() throws Exception
@Test
@Configuration("proxy.yaml")
@Specification({
- "${pgsql}/create.table.with.includes/client",
- "${effective}/create.table.with.includes/server" })
- public void shouldCreateTableWithIncludes() throws Exception
+ "${pgsql}/create.stream.with.includes/client",
+ "${effective}/create.stream.with.includes/server" })
+ public void shouldCreateStreamWithIncludes() throws Exception
{
k3po.finish();
}
diff --git a/incubator/command-dump/pom.xml b/incubator/command-dump/pom.xml
index 9a8543e19c..08a8a9b735 100644
--- a/incubator/command-dump/pom.xml
+++ b/incubator/command-dump/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/command-log/pom.xml b/incubator/command-log/pom.xml
index dd93d393a1..89a50e343f 100644
--- a/incubator/command-log/pom.xml
+++ b/incubator/command-log/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/command-tune/pom.xml b/incubator/command-tune/pom.xml
index 7ea44ca2ae..353d43a934 100644
--- a/incubator/command-tune/pom.xml
+++ b/incubator/command-tune/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/incubator/pom.xml b/incubator/pom.xml
index b76c84e7f1..c694066601 100644
--- a/incubator/pom.xml
+++ b/incubator/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/manager/pom.xml b/manager/pom.xml
index 0dc13e571b..962b99d0b0 100644
--- a/manager/pom.xml
+++ b/manager/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/pom.xml b/pom.xml
index a1b9917186..ec5a7d6ce3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
4.0.0
io.aklivity.zilla
zilla
- 0.9.96
+ 0.9.97
pom
zilla
https://github.com/aklivity/zilla
diff --git a/runtime/binding-asyncapi/pom.xml b/runtime/binding-asyncapi/pom.xml
index 39794069a2..4982cb11cb 100644
--- a/runtime/binding-asyncapi/pom.xml
+++ b/runtime/binding-asyncapi/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-echo/pom.xml b/runtime/binding-echo/pom.xml
index 99f4bf8462..b44df689f6 100644
--- a/runtime/binding-echo/pom.xml
+++ b/runtime/binding-echo/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-fan/pom.xml b/runtime/binding-fan/pom.xml
index 3020df23a2..b35557702d 100644
--- a/runtime/binding-fan/pom.xml
+++ b/runtime/binding-fan/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-filesystem/pom.xml b/runtime/binding-filesystem/pom.xml
index d042600d28..1012986a92 100644
--- a/runtime/binding-filesystem/pom.xml
+++ b/runtime/binding-filesystem/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-grpc-kafka/pom.xml b/runtime/binding-grpc-kafka/pom.xml
index 299ffeff63..703e99ea19 100644
--- a/runtime/binding-grpc-kafka/pom.xml
+++ b/runtime/binding-grpc-kafka/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-grpc/pom.xml b/runtime/binding-grpc/pom.xml
index dade8f75a8..2b86700ead 100644
--- a/runtime/binding-grpc/pom.xml
+++ b/runtime/binding-grpc/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-http-filesystem/pom.xml b/runtime/binding-http-filesystem/pom.xml
index 229dfe5413..714e9425fa 100644
--- a/runtime/binding-http-filesystem/pom.xml
+++ b/runtime/binding-http-filesystem/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-http-kafka/pom.xml b/runtime/binding-http-kafka/pom.xml
index dc58093614..522860ce6f 100644
--- a/runtime/binding-http-kafka/pom.xml
+++ b/runtime/binding-http-kafka/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-http/pom.xml b/runtime/binding-http/pom.xml
index fb6183cccc..b18a1b2393 100644
--- a/runtime/binding-http/pom.xml
+++ b/runtime/binding-http/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-kafka-grpc/pom.xml b/runtime/binding-kafka-grpc/pom.xml
index 19fcec0b84..16ab43d0f0 100644
--- a/runtime/binding-kafka-grpc/pom.xml
+++ b/runtime/binding-kafka-grpc/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-kafka/pom.xml b/runtime/binding-kafka/pom.xml
index 915c1ac818..86aba12931 100644
--- a/runtime/binding-kafka/pom.xml
+++ b/runtime/binding-kafka/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-mqtt-kafka/pom.xml b/runtime/binding-mqtt-kafka/pom.xml
index e5049ce30d..23360ce1f4 100644
--- a/runtime/binding-mqtt-kafka/pom.xml
+++ b/runtime/binding-mqtt-kafka/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-mqtt/pom.xml b/runtime/binding-mqtt/pom.xml
index 2eb850add0..f909c47a48 100644
--- a/runtime/binding-mqtt/pom.xml
+++ b/runtime/binding-mqtt/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-openapi-asyncapi/pom.xml b/runtime/binding-openapi-asyncapi/pom.xml
index 5bf7591394..ab32ca681e 100644
--- a/runtime/binding-openapi-asyncapi/pom.xml
+++ b/runtime/binding-openapi-asyncapi/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-openapi/pom.xml b/runtime/binding-openapi/pom.xml
index d58ab3f09f..40ba244303 100644
--- a/runtime/binding-openapi/pom.xml
+++ b/runtime/binding-openapi/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-proxy/pom.xml b/runtime/binding-proxy/pom.xml
index c9bdb407c2..690ff6cf2a 100644
--- a/runtime/binding-proxy/pom.xml
+++ b/runtime/binding-proxy/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-sse-kafka/pom.xml b/runtime/binding-sse-kafka/pom.xml
index 573a06895c..040dd67b82 100644
--- a/runtime/binding-sse-kafka/pom.xml
+++ b/runtime/binding-sse-kafka/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-sse/pom.xml b/runtime/binding-sse/pom.xml
index b11a798555..d95b35d641 100644
--- a/runtime/binding-sse/pom.xml
+++ b/runtime/binding-sse/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-tcp/pom.xml b/runtime/binding-tcp/pom.xml
index f3d7e18e67..be696937b9 100644
--- a/runtime/binding-tcp/pom.xml
+++ b/runtime/binding-tcp/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-tls/pom.xml b/runtime/binding-tls/pom.xml
index 9b9999e1f7..b34236e70d 100644
--- a/runtime/binding-tls/pom.xml
+++ b/runtime/binding-tls/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/binding-ws/pom.xml b/runtime/binding-ws/pom.xml
index 7923732e5e..84f190e598 100644
--- a/runtime/binding-ws/pom.xml
+++ b/runtime/binding-ws/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/catalog-apicurio/pom.xml b/runtime/catalog-apicurio/pom.xml
index 92ca89f37e..22a4144c16 100644
--- a/runtime/catalog-apicurio/pom.xml
+++ b/runtime/catalog-apicurio/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/catalog-filesystem/pom.xml b/runtime/catalog-filesystem/pom.xml
index bf16f084b1..b84133156a 100644
--- a/runtime/catalog-filesystem/pom.xml
+++ b/runtime/catalog-filesystem/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/catalog-inline/pom.xml b/runtime/catalog-inline/pom.xml
index 8057461088..ee7b222959 100644
--- a/runtime/catalog-inline/pom.xml
+++ b/runtime/catalog-inline/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/catalog-karapace/pom.xml b/runtime/catalog-karapace/pom.xml
index 1b7ce33c86..97e6ae27ae 100644
--- a/runtime/catalog-karapace/pom.xml
+++ b/runtime/catalog-karapace/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/catalog-schema-registry/pom.xml b/runtime/catalog-schema-registry/pom.xml
index a9aa8fc2fc..319b69c774 100644
--- a/runtime/catalog-schema-registry/pom.xml
+++ b/runtime/catalog-schema-registry/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/handler/SchemaRegistryCatalogHandler.java b/runtime/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/handler/SchemaRegistryCatalogHandler.java
index 10de4803db..587c991d91 100644
--- a/runtime/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/handler/SchemaRegistryCatalogHandler.java
+++ b/runtime/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/handler/SchemaRegistryCatalogHandler.java
@@ -15,6 +15,7 @@
package io.aklivity.zilla.runtime.catalog.schema.registry.internal.handler;
import static io.aklivity.zilla.runtime.catalog.schema.registry.internal.handler.CachedSchemaId.IN_PROGRESS;
+import static io.aklivity.zilla.runtime.catalog.schema.registry.internal.serializer.UnregisterSchemaRequest.NO_VERSIONS;
import java.net.URI;
import java.net.http.HttpClient;
@@ -35,6 +36,7 @@
import io.aklivity.zilla.runtime.catalog.schema.registry.internal.config.SchemaRegistryCatalogConfig;
import io.aklivity.zilla.runtime.catalog.schema.registry.internal.events.SchemaRegistryEventContext;
import io.aklivity.zilla.runtime.catalog.schema.registry.internal.serializer.RegisterSchemaRequest;
+import io.aklivity.zilla.runtime.catalog.schema.registry.internal.serializer.UnregisterSchemaRequest;
import io.aklivity.zilla.runtime.catalog.schema.registry.internal.types.SchemaRegistryPrefixFW;
import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler;
import io.aklivity.zilla.runtime.engine.model.function.ValueConsumer;
@@ -42,7 +44,8 @@
public class SchemaRegistryCatalogHandler implements CatalogHandler
{
private static final String SUBJECT_VERSION_PATH = "/subjects/{0}/versions/{1}";
- private static final String SUBJECT_PATH = "/subjects/{0}/versions";
+ private static final String REGISTER_SUBJECT_PATH = "/subjects/{0}/versions";
+ private static final String UNREGISTER_SUBJECT_PATH = "/subjects/{0}";
private static final String SCHEMA_PATH = "/schemas/ids/{0}";
private static final int MAX_PADDING_LENGTH = 5;
@@ -55,7 +58,8 @@ public class SchemaRegistryCatalogHandler implements CatalogHandler
private final HttpClient client;
private final String baseUrl;
- private final RegisterSchemaRequest request;
+ private final RegisterSchemaRequest registerRequest;
+ private final UnregisterSchemaRequest unregisterRequest;
private final CRC32C crc32c;
private final Int2ObjectCache schemas;
private final Int2ObjectCache schemaIds;
@@ -70,7 +74,8 @@ public SchemaRegistryCatalogHandler(
{
this.baseUrl = catalog.options.url;
this.client = HttpClient.newHttpClient();
- this.request = new RegisterSchemaRequest();
+ this.registerRequest = new RegisterSchemaRequest();
+ this.unregisterRequest = new UnregisterSchemaRequest();
this.crc32c = new CRC32C();
this.schemas = new Int2ObjectCache<>(1, 1024, i -> {});
this.schemaIds = new Int2ObjectCache<>(1, 1024, i -> {});
@@ -88,15 +93,30 @@ public int register(
{
int versionId = NO_VERSION_ID;
- String response = sendPostHttpRequest(MessageFormat.format(SUBJECT_PATH, subject), schema);
+ String response = sendPostHttpRequest(MessageFormat.format(REGISTER_SUBJECT_PATH, subject), schema);
if (response != null)
{
- versionId = request.resolveResponse(response);
+ versionId = registerRequest.resolveResponse(response);
}
return versionId;
}
+ @Override
+ public int[] unregister(
+ String subject)
+ {
+ int[] versions = NO_VERSIONS;
+
+ String response = sendDeleteHttpRequest(MessageFormat.format(UNREGISTER_SUBJECT_PATH, subject));
+ if (response != null)
+ {
+ versions = unregisterRequest.resolveResponse(response);
+ }
+
+ return versions;
+ }
+
@Override
public String resolve(
int schemaId)
@@ -149,7 +169,7 @@ public String resolve(
{
event.onRetrievableSchemaId(catalogId, schemaId);
}
- newFuture.complete(new CachedSchema(request.resolveSchemaResponse(response), retryAttempts));
+ newFuture.complete(new CachedSchema(registerRequest.resolveSchemaResponse(response), retryAttempts));
}
}
catch (Throwable ex)
@@ -251,8 +271,8 @@ else if (response != null)
{
event.onRetrievableSchemaSubjectVersion(catalogId, subject, version);
}
- newFuture.complete(new CachedSchemaId(System.currentTimeMillis(), request.resolveResponse(response),
- retryAttempts, retryAfter));
+ newFuture.complete(new CachedSchemaId(System.currentTimeMillis(),
+ registerRequest.resolveResponse(response), retryAttempts, retryAfter));
}
}
catch (Throwable ex)
@@ -390,6 +410,28 @@ private String sendPostHttpRequest(
return responseBody;
}
+ private String sendDeleteHttpRequest(
+ String path)
+ {
+ HttpRequest httpRequest = HttpRequest
+ .newBuilder(toURI(baseUrl, path))
+ .version(HttpClient.Version.HTTP_1_1)
+ .DELETE()
+ .build();
+
+ String responseBody;
+ try
+ {
+ HttpResponse httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());
+ responseBody = httpResponse.statusCode() == 200 ? httpResponse.body() : null;
+ }
+ catch (Exception ex)
+ {
+ responseBody = null;
+ }
+ return responseBody;
+ }
+
@Override
public String location()
{
diff --git a/runtime/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/serializer/UnregisterSchemaRequest.java b/runtime/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/serializer/UnregisterSchemaRequest.java
new file mode 100644
index 0000000000..84ff7d4361
--- /dev/null
+++ b/runtime/catalog-schema-registry/src/main/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/serializer/UnregisterSchemaRequest.java
@@ -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.
+ */
+package io.aklivity.zilla.runtime.catalog.schema.registry.internal.serializer;
+
+import java.io.StringReader;
+import java.util.stream.IntStream;
+
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonReader;
+import jakarta.json.stream.JsonParsingException;
+
+public class UnregisterSchemaRequest
+{
+ public static final int[] NO_VERSIONS = new int[0];
+
+ public int[] resolveResponse(
+ String response)
+ {
+ try
+ {
+ JsonReader reader = Json.createReader(new StringReader(response));
+ JsonArray array = reader.readArray();
+
+ return IntStream.range(0, array.size())
+ .map(array::getInt)
+ .toArray();
+ }
+ catch (JsonParsingException ex)
+ {
+ return NO_VERSIONS;
+ }
+ }
+}
diff --git a/runtime/catalog-schema-registry/src/test/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryIT.java b/runtime/catalog-schema-registry/src/test/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryIT.java
index d22a449690..704c6f25ad 100644
--- a/runtime/catalog-schema-registry/src/test/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryIT.java
+++ b/runtime/catalog-schema-registry/src/test/java/io/aklivity/zilla/runtime/catalog/schema/registry/internal/SchemaRegistryIT.java
@@ -145,4 +145,15 @@ public void shouldRegisterSchema() throws Exception
{
k3po.finish();
}
+
+ @Test
+ @Configuration("unregister/zilla.yaml")
+ @Specification({
+ "${net}/handshake/client",
+ "${app}/handshake/server",
+ "${remote}/unregister.schema" })
+ public void shouldUnregisterSchema() throws Exception
+ {
+ k3po.finish();
+ }
}
diff --git a/runtime/command-metrics/pom.xml b/runtime/command-metrics/pom.xml
index d19a28aeab..04f7864263 100644
--- a/runtime/command-metrics/pom.xml
+++ b/runtime/command-metrics/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/command-start/pom.xml b/runtime/command-start/pom.xml
index f7e4b07373..8b98acdfc8 100644
--- a/runtime/command-start/pom.xml
+++ b/runtime/command-start/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/command-stop/pom.xml b/runtime/command-stop/pom.xml
index 03fbc63623..2686e756c5 100644
--- a/runtime/command-stop/pom.xml
+++ b/runtime/command-stop/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/command-version/pom.xml b/runtime/command-version/pom.xml
index bb123a7271..b7b31f2153 100644
--- a/runtime/command-version/pom.xml
+++ b/runtime/command-version/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/command/pom.xml b/runtime/command/pom.xml
index f882c5f7a9..e673eae8a6 100644
--- a/runtime/command/pom.xml
+++ b/runtime/command/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/common/pom.xml b/runtime/common/pom.xml
index 08bc8138a3..628d3162c7 100644
--- a/runtime/common/pom.xml
+++ b/runtime/common/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/engine/pom.xml b/runtime/engine/pom.xml
index 5bc7d4b1fc..6048017d99 100644
--- a/runtime/engine/pom.xml
+++ b/runtime/engine/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/catalog/CatalogHandler.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/catalog/CatalogHandler.java
index 65b3aac632..ceabb8fdcf 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/catalog/CatalogHandler.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/catalog/CatalogHandler.java
@@ -69,6 +69,12 @@ default int register(
return NO_VERSION_ID;
}
+ default int[] unregister(
+ String subject)
+ {
+ return new int[0];
+ }
+
String resolve(
int schemaId);
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 e7e5a3e590..115764015e 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
@@ -343,11 +343,15 @@ else if (assertion.schema != null && !assertion.schema.equals(schema))
}
else
{
+ if (catalog.subject != null && schema == null)
+ {
+ handler.unregister(catalog.subject);
+ }
if (catalog.subject != null && schema != null)
{
handler.register(catalog.subject, schema);
}
- else if (catalog.subject != null && catalog.version != null)
+ else if (catalog.subject != null && catalog.version != null && schema != null)
{
handler.resolve(catalog.subject, catalog.version);
}
diff --git a/runtime/exporter-otlp/pom.xml b/runtime/exporter-otlp/pom.xml
index 54422d759f..12a0544f6e 100644
--- a/runtime/exporter-otlp/pom.xml
+++ b/runtime/exporter-otlp/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/exporter-prometheus/pom.xml b/runtime/exporter-prometheus/pom.xml
index 5b663abc61..6be180e600 100644
--- a/runtime/exporter-prometheus/pom.xml
+++ b/runtime/exporter-prometheus/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/exporter-stdout/pom.xml b/runtime/exporter-stdout/pom.xml
index d8222d2444..29c29b8aa3 100644
--- a/runtime/exporter-stdout/pom.xml
+++ b/runtime/exporter-stdout/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/filesystem-http/pom.xml b/runtime/filesystem-http/pom.xml
index 022f555971..9bab57bdb5 100644
--- a/runtime/filesystem-http/pom.xml
+++ b/runtime/filesystem-http/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/guard-jwt/pom.xml b/runtime/guard-jwt/pom.xml
index cc4dc08771..afc9802559 100644
--- a/runtime/guard-jwt/pom.xml
+++ b/runtime/guard-jwt/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/config/JwtOptionsConfig.java b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/config/JwtOptionsConfig.java
index 2ac7787f91..eb5ac5d879 100644
--- a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/config/JwtOptionsConfig.java
+++ b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/config/JwtOptionsConfig.java
@@ -29,6 +29,7 @@ public class JwtOptionsConfig extends OptionsConfig
public final String audience;
public final List keys;
public final Optional challenge;
+ public final String identity;
public final Optional keysURL;
public static JwtOptionsConfigBuilder builder()
@@ -47,12 +48,14 @@ public static JwtOptionsConfigBuilder builder(
String audience,
List keys,
Duration challenge,
+ String identity,
String keysURL)
{
this.issuer = issuer;
this.audience = audience;
this.keys = keys;
this.challenge = ofNullable(challenge);
+ this.identity = identity;
this.keysURL = ofNullable(keysURL);
}
}
diff --git a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/config/JwtOptionsConfigBuilder.java b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/config/JwtOptionsConfigBuilder.java
index 7ae6d40e22..eb3c437557 100644
--- a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/config/JwtOptionsConfigBuilder.java
+++ b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/config/JwtOptionsConfigBuilder.java
@@ -30,6 +30,7 @@ public class JwtOptionsConfigBuilder extends ConfigBuilder keys;
private Duration challenge;
+ private String identity;
private String keysURL;
JwtOptionsConfigBuilder(
@@ -66,6 +67,13 @@ public JwtOptionsConfigBuilder challenge(
return this;
}
+ public JwtOptionsConfigBuilder identity(
+ String identity)
+ {
+ this.identity = identity;
+ return this;
+ }
+
public JwtOptionsConfigBuilder keys(
List keys)
{
@@ -99,6 +107,6 @@ public JwtOptionsConfigBuilder keysURL(
@Override
public T build()
{
- return mapper.apply(new JwtOptionsConfig(issuer, audience, keys, challenge, keysURL));
+ return mapper.apply(new JwtOptionsConfig(issuer, audience, keys, challenge, identity, keysURL));
}
}
diff --git a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtGuardHandler.java b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtGuardHandler.java
index be90da20c5..c9748c8ddd 100644
--- a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtGuardHandler.java
+++ b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtGuardHandler.java
@@ -58,6 +58,7 @@ public class JwtGuardHandler implements GuardHandler
private final String issuer;
private final String audience;
private final Duration challenge;
+ private final String identity;
private final Map keys;
private final Long2ObjectHashMap sessionsById;
private final LongSupplier supplyAuthorizedId;
@@ -72,14 +73,14 @@ public JwtGuardHandler(
this.issuer = options.issuer;
this.audience = options.audience;
this.challenge = options.challenge.orElse(null);
+ this.identity = options.identity;
List keysConfig = options.keys;
if ((keysConfig == null || keysConfig.isEmpty()) && options.keysURL.isPresent())
{
- JsonbConfig config = new JsonbConfig()
- .withAdapters(new JwtKeySetConfigAdapter());
Jsonb jsonb = JsonbBuilder.newBuilder()
- .withConfig(config)
+ .withConfig(new JsonbConfig()
+ .withAdapters(new JwtKeySetConfigAdapter()))
.build();
Path keysPath = context.resolvePath(options.keysURL.get());
String keysText = readKeys(keysPath);
@@ -128,7 +129,7 @@ public long reauthorize(
String credentials)
{
JwtSession session = null;
- String subject = null;
+ String identity = null;
String reason = "";
authorize:
@@ -158,7 +159,7 @@ public long reauthorize(
String payload = signature.getPayload();
JwtClaims claims = JwtClaims.parse(payload);
- subject = claims.getSubject();
+ identity = this.identity != null ? claims.getStringClaimValue(this.identity) : claims.getSubject();
NumericDate notBefore = claims.getNotBefore();
NumericDate notAfter = claims.getExpirationTime();
String issuer = claims.getIssuer();
@@ -185,7 +186,7 @@ public long reauthorize(
.orElse(null);
JwtSessionStore sessionStore = supplySessionStore(contextId);
- session = sessionStore.supplySession(subject, roles);
+ session = sessionStore.supplySession(identity, roles);
session.credentials = credentials;
session.roles = roles;
@@ -204,7 +205,7 @@ public long reauthorize(
}
if (session == null)
{
- event.authorizationFailed(traceId, bindingId, subject, reason);
+ event.authorizationFailed(traceId, bindingId, identity, reason);
}
return session != null ? session.authorized : NOT_AUTHORIZED;
}
@@ -231,7 +232,7 @@ public String identity(
long sessionId)
{
JwtSession session = sessionsById.get(sessionId);
- return session != null ? session.subject : null;
+ return session != null ? session.identity : null;
}
@Override
@@ -298,51 +299,51 @@ private JwtSessionStore supplySessionStore(
private final class JwtSessionStore
{
private final long contextId;
- private final Map sessionsBySubject;
+ private final Map sessionsByIdentity;
private JwtSessionStore(
long contextId)
{
this.contextId = contextId;
- this.sessionsBySubject = new IdentityHashMap<>();
+ this.sessionsByIdentity = new IdentityHashMap<>();
}
private JwtSession supplySession(
- String subject,
+ String identity,
List roles)
{
- String subjectKey = subject != null ? subject.intern() : null;
- JwtSession session = sessionsBySubject.get(subjectKey);
+ String identityKey = identity != null ? identity.intern() : null;
+ JwtSession session = sessionsByIdentity.get(identityKey);
- if (subjectKey == null || session != null && roles != null && !supersetOf(session, roles))
+ if (identityKey == null || session != null && roles != null && !supersetOf(session, roles))
{
- session = newSession(subjectKey);
+ session = newSession(identityKey);
}
else
{
- session = sessionsBySubject.computeIfAbsent(subjectKey, this::newSharedSession);
+ session = sessionsByIdentity.computeIfAbsent(identityKey, this::newSharedSession);
}
return session;
}
private JwtSession newSharedSession(
- String subject)
+ String identity)
{
- return new JwtSession(supplyAuthorizedId.getAsLong(), subject, this::onUnshared);
+ return new JwtSession(supplyAuthorizedId.getAsLong(), identity, this::onUnshared);
}
private JwtSession newSession(
- String subject)
+ String identity)
{
- return new JwtSession(supplyAuthorizedId.getAsLong(), subject);
+ return new JwtSession(supplyAuthorizedId.getAsLong(), identity);
}
private void onUnshared(
JwtSession session)
{
- sessionsBySubject.remove(session.subject);
- if (sessionsBySubject.isEmpty())
+ sessionsByIdentity.remove(session.identity);
+ if (sessionsByIdentity.isEmpty())
{
sessionStoresByContextId.remove(contextId);
}
@@ -352,7 +353,7 @@ private void onUnshared(
private final class JwtSession
{
private final long authorized;
- private final String subject;
+ private final String identity;
private final Consumer unshare;
private String credentials;
@@ -366,18 +367,18 @@ private final class JwtSession
private JwtSession(
long authorized,
- String subject)
+ String identity)
{
- this(authorized, subject, null);
+ this(authorized, identity, null);
}
private JwtSession(
long authorized,
- String subject,
+ String identity,
Consumer unshare)
{
this.authorized = authorized;
- this.subject = subject;
+ this.identity = identity;
this.unshare = unshare;
}
@@ -385,7 +386,7 @@ boolean challenge(
long now)
{
final boolean challenge =
- subject != null &&
+ identity != null &&
challengeAt <= now && now < expiresAt &&
challengedAt < challengeAt;
diff --git a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/config/JwtOptionsConfigAdapter.java b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/config/JwtOptionsConfigAdapter.java
index 8c6330c1b3..bab73ac590 100644
--- a/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/config/JwtOptionsConfigAdapter.java
+++ b/runtime/guard-jwt/src/main/java/io/aklivity/zilla/runtime/guard/jwt/internal/config/JwtOptionsConfigAdapter.java
@@ -40,6 +40,7 @@ public final class JwtOptionsConfigAdapter implements OptionsConfigAdapterSpi, J
private static final String AUDIENCE_NAME = "audience";
private static final String KEYS_NAME = "keys";
private static final String CHALLENGE_NAME = "challenge";
+ private static final String IDENTITY_NAME = "identity";
private static final List KEYS_DEFAULT = emptyList();
@@ -92,6 +93,11 @@ public JsonObject adaptToJson(
object.add(CHALLENGE_NAME, jwtOptions.challenge.get().getSeconds());
}
+ if (jwtOptions.identity != null)
+ {
+ object.add(IDENTITY_NAME, jwtOptions.identity);
+ }
+
return object.build();
}
@@ -149,6 +155,11 @@ public OptionsConfig adaptFromJson(
jwtOptions.challenge(Duration.ofSeconds(object.getInt(CHALLENGE_NAME)));
}
+ if (object.containsKey(IDENTITY_NAME))
+ {
+ jwtOptions.identity(object.getString(IDENTITY_NAME));
+ }
+
return jwtOptions.build();
}
}
diff --git a/runtime/guard-jwt/src/test/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtGuardHandlerTest.java b/runtime/guard-jwt/src/test/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtGuardHandlerTest.java
index a19d95da95..6df44ab5f1 100644
--- a/runtime/guard-jwt/src/test/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtGuardHandlerTest.java
+++ b/runtime/guard-jwt/src/test/java/io/aklivity/zilla/runtime/guard/jwt/internal/JwtGuardHandlerTest.java
@@ -88,6 +88,40 @@ public void shouldAuthorize() throws Exception
assertTrue(guard.verify(sessionId, asList("read:stream", "write:stream")));
}
+ @Test
+ public void shouldAuthorizeWithCustomIdentity() throws Exception
+ {
+ Duration challenge = ofSeconds(3L);
+ JwtOptionsConfig options = JwtOptionsConfig.builder()
+ .inject(identity())
+ .issuer("test issuer")
+ .audience("testAudience")
+ .key(RFC7515_RS256_CONFIG)
+ .challenge(challenge)
+ .identity("username")
+ .build();
+ JwtGuardHandler guard = new JwtGuardHandler(options, context, new MutableLong(1L)::getAndIncrement);
+
+ Instant now = Instant.now();
+
+ JwtClaims claims = new JwtClaims();
+ claims.setClaim("iss", "test issuer");
+ claims.setClaim("aud", "testAudience");
+ claims.setClaim("username", "johndoe");
+ claims.setClaim("exp", now.getEpochSecond() + 10L);
+ claims.setClaim("scope", "read:stream write:stream");
+
+ String token = sign(claims.toJson(), "test", RFC7515_RS256, "RS256");
+
+ long sessionId = guard.reauthorize(0L, 0L, 101L, token);
+
+ assertThat(sessionId, not(equalTo(0L)));
+ assertThat(guard.identity(sessionId), equalTo("johndoe"));
+ assertThat(guard.expiresAt(sessionId), equalTo(ofSeconds(now.getEpochSecond() + 10L).toMillis()));
+ assertThat(guard.expiringAt(sessionId), equalTo(ofSeconds(now.getEpochSecond() + 10L).minus(challenge).toMillis()));
+ assertTrue(guard.verify(sessionId, asList("read:stream", "write:stream")));
+ }
+
@Test
public void shouldChallengeDuringChallengeWindow() throws Exception
{
diff --git a/runtime/metrics-grpc/pom.xml b/runtime/metrics-grpc/pom.xml
index 8d13c7a77d..cc76d4ffd3 100644
--- a/runtime/metrics-grpc/pom.xml
+++ b/runtime/metrics-grpc/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/metrics-http/pom.xml b/runtime/metrics-http/pom.xml
index fbfdeac377..5e54ddd369 100644
--- a/runtime/metrics-http/pom.xml
+++ b/runtime/metrics-http/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/metrics-stream/pom.xml b/runtime/metrics-stream/pom.xml
index 616b23b386..3797a07cf3 100644
--- a/runtime/metrics-stream/pom.xml
+++ b/runtime/metrics-stream/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/model-avro/pom.xml b/runtime/model-avro/pom.xml
index d91dbc6375..87bf728b91 100644
--- a/runtime/model-avro/pom.xml
+++ b/runtime/model-avro/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/model-core/pom.xml b/runtime/model-core/pom.xml
index ab48cb4cec..a339c058f6 100644
--- a/runtime/model-core/pom.xml
+++ b/runtime/model-core/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/model-json/pom.xml b/runtime/model-json/pom.xml
index 193aa18b92..e160617d55 100644
--- a/runtime/model-json/pom.xml
+++ b/runtime/model-json/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/model-protobuf/pom.xml b/runtime/model-protobuf/pom.xml
index d027181acb..12ca2db469 100644
--- a/runtime/model-protobuf/pom.xml
+++ b/runtime/model-protobuf/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/pom.xml b/runtime/pom.xml
index f648ed44e9..5ffe088ab2 100644
--- a/runtime/pom.xml
+++ b/runtime/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/resolver-env/pom.xml b/runtime/resolver-env/pom.xml
index a56fdab514..f1c0282e9e 100644
--- a/runtime/resolver-env/pom.xml
+++ b/runtime/resolver-env/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/runtime/vault-filesystem/pom.xml b/runtime/vault-filesystem/pom.xml
index 4f94506026..692d3d47c7 100644
--- a/runtime/vault-filesystem/pom.xml
+++ b/runtime/vault-filesystem/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-asyncapi.spec/pom.xml b/specs/binding-asyncapi.spec/pom.xml
index 279c25be60..d06094f8b0 100644
--- a/specs/binding-asyncapi.spec/pom.xml
+++ b/specs/binding-asyncapi.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-echo.spec/pom.xml b/specs/binding-echo.spec/pom.xml
index ee764f5f34..1d670cb207 100644
--- a/specs/binding-echo.spec/pom.xml
+++ b/specs/binding-echo.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-fan.spec/pom.xml b/specs/binding-fan.spec/pom.xml
index b6889572a7..e958766e7c 100644
--- a/specs/binding-fan.spec/pom.xml
+++ b/specs/binding-fan.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-filesystem.spec/pom.xml b/specs/binding-filesystem.spec/pom.xml
index 5e7f73026f..658acdc779 100644
--- a/specs/binding-filesystem.spec/pom.xml
+++ b/specs/binding-filesystem.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-grpc-kafka.spec/pom.xml b/specs/binding-grpc-kafka.spec/pom.xml
index 16c7749599..03dbcf18aa 100644
--- a/specs/binding-grpc-kafka.spec/pom.xml
+++ b/specs/binding-grpc-kafka.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-grpc.spec/pom.xml b/specs/binding-grpc.spec/pom.xml
index 912eb08c15..caedaf2765 100644
--- a/specs/binding-grpc.spec/pom.xml
+++ b/specs/binding-grpc.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-http-filesystem.spec/pom.xml b/specs/binding-http-filesystem.spec/pom.xml
index 5e2a490211..f913b91f87 100644
--- a/specs/binding-http-filesystem.spec/pom.xml
+++ b/specs/binding-http-filesystem.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-http-kafka.spec/pom.xml b/specs/binding-http-kafka.spec/pom.xml
index 116c8e16ca..871e81f544 100644
--- a/specs/binding-http-kafka.spec/pom.xml
+++ b/specs/binding-http-kafka.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-http.spec/pom.xml b/specs/binding-http.spec/pom.xml
index 42dc068428..6cecaabc2d 100644
--- a/specs/binding-http.spec/pom.xml
+++ b/specs/binding-http.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-kafka-grpc.spec/pom.xml b/specs/binding-kafka-grpc.spec/pom.xml
index 268491b29f..96e689aa78 100644
--- a/specs/binding-kafka-grpc.spec/pom.xml
+++ b/specs/binding-kafka-grpc.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-kafka.spec/pom.xml b/specs/binding-kafka.spec/pom.xml
index b6f12d3497..21e53f8b6c 100644
--- a/specs/binding-kafka.spec/pom.xml
+++ b/specs/binding-kafka.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-mqtt-kafka.spec/pom.xml b/specs/binding-mqtt-kafka.spec/pom.xml
index 9a761dbe32..1ee013e8ae 100644
--- a/specs/binding-mqtt-kafka.spec/pom.xml
+++ b/specs/binding-mqtt-kafka.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-mqtt.spec/pom.xml b/specs/binding-mqtt.spec/pom.xml
index 93754aa66e..d265d955b7 100644
--- a/specs/binding-mqtt.spec/pom.xml
+++ b/specs/binding-mqtt.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-openapi-asyncapi.spec/pom.xml b/specs/binding-openapi-asyncapi.spec/pom.xml
index ff2f59f36e..94f3d851f2 100644
--- a/specs/binding-openapi-asyncapi.spec/pom.xml
+++ b/specs/binding-openapi-asyncapi.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-openapi.spec/pom.xml b/specs/binding-openapi.spec/pom.xml
index 69c54a0721..6d846b2711 100644
--- a/specs/binding-openapi.spec/pom.xml
+++ b/specs/binding-openapi.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-proxy.spec/pom.xml b/specs/binding-proxy.spec/pom.xml
index 9f1f424bb7..a7b1b2885a 100644
--- a/specs/binding-proxy.spec/pom.xml
+++ b/specs/binding-proxy.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-sse-kafka.spec/pom.xml b/specs/binding-sse-kafka.spec/pom.xml
index d239d8bc7e..45d3893762 100644
--- a/specs/binding-sse-kafka.spec/pom.xml
+++ b/specs/binding-sse-kafka.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-sse.spec/pom.xml b/specs/binding-sse.spec/pom.xml
index 08f93a2695..c0325cbb59 100644
--- a/specs/binding-sse.spec/pom.xml
+++ b/specs/binding-sse.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-tcp.spec/pom.xml b/specs/binding-tcp.spec/pom.xml
index 5391af661c..9b648b6f3f 100644
--- a/specs/binding-tcp.spec/pom.xml
+++ b/specs/binding-tcp.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-tls.spec/pom.xml b/specs/binding-tls.spec/pom.xml
index 9e6e183ffe..c6f545ee78 100644
--- a/specs/binding-tls.spec/pom.xml
+++ b/specs/binding-tls.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/binding-ws.spec/pom.xml b/specs/binding-ws.spec/pom.xml
index dfc4d053a0..b48c19c8fb 100644
--- a/specs/binding-ws.spec/pom.xml
+++ b/specs/binding-ws.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/catalog-apicurio.spec/pom.xml b/specs/catalog-apicurio.spec/pom.xml
index c7758fcfa0..00def73d78 100644
--- a/specs/catalog-apicurio.spec/pom.xml
+++ b/specs/catalog-apicurio.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/catalog-filesystem.spec/pom.xml b/specs/catalog-filesystem.spec/pom.xml
index 6e348598b2..a1eababef0 100644
--- a/specs/catalog-filesystem.spec/pom.xml
+++ b/specs/catalog-filesystem.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/catalog-inline.spec/pom.xml b/specs/catalog-inline.spec/pom.xml
index 09fe911b7e..7660cdc502 100644
--- a/specs/catalog-inline.spec/pom.xml
+++ b/specs/catalog-inline.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/catalog-karapace.spec/pom.xml b/specs/catalog-karapace.spec/pom.xml
index 73901d083f..181f306deb 100644
--- a/specs/catalog-karapace.spec/pom.xml
+++ b/specs/catalog-karapace.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/catalog-schema-registry.spec/pom.xml b/specs/catalog-schema-registry.spec/pom.xml
index c4069b3eb2..9a8a541641 100644
--- a/specs/catalog-schema-registry.spec/pom.xml
+++ b/specs/catalog-schema-registry.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/config/unregister/zilla.yaml b/specs/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/config/unregister/zilla.yaml
new file mode 100644
index 0000000000..aac3817758
--- /dev/null
+++ b/specs/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/config/unregister/zilla.yaml
@@ -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.
+#
+
+---
+name: test
+catalogs:
+ catalog0:
+ type: schema-registry
+ options:
+ url: http://localhost:8081
+bindings:
+ net0:
+ type: test
+ kind: server
+ options:
+ catalog:
+ catalog0:
+ - subject: items-snapshots-value
+ exit: app0
diff --git a/specs/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/streams/unregister.schema.rpt b/specs/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/streams/unregister.schema.rpt
new file mode 100644
index 0000000000..98873d56dd
--- /dev/null
+++ b/specs/catalog-schema-registry.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/schema/registry/streams/unregister.schema.rpt
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+
+accept "http://localhost:8081/subjects/items-snapshots-value"
+
+accepted
+connected
+
+read http:method "DELETE"
+read http:version "HTTP/1.1"
+read http:header "Host" "localhost:8081"
+
+read closed
+
+write http:status "200" "OK"
+write http:header "content-type" "application/vnd.schemaregistry.v1+json"
+write http:content-length
+
+write '[1]'
+
+write close
diff --git a/specs/engine.spec/pom.xml b/specs/engine.spec/pom.xml
index f57168b289..b32017696e 100644
--- a/specs/engine.spec/pom.xml
+++ b/specs/engine.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/exporter-otlp.spec/pom.xml b/specs/exporter-otlp.spec/pom.xml
index 4aae1ca78b..3de4da33e8 100644
--- a/specs/exporter-otlp.spec/pom.xml
+++ b/specs/exporter-otlp.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/exporter-prometheus.spec/pom.xml b/specs/exporter-prometheus.spec/pom.xml
index 2cf1d7212a..d1a2fbc17c 100644
--- a/specs/exporter-prometheus.spec/pom.xml
+++ b/specs/exporter-prometheus.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/exporter-stdout.spec/pom.xml b/specs/exporter-stdout.spec/pom.xml
index 1086bd5ecc..18b1557673 100644
--- a/specs/exporter-stdout.spec/pom.xml
+++ b/specs/exporter-stdout.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/filesystem-http.spec/pom.xml b/specs/filesystem-http.spec/pom.xml
index ce328f4b11..d3791991be 100644
--- a/specs/filesystem-http.spec/pom.xml
+++ b/specs/filesystem-http.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/guard-jwt.spec/pom.xml b/specs/guard-jwt.spec/pom.xml
index 7964825128..92ddafd962 100644
--- a/specs/guard-jwt.spec/pom.xml
+++ b/specs/guard-jwt.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/guard-jwt.spec/src/main/scripts/io/aklivity/zilla/specs/guard/jwt/schema/jwt.schema.patch.json b/specs/guard-jwt.spec/src/main/scripts/io/aklivity/zilla/specs/guard/jwt/schema/jwt.schema.patch.json
index 05aa10de29..e88157673e 100644
--- a/specs/guard-jwt.spec/src/main/scripts/io/aklivity/zilla/specs/guard/jwt/schema/jwt.schema.patch.json
+++ b/specs/guard-jwt.spec/src/main/scripts/io/aklivity/zilla/specs/guard/jwt/schema/jwt.schema.patch.json
@@ -83,6 +83,12 @@
{
"title": "Challenge",
"type": "integer"
+ },
+ "identity":
+ {
+ "title": "Identity",
+ "type": "string",
+ "default": "sub"
}
},
"additionalProperties": false
diff --git a/specs/metrics-grpc.spec/pom.xml b/specs/metrics-grpc.spec/pom.xml
index a5919639d3..3b61460c34 100644
--- a/specs/metrics-grpc.spec/pom.xml
+++ b/specs/metrics-grpc.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/metrics-http.spec/pom.xml b/specs/metrics-http.spec/pom.xml
index 7eae34dcc8..c167c0d929 100644
--- a/specs/metrics-http.spec/pom.xml
+++ b/specs/metrics-http.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/metrics-stream.spec/pom.xml b/specs/metrics-stream.spec/pom.xml
index 25aa3f6a28..4b8c5a824b 100644
--- a/specs/metrics-stream.spec/pom.xml
+++ b/specs/metrics-stream.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/model-avro.spec/pom.xml b/specs/model-avro.spec/pom.xml
index c0a1f14818..fd73e029b7 100644
--- a/specs/model-avro.spec/pom.xml
+++ b/specs/model-avro.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/model-core.spec/pom.xml b/specs/model-core.spec/pom.xml
index 2098be2739..0ad8c3c55a 100644
--- a/specs/model-core.spec/pom.xml
+++ b/specs/model-core.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/model-json.spec/pom.xml b/specs/model-json.spec/pom.xml
index 181821985f..10c8ce9306 100644
--- a/specs/model-json.spec/pom.xml
+++ b/specs/model-json.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/model-protobuf.spec/pom.xml b/specs/model-protobuf.spec/pom.xml
index f550f7f5ea..eeec3f4b7b 100644
--- a/specs/model-protobuf.spec/pom.xml
+++ b/specs/model-protobuf.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/pom.xml b/specs/pom.xml
index 04b95ef3b1..fd64db3db4 100644
--- a/specs/pom.xml
+++ b/specs/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.96
+ 0.9.97
../pom.xml
diff --git a/specs/vault-filesystem.spec/pom.xml b/specs/vault-filesystem.spec/pom.xml
index a2d2fe8dee..cf14664e05 100644
--- a/specs/vault-filesystem.spec/pom.xml
+++ b/specs/vault-filesystem.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.96
+ 0.9.97
../pom.xml