diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf7b31899e..93393ccb4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
# Changelog
+## [Unreleased](https://github.com/aklivity/zilla/tree/HEAD)
+
+[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.78...HEAD)
+
+**Implemented enhancements:**
+
+- Support `filesystem` catalog for local schemas [\#908](https://github.com/aklivity/zilla/issues/908)
+
+## [0.9.78](https://github.com/aklivity/zilla/tree/0.9.78) (2024-04-16)
+
+[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.77...0.9.78)
+
+**Merged pull requests:**
+
+- Ensure binding types are populated for `zilla dump` to dissect protocol-specific frames [\#928](https://github.com/aklivity/zilla/pull/928) ([attilakreiner](https://github.com/attilakreiner))
+
## [0.9.77](https://github.com/aklivity/zilla/tree/0.9.77) (2024-04-15)
[Full Changelog](https://github.com/aklivity/zilla/compare/0.9.76...0.9.77)
diff --git a/build/flyweight-maven-plugin/pom.xml b/build/flyweight-maven-plugin/pom.xml
index 34665e5db3..835a1082cd 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.78
+ 0.9.79
../pom.xml
diff --git a/build/pom.xml b/build/pom.xml
index 3b227d3e8e..86a6313d31 100644
--- a/build/pom.xml
+++ b/build/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/cloud/docker-image/pom.xml b/cloud/docker-image/pom.xml
index 45989ce01d..fb65026b3e 100644
--- a/cloud/docker-image/pom.xml
+++ b/cloud/docker-image/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
cloud
- 0.9.78
+ 0.9.79
../pom.xml
@@ -175,6 +175,12 @@
${project.version}
runtime
+
+ ${project.groupId}
+ catalog-filesystem
+ ${project.version}
+ runtime
+
${project.groupId}
catalog-inline
diff --git a/cloud/docker-image/src/main/docker/zpm.json.template b/cloud/docker-image/src/main/docker/zpm.json.template
index a4934b0242..392e048a10 100644
--- a/cloud/docker-image/src/main/docker/zpm.json.template
+++ b/cloud/docker-image/src/main/docker/zpm.json.template
@@ -36,6 +36,7 @@
"io.aklivity.zilla:binding-tls",
"io.aklivity.zilla:binding-ws",
"io.aklivity.zilla:catalog-apicurio",
+ "io.aklivity.zilla:catalog-filesystem",
"io.aklivity.zilla:catalog-inline",
"io.aklivity.zilla:catalog-karapace",
"io.aklivity.zilla:common",
diff --git a/cloud/helm-chart/pom.xml b/cloud/helm-chart/pom.xml
index 7a4f6857b4..8867fc87fb 100644
--- a/cloud/helm-chart/pom.xml
+++ b/cloud/helm-chart/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
cloud
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/cloud/pom.xml b/cloud/pom.xml
index bc5c91eaa1..2aeb72ff2e 100644
--- a/cloud/pom.xml
+++ b/cloud/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/conf/pom.xml b/conf/pom.xml
index 70135a619f..d0baf21a82 100644
--- a/conf/pom.xml
+++ b/conf/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/incubator/binding-amqp.spec/pom.xml b/incubator/binding-amqp.spec/pom.xml
index c276ddfa5d..331009404b 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.78
+ 0.9.79
../pom.xml
diff --git a/incubator/binding-amqp/pom.xml b/incubator/binding-amqp/pom.xml
index 5cd4bce270..d76570cb0f 100644
--- a/incubator/binding-amqp/pom.xml
+++ b/incubator/binding-amqp/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/incubator/catalog-filesystem.spec/COPYRIGHT b/incubator/catalog-filesystem.spec/COPYRIGHT
new file mode 100644
index 0000000000..0cb10b6f62
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/COPYRIGHT
@@ -0,0 +1,12 @@
+Copyright ${copyrightYears} Aklivity Inc
+
+Licensed under the Aklivity Community License (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at
+
+ https://www.aklivity.io/aklivity-community-license/
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
diff --git a/incubator/catalog-filesystem.spec/LICENSE b/incubator/catalog-filesystem.spec/LICENSE
new file mode 100644
index 0000000000..f6abb6327b
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/LICENSE
@@ -0,0 +1,114 @@
+ Aklivity Community License Agreement
+ Version 1.0
+
+This Aklivity Community License Agreement Version 1.0 (the “Agreement”) sets
+forth the terms on which Aklivity, Inc. (“Aklivity”) makes available certain
+software made available by Aklivity under this Agreement (the “Software”). BY
+INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE,
+YOU AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO
+SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE SOFTWARE. IF YOU ARE RECEIVING
+THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU
+HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS
+AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you, an individual, or
+the entity on whose behalf you are receiving the Software.
+
+ 1. LICENSE GRANT AND CONDITIONS.
+
+ 1.1 License. Subject to the terms and conditions of this Agreement,
+ Aklivity hereby grants to Licensee a non-exclusive, royalty-free,
+ worldwide, non-transferable, non-sublicenseable license during the term
+ of this Agreement to: (a) use the Software; (b) prepare modifications and
+ derivative works of the Software; (c) distribute the Software (including
+ without limitation in source code or object code form); and (d) reproduce
+ copies of the Software (the “License”). Licensee is not granted the
+ right to, and Licensee shall not, exercise the License for an Excluded
+ Purpose. For purposes of this Agreement, “Excluded Purpose” means making
+ available any software-as-a-service, platform-as-a-service,
+ infrastructure-as-a-service or other similar online service that competes
+ with Aklivity products or services that provide the Software.
+
+ 1.2 Conditions. In consideration of the License, Licensee’s distribution
+ of the Software is subject to the following conditions:
+
+ (a) Licensee must cause any Software modified by Licensee to carry
+ prominent notices stating that Licensee modified the Software.
+
+ (b) On each Software copy, Licensee shall reproduce and not remove or
+ alter all Aklivity or third party copyright or other proprietary
+ notices contained in the Software, and Licensee must provide the
+ notice below with each copy.
+
+ “This software is made available by Aklivity, Inc., under the
+ terms of the Aklivity Community License Agreement, Version 1.0
+ located at http://www.Aklivity.io/Aklivity-community-license. BY
+ INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF
+ THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.”
+
+ 1.3 Licensee Modifications. Licensee may add its own copyright notices
+ to modifications made by Licensee and may provide additional or different
+ license terms and conditions for use, reproduction, or distribution of
+ Licensee’s modifications. While redistributing the Software or
+ modifications thereof, Licensee may choose to offer, for a fee or free of
+ charge, support, warranty, indemnity, or other obligations. Licensee, and
+ not Aklivity, will be responsible for any such obligations.
+
+ 1.4 No Sublicensing. The License does not include the right to
+ sublicense the Software, however, each recipient to which Licensee
+ provides the Software may exercise the Licenses so long as such recipient
+ agrees to the terms and conditions of this Agreement.
+
+ 2. TERM AND TERMINATION. This Agreement will continue unless and until
+ earlier terminated as set forth herein. If Licensee breaches any of its
+ conditions or obligations under this Agreement, this Agreement will
+ terminate automatically and the License will terminate automatically and
+ permanently.
+
+ 3. INTELLECTUAL PROPERTY. As between the parties, Aklivity will retain all
+ right, title, and interest in the Software, and all intellectual property
+ rights therein. Aklivity hereby reserves all rights not expressly granted
+ to Licensee in this Agreement. Aklivity hereby reserves all rights in its
+ trademarks and service marks, and no licenses therein are granted in this
+ Agreement.
+
+ 4. DISCLAIMER. Aklivity HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND
+ CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY
+ DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ PURPOSE, WITH RESPECT TO THE SOFTWARE.
+
+ 5. LIMITATION OF LIABILITY. Aklivity WILL NOT BE LIABLE FOR ANY DAMAGES OF
+ ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL,
+ SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL
+ APPLY TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+
+ 6.GENERAL.
+
+ 6.1 Governing Law. This Agreement will be governed by and interpreted in
+ accordance with the laws of the state of California, without reference to
+ its conflict of laws principles. If Licensee is located within the
+ United States, all disputes arising out of this Agreement are subject to
+ the exclusive jurisdiction of courts located in Santa Clara County,
+ California. USA. If Licensee is located outside of the United States,
+ any dispute, controversy or claim arising out of or relating to this
+ Agreement will be referred to and finally determined by arbitration in
+ accordance with the JAMS International Arbitration Rules. The tribunal
+ will consist of one arbitrator. The place of arbitration will be Palo
+ Alto, California. The language to be used in the arbitral proceedings
+ will be English. Judgment upon the award rendered by the arbitrator may
+ be entered in any court having jurisdiction thereof.
+
+ 6.2 Assignment. Licensee is not authorized to assign its rights under
+ this Agreement to any third party. Aklivity may freely assign its rights
+ under this Agreement to any third party.
+
+ 6.3 Other. This Agreement is the entire agreement between the parties
+ regarding the subject matter hereof. No amendment or modification of
+ this Agreement will be valid or binding upon the parties unless made in
+ writing and signed by the duly authorized representatives of both
+ parties. In the event that any provision, including without limitation
+ any condition, of this Agreement is held to be unenforceable, this
+ Agreement and all licenses and rights granted hereunder will immediately
+ terminate. Waiver by Aklivity of a breach of any provision of this
+ Agreement or the failure by Aklivity to exercise any right hereunder
+ will not be construed as a waiver of any subsequent breach of that right
+ or as a waiver of any other right.
\ No newline at end of file
diff --git a/incubator/catalog-filesystem.spec/NOTICE b/incubator/catalog-filesystem.spec/NOTICE
new file mode 100644
index 0000000000..ed4c502c75
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/NOTICE
@@ -0,0 +1,23 @@
+Licensed under the Aklivity Community License (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at
+
+ https://www.aklivity.io/aklivity-community-license/
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+
+This project includes:
+ agrona under The Apache License, Version 2.0
+ ANTLR 4 Runtime under BSD-3-Clause
+ ICU4J under Unicode/ICU License
+ Jakarta JSON Processing API under Eclipse Public License 2.0 or GNU General Public License, version 2 with the GNU Classpath Exception
+ Java Unified Expression Language API under The Apache Software License, Version 2.0
+ Java Unified Expression Language Implementation under The Apache Software License, Version 2.0
+ k3po/lang under The Apache Software License, Version 2.0
+ Kaazing Corporation License under The Apache Software License, Version 2.0
+ org.leadpony.justify under The Apache Software License, Version 2.0
+ zilla::specs::engine.spec under The Apache Software License, Version 2.0
+
diff --git a/incubator/catalog-filesystem.spec/NOTICE.template b/incubator/catalog-filesystem.spec/NOTICE.template
new file mode 100644
index 0000000000..209ca12f74
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/NOTICE.template
@@ -0,0 +1,13 @@
+Licensed under the Aklivity Community License (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at
+
+ https://www.aklivity.io/aklivity-community-license/
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+
+This project includes:
+#GENERATED_NOTICES#
diff --git a/incubator/catalog-filesystem.spec/mvnw b/incubator/catalog-filesystem.spec/mvnw
new file mode 100755
index 0000000000..d2f0ea3808
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/mvnw
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/incubator/catalog-filesystem.spec/mvnw.cmd b/incubator/catalog-filesystem.spec/mvnw.cmd
new file mode 100644
index 0000000000..b26ab24f03
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/mvnw.cmd
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/incubator/catalog-filesystem.spec/pom.xml b/incubator/catalog-filesystem.spec/pom.xml
new file mode 100644
index 0000000000..499001b2b9
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/pom.xml
@@ -0,0 +1,135 @@
+
+
+
+ 4.0.0
+
+ io.aklivity.zilla
+ incubator
+ 0.9.79
+ ../pom.xml
+
+
+ catalog-filesystem.spec
+ zilla::incubator::catalog-filesystem.spec
+
+
+
+ Aklivity Community License Agreement
+ https://www.aklivity.io/aklivity-community-license/
+ repo
+
+
+
+
+ 11
+ 11
+ 0.98
+ 0
+
+
+
+
+ ${project.groupId}
+ engine.spec
+ ${project.version}
+
+
+ junit
+ junit
+ test
+
+
+ org.hamcrest
+ hamcrest-library
+ test
+
+
+
+
+
+
+ src/main/resources
+
+
+ src/main/scripts
+
+
+
+
+
+ org.jasig.maven
+ maven-notice-plugin
+
+
+ ${project.groupId}
+ flyweight-maven-plugin
+ ${project.version}
+
+ core filesystem
+ io.aklivity.zilla.specs.catalog.filesystem.internal.types
+
+
+
+
+ validate
+ generate
+
+
+
+
+
+ com.mycila
+ license-maven-plugin
+
+
+ **/mqtt.yaml
+
+
+
+
+ maven-checkstyle-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ org.moditect
+ moditect-maven-plugin
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+
+ io/aklivity/zilla/specs/catalog/filesystem/internal/types/**/*.class
+
+
+
+ BUNDLE
+
+
+ INSTRUCTION
+ COVEREDRATIO
+ ${jacoco.coverage.ratio}
+
+
+ CLASS
+ MISSEDCOUNT
+ ${jacoco.missed.count}
+
+
+
+
+
+
+
+
+
diff --git a/incubator/catalog-filesystem.spec/src/main/moditect/module-info.java b/incubator/catalog-filesystem.spec/src/main/moditect/module-info.java
new file mode 100644
index 0000000000..bec4ba60f7
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/src/main/moditect/module-info.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+open module io.aklivity.zilla.specs.catalog.filesystem
+{
+ requires transitive io.aklivity.zilla.specs.engine;
+}
diff --git a/incubator/catalog-filesystem.spec/src/main/resources/META-INF/zilla/filesystem.idl b/incubator/catalog-filesystem.spec/src/main/resources/META-INF/zilla/filesystem.idl
new file mode 100644
index 0000000000..1918ca6302
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/src/main/resources/META-INF/zilla/filesystem.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+scope filesystem
+{
+ scope event
+ {
+ enum FilesystemEventType (uint8)
+ {
+ FILE_NOT_FOUND (1)
+ }
+
+ struct FilesystemFileNotFoundEx extends core::stream::Extension
+ {
+ string16 location;
+ }
+
+ union FilesystemEventEx switch (FilesystemEventType)
+ {
+ case FILE_NOT_FOUND: FilesystemFileNotFoundEx fileNotFound;
+ }
+ }
+}
diff --git a/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/asyncapi/mqtt.yaml b/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/asyncapi/mqtt.yaml
new file mode 100644
index 0000000000..9cbf82b254
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/asyncapi/mqtt.yaml
@@ -0,0 +1,11 @@
+asyncapi: 3.0.0
+info:
+ title: Zilla MQTT Proxy
+ version: 1.0.0
+ license:
+ name: Aklivity Community License
+servers:
+ plain:
+ host: mqtt://localhost:7183
+ protocol: mqtt
+defaultContentType: application/json
diff --git a/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/catalog.yaml b/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/catalog.yaml
new file mode 100644
index 0000000000..853b3f08a4
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/catalog.yaml
@@ -0,0 +1,25 @@
+#
+# 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: filesystem
+ options:
+ subjects:
+ subject1:
+ path: asyncapi/mqtt.yaml
+
diff --git a/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/event.yaml b/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/event.yaml
new file mode 100644
index 0000000000..63872968f3
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/config/event.yaml
@@ -0,0 +1,41 @@
+#
+# Copyright 2021-2023 Aklivity Inc
+#
+# Licensed under the Aklivity Community License (the "License"); you may not use
+# this file except in compliance with the License. You may obtain a copy of the
+# License at
+#
+# https://www.aklivity.io/aklivity-community-license/
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OF ANY KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations under the License.
+#
+
+---
+name: test
+telemetry:
+ exporters:
+ exporter0:
+ type: test
+ options:
+ events:
+ - qname: test.catalog0
+ id: catalog.filesystem.file.not.found
+ message: FILE_NOT_FOUND asyncapi/kafka.yaml
+catalogs:
+ catalog0:
+ type: filesystem
+ options:
+ subjects:
+ subject1:
+ path: asyncapi/kafka.yaml
+bindings:
+ net0:
+ type: test
+ kind: server
+ options:
+ catalogs:
+ - catalog0
+ exit: app0
diff --git a/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/schema/filesystem.schema.patch.json b/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/schema/filesystem.schema.patch.json
new file mode 100644
index 0000000000..341ec9701c
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/catalog/filesystem/schema/filesystem.schema.patch.json
@@ -0,0 +1,66 @@
+[
+ {
+ "op": "add",
+ "path": "/$defs/catalog/properties/type/enum/-",
+ "value": "filesystem"
+ },
+ {
+ "op": "add",
+ "path": "/$defs/catalog/allOf/-",
+ "value":
+ {
+ "if":
+ {
+ "properties":
+ {
+ "type":
+ {
+ "const": "filesystem"
+ }
+ }
+ },
+ "then":
+ {
+ "properties":
+ {
+ "type":
+ {
+ "const": "filesystem"
+ },
+ "options":
+ {
+ "properties":
+ {
+ "subjects":
+ {
+ "type": "object",
+ "patternProperties":
+ {
+ "^[a-zA-Z]+[a-zA-Z0-9\\._\\-]*$":
+ {
+ "title": "Subject",
+ "type": "object",
+ "properties":
+ {
+ "path":
+ {
+ "type": "string"
+ }
+ },
+ "required":
+ [
+ "path"
+ ],
+ "additionalProperties": false
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ }
+]
diff --git a/incubator/catalog-filesystem.spec/src/test/java/io/aklivity/zilla/specs/catalog/filesystem/config/SchemaTest.java b/incubator/catalog-filesystem.spec/src/test/java/io/aklivity/zilla/specs/catalog/filesystem/config/SchemaTest.java
new file mode 100644
index 0000000000..4abc31377f
--- /dev/null
+++ b/incubator/catalog-filesystem.spec/src/test/java/io/aklivity/zilla/specs/catalog/filesystem/config/SchemaTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.specs.catalog.filesystem.config;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+
+import jakarta.json.JsonObject;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import io.aklivity.zilla.specs.engine.config.ConfigSchemaRule;
+
+public class SchemaTest
+{
+ @Rule
+ public final ConfigSchemaRule schema = new ConfigSchemaRule()
+ .schemaPatch("io/aklivity/zilla/specs/catalog/filesystem/schema/filesystem.schema.patch.json")
+ .configurationRoot("io/aklivity/zilla/specs/catalog/filesystem/config");
+
+ @Test
+ public void shouldValidateCatalog()
+ {
+ JsonObject config = schema.validate("catalog.yaml");
+
+ assertThat(config, not(nullValue()));
+ }
+}
diff --git a/incubator/catalog-filesystem/COPYRIGHT b/incubator/catalog-filesystem/COPYRIGHT
new file mode 100644
index 0000000000..0cb10b6f62
--- /dev/null
+++ b/incubator/catalog-filesystem/COPYRIGHT
@@ -0,0 +1,12 @@
+Copyright ${copyrightYears} Aklivity Inc
+
+Licensed under the Aklivity Community License (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at
+
+ https://www.aklivity.io/aklivity-community-license/
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
diff --git a/incubator/catalog-filesystem/LICENSE b/incubator/catalog-filesystem/LICENSE
new file mode 100644
index 0000000000..f6abb6327b
--- /dev/null
+++ b/incubator/catalog-filesystem/LICENSE
@@ -0,0 +1,114 @@
+ Aklivity Community License Agreement
+ Version 1.0
+
+This Aklivity Community License Agreement Version 1.0 (the “Agreement”) sets
+forth the terms on which Aklivity, Inc. (“Aklivity”) makes available certain
+software made available by Aklivity under this Agreement (the “Software”). BY
+INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE,
+YOU AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO
+SUCH TERMS AND CONDITIONS, YOU MUST NOT USE THE SOFTWARE. IF YOU ARE RECEIVING
+THE SOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU
+HAVE THE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS
+AGREEMENT ON BEHALF OF SUCH ENTITY. “Licensee” means you, an individual, or
+the entity on whose behalf you are receiving the Software.
+
+ 1. LICENSE GRANT AND CONDITIONS.
+
+ 1.1 License. Subject to the terms and conditions of this Agreement,
+ Aklivity hereby grants to Licensee a non-exclusive, royalty-free,
+ worldwide, non-transferable, non-sublicenseable license during the term
+ of this Agreement to: (a) use the Software; (b) prepare modifications and
+ derivative works of the Software; (c) distribute the Software (including
+ without limitation in source code or object code form); and (d) reproduce
+ copies of the Software (the “License”). Licensee is not granted the
+ right to, and Licensee shall not, exercise the License for an Excluded
+ Purpose. For purposes of this Agreement, “Excluded Purpose” means making
+ available any software-as-a-service, platform-as-a-service,
+ infrastructure-as-a-service or other similar online service that competes
+ with Aklivity products or services that provide the Software.
+
+ 1.2 Conditions. In consideration of the License, Licensee’s distribution
+ of the Software is subject to the following conditions:
+
+ (a) Licensee must cause any Software modified by Licensee to carry
+ prominent notices stating that Licensee modified the Software.
+
+ (b) On each Software copy, Licensee shall reproduce and not remove or
+ alter all Aklivity or third party copyright or other proprietary
+ notices contained in the Software, and Licensee must provide the
+ notice below with each copy.
+
+ “This software is made available by Aklivity, Inc., under the
+ terms of the Aklivity Community License Agreement, Version 1.0
+ located at http://www.Aklivity.io/Aklivity-community-license. BY
+ INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF
+ THE SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.”
+
+ 1.3 Licensee Modifications. Licensee may add its own copyright notices
+ to modifications made by Licensee and may provide additional or different
+ license terms and conditions for use, reproduction, or distribution of
+ Licensee’s modifications. While redistributing the Software or
+ modifications thereof, Licensee may choose to offer, for a fee or free of
+ charge, support, warranty, indemnity, or other obligations. Licensee, and
+ not Aklivity, will be responsible for any such obligations.
+
+ 1.4 No Sublicensing. The License does not include the right to
+ sublicense the Software, however, each recipient to which Licensee
+ provides the Software may exercise the Licenses so long as such recipient
+ agrees to the terms and conditions of this Agreement.
+
+ 2. TERM AND TERMINATION. This Agreement will continue unless and until
+ earlier terminated as set forth herein. If Licensee breaches any of its
+ conditions or obligations under this Agreement, this Agreement will
+ terminate automatically and the License will terminate automatically and
+ permanently.
+
+ 3. INTELLECTUAL PROPERTY. As between the parties, Aklivity will retain all
+ right, title, and interest in the Software, and all intellectual property
+ rights therein. Aklivity hereby reserves all rights not expressly granted
+ to Licensee in this Agreement. Aklivity hereby reserves all rights in its
+ trademarks and service marks, and no licenses therein are granted in this
+ Agreement.
+
+ 4. DISCLAIMER. Aklivity HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND
+ CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY
+ DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ PURPOSE, WITH RESPECT TO THE SOFTWARE.
+
+ 5. LIMITATION OF LIABILITY. Aklivity WILL NOT BE LIABLE FOR ANY DAMAGES OF
+ ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL,
+ SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL
+ APPLY TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+
+ 6.GENERAL.
+
+ 6.1 Governing Law. This Agreement will be governed by and interpreted in
+ accordance with the laws of the state of California, without reference to
+ its conflict of laws principles. If Licensee is located within the
+ United States, all disputes arising out of this Agreement are subject to
+ the exclusive jurisdiction of courts located in Santa Clara County,
+ California. USA. If Licensee is located outside of the United States,
+ any dispute, controversy or claim arising out of or relating to this
+ Agreement will be referred to and finally determined by arbitration in
+ accordance with the JAMS International Arbitration Rules. The tribunal
+ will consist of one arbitrator. The place of arbitration will be Palo
+ Alto, California. The language to be used in the arbitral proceedings
+ will be English. Judgment upon the award rendered by the arbitrator may
+ be entered in any court having jurisdiction thereof.
+
+ 6.2 Assignment. Licensee is not authorized to assign its rights under
+ this Agreement to any third party. Aklivity may freely assign its rights
+ under this Agreement to any third party.
+
+ 6.3 Other. This Agreement is the entire agreement between the parties
+ regarding the subject matter hereof. No amendment or modification of
+ this Agreement will be valid or binding upon the parties unless made in
+ writing and signed by the duly authorized representatives of both
+ parties. In the event that any provision, including without limitation
+ any condition, of this Agreement is held to be unenforceable, this
+ Agreement and all licenses and rights granted hereunder will immediately
+ terminate. Waiver by Aklivity of a breach of any provision of this
+ Agreement or the failure by Aklivity to exercise any right hereunder
+ will not be construed as a waiver of any subsequent breach of that right
+ or as a waiver of any other right.
\ No newline at end of file
diff --git a/incubator/catalog-filesystem/NOTICE b/incubator/catalog-filesystem/NOTICE
new file mode 100644
index 0000000000..06744bbce0
--- /dev/null
+++ b/incubator/catalog-filesystem/NOTICE
@@ -0,0 +1,16 @@
+Licensed under the Aklivity Community License (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at
+
+ https://www.aklivity.io/aklivity-community-license/
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+
+This project includes:
+
+
+This project also includes code under copyright of the following entities:
+ https://github.com/reaktivity/
diff --git a/incubator/catalog-filesystem/NOTICE.template b/incubator/catalog-filesystem/NOTICE.template
new file mode 100644
index 0000000000..ff901de01b
--- /dev/null
+++ b/incubator/catalog-filesystem/NOTICE.template
@@ -0,0 +1,16 @@
+Licensed under the Aklivity Community License (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at
+
+ https://www.aklivity.io/aklivity-community-license/
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+
+This project includes:
+#GENERATED_NOTICES#
+
+This project also includes code under copyright of the following entities:
+ https://github.com/reaktivity/
\ No newline at end of file
diff --git a/incubator/catalog-filesystem/mvnw b/incubator/catalog-filesystem/mvnw
new file mode 100755
index 0000000000..d2f0ea3808
--- /dev/null
+++ b/incubator/catalog-filesystem/mvnw
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/incubator/catalog-filesystem/mvnw.cmd b/incubator/catalog-filesystem/mvnw.cmd
new file mode 100644
index 0000000000..b26ab24f03
--- /dev/null
+++ b/incubator/catalog-filesystem/mvnw.cmd
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/incubator/catalog-filesystem/pom.xml b/incubator/catalog-filesystem/pom.xml
new file mode 100644
index 0000000000..47e8191d91
--- /dev/null
+++ b/incubator/catalog-filesystem/pom.xml
@@ -0,0 +1,203 @@
+
+
+ 4.0.0
+
+ io.aklivity.zilla
+ incubator
+ 0.9.79
+ ../pom.xml
+
+
+ catalog-filesystem
+ zilla::incubator::catalog-filesystem
+
+
+
+ Aklivity Community License Agreement
+ https://www.aklivity.io/aklivity-community-license/
+ repo
+
+
+
+
+ 11
+ 11
+ 0.80
+ 0
+
+
+
+
+ ${project.groupId}
+ catalog-filesystem.spec
+ ${project.version}
+ provided
+
+
+ ${project.groupId}
+ engine
+ ${project.version}
+ provided
+
+
+ ${project.groupId}
+ engine
+ test-jar
+ ${project.version}
+ test
+
+
+ org.kaazing
+ k3po.junit
+ test
+
+
+ org.kaazing
+ k3po.lang
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+
+
+
+
+ org.jasig.maven
+ maven-notice-plugin
+
+
+ ${project.groupId}
+ flyweight-maven-plugin
+ ${project.version}
+
+ core filesystem internal
+ io.aklivity.zilla.runtime.catalog.filesystem.internal.types
+
+
+
+
+ generate
+
+
+
+
+
+ com.mycila
+ license-maven-plugin
+
+
+ maven-checkstyle-plugin
+
+
+ maven-dependency-plugin
+
+
+ process-resources
+
+ unpack
+
+
+
+
+ ${project.groupId}
+ catalog-filesystem.spec
+
+
+ ^\Qio/aklivity/zilla/specs/catalog/filesystem/\E
+ io/aklivity/zilla/runtime/catalog/filesystem/internal/
+
+
+
+
+ io/aklivity/zilla/specs/catalog/filesystem/schema/filesystem.schema.patch.json
+ ${project.build.directory}/classes
+
+
+
+ unpack-asyncapi
+ generate-sources
+
+ unpack
+
+
+
+
+ ${project.groupId}
+ catalog-filesystem.spec
+ ${project.version}
+ ${basedir}/target/test-classes
+ **\/*.yaml
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ org.moditect
+ moditect-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+
+ io/aklivity/zilla/runtime/catalog/filesystem/internal/types/**/*.class
+
+
+
+ BUNDLE
+
+
+ INSTRUCTION
+ COVEREDRATIO
+ ${jacoco.coverage.ratio}
+
+
+ CLASS
+ MISSEDCOUNT
+ ${jacoco.missed.count}
+
+
+
+
+
+
+
+ org.kaazing
+ k3po-maven-plugin
+
+
+ ${project.groupId}
+ engine
+ ${project.version}
+ test-jar
+
+
+ ${project.groupId}
+ engine
+ ${project.version}
+
+
+
+
+
+
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalog.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalog.java
new file mode 100644
index 0000000000..76c4a9a191
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalog.java
@@ -0,0 +1,51 @@
+/*
+ * 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.filesystem.internal;
+
+import java.net.URL;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.catalog.Catalog;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogContext;
+
+public class FilesystemCatalog implements Catalog
+{
+ public static final String NAME = "filesystem";
+
+ public FilesystemCatalog(
+ Configuration config)
+ {
+ }
+
+ @Override
+ public String name()
+ {
+ return FilesystemCatalog.NAME;
+ }
+
+ @Override
+ public CatalogContext supply(
+ EngineContext context)
+ {
+ return new FilesystemCatalogContext(context);
+ }
+
+ @Override
+ public URL type()
+ {
+ return getClass().getResource("schema/filesystem.schema.patch.json");
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogContext.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogContext.java
new file mode 100644
index 0000000000..531624609c
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogContext.java
@@ -0,0 +1,40 @@
+/*
+ * 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.filesystem.internal;
+
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemOptionsConfig;
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogContext;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler;
+import io.aklivity.zilla.runtime.engine.config.CatalogConfig;
+
+public class FilesystemCatalogContext implements CatalogContext
+{
+ private final EngineContext context;
+
+ public FilesystemCatalogContext(
+ EngineContext context)
+ {
+ this.context = context;
+ }
+
+ @Override
+ public CatalogHandler attach(
+ CatalogConfig catalog)
+ {
+ return new FilesystemCatalogHandler(
+ FilesystemOptionsConfig.class.cast(catalog.options), context, catalog.id);
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogFactorySpi.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogFactorySpi.java
new file mode 100644
index 0000000000..90f0b4984b
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogFactorySpi.java
@@ -0,0 +1,37 @@
+/*
+ * 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.filesystem.internal;
+
+import io.aklivity.zilla.runtime.common.feature.Incubating;
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.catalog.Catalog;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogFactorySpi;
+
+@Incubating
+public class FilesystemCatalogFactorySpi implements CatalogFactorySpi
+{
+ @Override
+ public String type()
+ {
+ return FilesystemCatalog.NAME;
+ }
+
+ @Override
+ public Catalog create(
+ Configuration config)
+ {
+ return new FilesystemCatalog(config);
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogHandler.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogHandler.java
new file mode 100644
index 0000000000..4716cff249
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogHandler.java
@@ -0,0 +1,99 @@
+/*
+ * 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.filesystem.internal;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.zip.CRC32C;
+
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemOptionsConfig;
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemSchemaConfig;
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler;
+
+public class FilesystemCatalogHandler implements CatalogHandler
+{
+ private final Map schemas;
+ private final Map schemaIds;
+ private final CRC32C crc32c;
+ private final FilesystemEventContext event;
+ private final long catalogId;
+ private final Function resolvePath;
+
+ public FilesystemCatalogHandler(
+ FilesystemOptionsConfig config,
+ EngineContext context,
+ long catalogId)
+ {
+ this.schemas = new HashMap<>();
+ this.schemaIds = new HashMap<>();
+ this.crc32c = new CRC32C();
+ this.event = new FilesystemEventContext(context);
+ this.resolvePath = context::resolvePath;
+ this.catalogId = catalogId;
+ registerSchema(config.subjects);
+ }
+
+ @Override
+ public String resolve(
+ int schemaId)
+ {
+ return schemas.getOrDefault(schemaId, null);
+ }
+
+ @Override
+ public int resolve(
+ String subject,
+ String version)
+ {
+ return schemaIds.getOrDefault(subject, NO_SCHEMA_ID);
+ }
+
+ private void registerSchema(
+ List configs)
+ {
+ for (FilesystemSchemaConfig config : configs)
+ {
+ try
+ {
+ URL storeURL = resolvePath.apply(config.path);
+ try (InputStream input = storeURL.openStream())
+ {
+ String schema = new String(input.readAllBytes());
+ int schemaId = generateCRC32C(schema);
+ schemas.put(schemaId, schema);
+ schemaIds.put(config.subject, schemaId);
+ }
+ }
+ catch (Exception ex)
+ {
+ event.fileNotFound(catalogId, config.path);
+ }
+ }
+ }
+
+ private int generateCRC32C(
+ String schema)
+ {
+ byte[] bytes = schema.getBytes();
+ crc32c.reset();
+ crc32c.update(bytes, 0, bytes.length);
+ return (int) crc32c.getValue();
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventContext.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventContext.java
new file mode 100644
index 0000000000..bc7cafa832
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventContext.java
@@ -0,0 +1,71 @@
+/*
+ * 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.filesystem.internal;
+
+import java.nio.ByteBuffer;
+import java.time.Clock;
+
+import org.agrona.MutableDirectBuffer;
+import org.agrona.concurrent.UnsafeBuffer;
+
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.types.event.FilesystemEventExFW;
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.types.event.FilesystemEventType;
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.binding.function.MessageConsumer;
+
+public class FilesystemEventContext
+{
+ private static final int EVENT_BUFFER_CAPACITY = 1024;
+
+ private final MutableDirectBuffer eventBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final MutableDirectBuffer extensionBuffer = new UnsafeBuffer(ByteBuffer.allocate(EVENT_BUFFER_CAPACITY));
+ private final EventFW.Builder eventRW = new EventFW.Builder();
+ private final FilesystemEventExFW.Builder schemaRegistryEventExRW = new FilesystemEventExFW.Builder();
+ private final int filesystemTypeId;
+ private final int fileNotFoundEventId;
+ private final MessageConsumer eventWriter;
+ private final Clock clock;
+
+ public FilesystemEventContext(
+ EngineContext context)
+ {
+ this.filesystemTypeId = context.supplyTypeId(FilesystemCatalog.NAME);
+ this.fileNotFoundEventId = context.supplyEventId("catalog.filesystem.file.not.found");
+ this.eventWriter = context.supplyEventWriter();
+ this.clock = context.clock();
+ }
+
+ public void fileNotFound(
+ long catalogId,
+ String location)
+ {
+ FilesystemEventExFW extension = schemaRegistryEventExRW
+ .wrap(extensionBuffer, 0, extensionBuffer.capacity())
+ .fileNotFound(e -> e
+ .typeId(FilesystemEventType.FILE_NOT_FOUND.value())
+ .location(location)
+ ).build();
+ EventFW event = eventRW
+ .wrap(eventBuffer, 0, eventBuffer.capacity())
+ .id(fileNotFoundEventId)
+ .timestamp(clock.millis())
+ .traceId(0L)
+ .namespacedId(catalogId)
+ .extension(extension.buffer(), extension.offset(), extension.limit())
+ .build();
+ eventWriter.accept(filesystemTypeId, event.buffer(), event.offset(), event.limit());
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventFormatter.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventFormatter.java
new file mode 100644
index 0000000000..1a64df8309
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventFormatter.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.runtime.catalog.filesystem.internal;
+
+import org.agrona.DirectBuffer;
+
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.types.String16FW;
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.types.event.EventFW;
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.types.event.FilesystemEventExFW;
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.types.event.FilesystemFileNotFoundExFW;
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterSpi;
+
+public final class FilesystemEventFormatter implements EventFormatterSpi
+{
+ private static final String FILE_NOT_FOUND = "FILE_NOT_FOUND %s";
+
+ private final EventFW eventRO = new EventFW();
+ private final FilesystemEventExFW schemaRegistryEventExRO = new FilesystemEventExFW();
+
+ FilesystemEventFormatter(
+ Configuration config)
+ {
+ }
+
+ public String format(
+ DirectBuffer buffer,
+ int index,
+ int length)
+ {
+ final EventFW event = eventRO.wrap(buffer, index, index + length);
+ final FilesystemEventExFW extension = schemaRegistryEventExRO
+ .wrap(event.extension().buffer(), event.extension().offset(), event.extension().limit());
+ String result = null;
+ switch (extension.kind())
+ {
+ case FILE_NOT_FOUND:
+ {
+ FilesystemFileNotFoundExFW ex = extension.fileNotFound();
+ result = String.format(FILE_NOT_FOUND, asString(ex.location()));
+ break;
+ }
+ }
+ return result;
+ }
+
+ private static String asString(
+ String16FW stringFW)
+ {
+ String s = stringFW.asString();
+ return s == null ? "" : s;
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventFormatterFactory.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventFormatterFactory.java
new file mode 100644
index 0000000000..dbf5db5c64
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemEventFormatterFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.runtime.catalog.filesystem.internal;
+
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi;
+
+public final class FilesystemEventFormatterFactory implements EventFormatterFactorySpi
+{
+ @Override
+ public FilesystemEventFormatter create(
+ Configuration config)
+ {
+ return new FilesystemEventFormatter(config);
+ }
+
+ @Override
+ public String type()
+ {
+ return FilesystemCatalog.NAME;
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfig.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfig.java
new file mode 100644
index 0000000000..f396581829
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfig.java
@@ -0,0 +1,42 @@
+/*
+ * 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.filesystem.internal.config;
+
+import java.util.List;
+import java.util.function.Function;
+
+import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
+
+public class FilesystemOptionsConfig extends OptionsConfig
+{
+ public final List subjects;
+
+ public static FilesystemOptionsConfigBuilder builder()
+ {
+ return new FilesystemOptionsConfigBuilder<>(FilesystemOptionsConfig.class::cast);
+ }
+
+ public static FilesystemOptionsConfigBuilder builder(
+ Function mapper)
+ {
+ return new FilesystemOptionsConfigBuilder<>(mapper);
+ }
+
+ public FilesystemOptionsConfig(
+ List subjects)
+ {
+ this.subjects = subjects;
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigAdapter.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigAdapter.java
new file mode 100644
index 0000000000..f8c5347cd4
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigAdapter.java
@@ -0,0 +1,88 @@
+/*
+ * 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.filesystem.internal.config;
+
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+import jakarta.json.bind.adapter.JsonbAdapter;
+
+import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
+import io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi;
+
+public class FilesystemOptionsConfigAdapter implements OptionsConfigAdapterSpi, JsonbAdapter
+{
+ private static final String SUBJECTS_NAME = "subjects";
+ private static final String PATH_NAME = "path";
+
+ @Override
+ public Kind kind()
+ {
+ return Kind.CATALOG;
+ }
+
+ @Override
+ public String type()
+ {
+ return "filesystem";
+ }
+
+ @Override
+ public JsonObject adaptToJson(
+ OptionsConfig options)
+ {
+ FilesystemOptionsConfig config = (FilesystemOptionsConfig) options;
+ JsonObjectBuilder subjects = Json.createObjectBuilder();
+
+ if (config.subjects != null && !config.subjects.isEmpty())
+ {
+ JsonObjectBuilder catalogs = Json.createObjectBuilder();
+ for (FilesystemSchemaConfig schema : config.subjects)
+ {
+ JsonObjectBuilder schemaJson = Json.createObjectBuilder();
+
+ schemaJson.add(PATH_NAME, schema.path);
+
+ catalogs.add(schema.subject, schemaJson);
+ }
+ subjects.add(SUBJECTS_NAME, catalogs);
+ }
+ return subjects.build();
+ }
+
+ @Override
+ public OptionsConfig adaptFromJson(
+ JsonObject object)
+ {
+ FilesystemOptionsConfigBuilder options = FilesystemOptionsConfig.builder();
+ if (object != null)
+ {
+ if (object.containsKey(SUBJECTS_NAME))
+ {
+ JsonObject subjectsJson = object.getJsonObject(SUBJECTS_NAME);
+ for (String subject: subjectsJson.keySet())
+ {
+ JsonObject schemaJson = subjectsJson.getJsonObject(subject);
+
+ String url = schemaJson.getString(PATH_NAME);
+
+ options.subjects(new FilesystemSchemaConfig(subject, url));
+ }
+ }
+ }
+
+ return options.build();
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigBuilder.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigBuilder.java
new file mode 100644
index 0000000000..8133071600
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigBuilder.java
@@ -0,0 +1,64 @@
+/*
+ * 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.filesystem.internal.config;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+import io.aklivity.zilla.runtime.engine.config.ConfigBuilder;
+import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
+
+public final class FilesystemOptionsConfigBuilder extends ConfigBuilder>
+{
+ private final Function mapper;
+
+ private List subjects;
+
+ FilesystemOptionsConfigBuilder(
+ Function mapper)
+ {
+ this.mapper = mapper;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Class> thisType()
+ {
+ return (Class>) getClass();
+ }
+
+ public FilesystemSchemaConfigBuilder> subjects()
+ {
+ return new FilesystemSchemaConfigBuilder<>(this::subjects);
+ }
+
+ public FilesystemOptionsConfigBuilder subjects(
+ FilesystemSchemaConfig config)
+ {
+ if (subjects == null)
+ {
+ subjects = new ArrayList<>();
+ }
+ subjects.add(config);
+ return this;
+ }
+
+ @Override
+ public T build()
+ {
+ return mapper.apply(new FilesystemOptionsConfig(subjects));
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemSchemaConfig.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemSchemaConfig.java
new file mode 100644
index 0000000000..538339138d
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemSchemaConfig.java
@@ -0,0 +1,29 @@
+/*
+ * 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.filesystem.internal.config;
+
+public class FilesystemSchemaConfig
+{
+ public final String subject;
+ public final String path;
+
+ public FilesystemSchemaConfig(
+ String subject,
+ String path)
+ {
+ this.subject = subject;
+ this.path = path;
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemSchemaConfigBuilder.java b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemSchemaConfigBuilder.java
new file mode 100644
index 0000000000..f949e20642
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemSchemaConfigBuilder.java
@@ -0,0 +1,60 @@
+/*
+ * 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.filesystem.internal.config;
+
+import java.util.function.Function;
+
+import io.aklivity.zilla.runtime.engine.config.ConfigBuilder;
+
+public class FilesystemSchemaConfigBuilder extends ConfigBuilder>
+{
+ private final Function mapper;
+
+ private String subject;
+ private String path;
+
+ public FilesystemSchemaConfigBuilder(
+ Function mapper)
+ {
+ this.mapper = mapper;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Class> thisType()
+ {
+ return (Class>) getClass();
+ }
+
+ public FilesystemSchemaConfigBuilder subject(
+ String subject)
+ {
+ this.subject = subject;
+ return this;
+ }
+
+ public FilesystemSchemaConfigBuilder path(
+ String path)
+ {
+ this.path = path;
+ return this;
+ }
+
+ @Override
+ public T build()
+ {
+ return mapper.apply(new FilesystemSchemaConfig(subject, path));
+ }
+}
diff --git a/incubator/catalog-filesystem/src/main/moditect/module-info.java b/incubator/catalog-filesystem/src/main/moditect/module-info.java
new file mode 100644
index 0000000000..8a4d9fcabf
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/moditect/module-info.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+module io.aklivity.zilla.runtime.catalog.filesystem
+{
+ requires io.aklivity.zilla.runtime.engine;
+
+ provides io.aklivity.zilla.runtime.engine.catalog.CatalogFactorySpi
+ with io.aklivity.zilla.runtime.catalog.filesystem.internal.FilesystemCatalogFactorySpi;
+
+ provides io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi
+ with io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemOptionsConfigAdapter;
+
+ provides io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
+ with io.aklivity.zilla.runtime.catalog.filesystem.internal.FilesystemEventFormatterFactory;
+}
diff --git a/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.catalog.CatalogFactorySpi b/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.catalog.CatalogFactorySpi
new file mode 100644
index 0000000000..5f177925f1
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.catalog.CatalogFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.catalog.filesystem.internal.FilesystemCatalogFactorySpi
diff --git a/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi b/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi
new file mode 100644
index 0000000000..81353f9925
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemOptionsConfigAdapter
diff --git a/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi b/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
new file mode 100644
index 0000000000..e1c1c2536c
--- /dev/null
+++ b/incubator/catalog-filesystem/src/main/resources/META-INF/services/io.aklivity.zilla.runtime.engine.event.EventFormatterFactorySpi
@@ -0,0 +1 @@
+io.aklivity.zilla.runtime.catalog.filesystem.internal.FilesystemEventFormatterFactory
\ No newline at end of file
diff --git a/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/EventIT.java b/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/EventIT.java
new file mode 100644
index 0000000000..21180d34df
--- /dev/null
+++ b/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/EventIT.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021-2023 Aklivity Inc
+ *
+ * Licensed under the Aklivity Community License (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * https://www.aklivity.io/aklivity-community-license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package io.aklivity.zilla.runtime.catalog.filesystem.internal;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.rules.RuleChain.outerRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.DisableOnDebug;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.kaazing.k3po.junit.annotation.Specification;
+import org.kaazing.k3po.junit.rules.K3poRule;
+
+import io.aklivity.zilla.runtime.engine.test.EngineRule;
+import io.aklivity.zilla.runtime.engine.test.annotation.Configuration;
+
+public class EventIT
+{
+ private final K3poRule k3po = new K3poRule()
+ .addScriptRoot("net", "io/aklivity/zilla/specs/engine/streams/network")
+ .addScriptRoot("app", "io/aklivity/zilla/specs/engine/streams/application");
+
+ private final TestRule timeout = new DisableOnDebug(new Timeout(10, SECONDS));
+
+ private final EngineRule engine = new EngineRule()
+ .directory("target/zilla-itests")
+ .countersBufferCapacity(4096)
+ .configurationRoot("io/aklivity/zilla/specs/catalog/filesystem/config")
+ .external("app0")
+ .clean();
+
+ @Rule
+ public final TestRule chain = outerRule(engine).around(k3po).around(timeout);
+
+ @Test
+ @Configuration("event.yaml")
+ @Specification({
+ "${net}/event/client",
+ "${app}/event/server"
+ })
+ public void shouldLogEvents() throws Exception
+ {
+ k3po.finish();
+ }
+}
diff --git a/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogFactoryTest.java b/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogFactoryTest.java
new file mode 100644
index 0000000000..042367e125
--- /dev/null
+++ b/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemCatalogFactoryTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.filesystem.internal;
+
+import static java.util.Collections.singletonList;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import java.net.URL;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemOptionsConfig;
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemSchemaConfig;
+import io.aklivity.zilla.runtime.engine.Configuration;
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.catalog.Catalog;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogContext;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogFactory;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler;
+import io.aklivity.zilla.runtime.engine.config.CatalogConfig;
+
+public class FilesystemCatalogFactoryTest
+{
+ @Test
+ public void shouldLoadAndCreate()
+ {
+ Configuration config = new Configuration();
+ CatalogFactory factory = CatalogFactory.instantiate();
+ Catalog catalog = factory.create("filesystem", config);
+
+ assertThat(catalog, instanceOf(FilesystemCatalog.class));
+ assertEquals("filesystem", catalog.name());
+
+ EngineContext engineContext = mock(EngineContext.class);
+ URL url = FilesystemCatalogFactoryTest.class
+ .getResource("../../../../specs/catalog/filesystem/config/asyncapi/mqtt.yaml");
+ Mockito.doReturn(url).when(engineContext).resolvePath("asyncapi/mqtt.yaml");
+
+ CatalogContext context = catalog.supply(engineContext);
+ assertThat(context, instanceOf(FilesystemCatalogContext.class));
+
+ FilesystemOptionsConfig catalogConfig =
+ new FilesystemOptionsConfig(singletonList(
+ new FilesystemSchemaConfig("subject1", "asyncapi/mqtt.yaml")));
+
+ CatalogConfig options = new CatalogConfig("test", "catalog0", "filesystem", catalogConfig);
+ CatalogHandler handler = context.attach(options);
+
+ assertThat(handler, instanceOf(FilesystemCatalogHandler.class));
+ }
+}
diff --git a/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemIT.java b/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemIT.java
new file mode 100644
index 0000000000..58b6675c2d
--- /dev/null
+++ b/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/FilesystemIT.java
@@ -0,0 +1,111 @@
+/*
+ * 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.filesystem.internal;
+
+import static java.util.Collections.singletonList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import java.net.URL;
+
+import org.agrona.DirectBuffer;
+import org.agrona.concurrent.UnsafeBuffer;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemOptionsConfig;
+import io.aklivity.zilla.runtime.catalog.filesystem.internal.config.FilesystemSchemaConfig;
+import io.aklivity.zilla.runtime.engine.EngineContext;
+import io.aklivity.zilla.runtime.engine.catalog.CatalogHandler;
+import io.aklivity.zilla.runtime.engine.model.function.ValueConsumer;
+
+public class FilesystemIT
+{
+ private FilesystemOptionsConfig config;
+ private EngineContext context = mock(EngineContext.class);
+
+ @Before
+ public void setup()
+ {
+ config = new FilesystemOptionsConfig(singletonList(
+ new FilesystemSchemaConfig("subject1", "asyncapi/mqtt.yaml")));
+
+ URL url = FilesystemIT.class.getResource("../../../../specs/catalog/filesystem/config/asyncapi/mqtt.yaml");
+ Mockito.doReturn(url).when(context).resolvePath("asyncapi/mqtt.yaml");
+ }
+
+ @Test
+ public void shouldResolveSchemaViaSchemaId()
+ {
+ String expected = "asyncapi: 3.0.0\n" +
+ "info:\n" +
+ " title: Zilla MQTT Proxy\n" +
+ " version: 1.0.0\n" +
+ " license:\n" +
+ " name: Aklivity Community License\n" +
+ "servers:\n" +
+ " plain:\n" +
+ " host: mqtt://localhost:7183\n" +
+ " protocol: mqtt\n" +
+ "defaultContentType: application/json\n";
+
+ FilesystemCatalogHandler catalog = new FilesystemCatalogHandler(config, context, 0L);
+
+ int schemaId = catalog.resolve("subject1", "latest");
+ String schema = catalog.resolve(schemaId);
+
+ assertThat(schema, not(nullValue()));
+ assertEquals(expected, schema);
+ }
+
+ @Test
+ public void shouldResolveSchemaIdAndProcessData()
+ {
+ FilesystemCatalogHandler catalog = new FilesystemCatalogHandler(config, context, 0L);
+
+ DirectBuffer data = new UnsafeBuffer();
+
+ String payload =
+ "{" +
+ "\"id\": \"123\"," +
+ "\"status\": \"OK\"" +
+ "}";
+ byte[] bytes = payload.getBytes();
+ data.wrap(bytes, 0, bytes.length);
+
+ int valLength = catalog.decode(0L, 0L, data, 0, data.capacity(), ValueConsumer.NOP, CatalogHandler.Decoder.IDENTITY);
+
+ assertEquals(data.capacity(), valLength);
+ }
+
+ @Test
+ public void shouldVerifyEncodedData()
+ {
+ FilesystemCatalogHandler catalog = new FilesystemCatalogHandler(config, context, 0L);
+
+ DirectBuffer data = new UnsafeBuffer();
+
+ byte[] bytes = {0x06, 0x69, 0x64,
+ 0x30, 0x10, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65};
+ data.wrap(bytes, 0, bytes.length);
+
+ assertEquals(13, catalog.encode(0L, 0L, 1, data, 0, data.capacity(),
+ ValueConsumer.NOP, CatalogHandler.Encoder.IDENTITY));
+ }
+}
diff --git a/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigAdapterTest.java b/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigAdapterTest.java
new file mode 100644
index 0000000000..8d0cb95cd1
--- /dev/null
+++ b/incubator/catalog-filesystem/src/test/java/io/aklivity/zilla/runtime/catalog/filesystem/internal/config/FilesystemOptionsConfigAdapterTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.filesystem.internal.config;
+
+import static java.util.function.Function.identity;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class FilesystemOptionsConfigAdapterTest
+{
+ private Jsonb jsonb;
+
+ @Before
+ public void initJson()
+ {
+ JsonbConfig config = new JsonbConfig()
+ .withAdapters(new FilesystemOptionsConfigAdapter());
+ jsonb = JsonbBuilder.create(config);
+ }
+
+ @Test
+ public void shouldReadCondition()
+ {
+ String text = "{" +
+ "\"subjects\":" +
+ "{" +
+ "\"subject1\":" +
+ "{" +
+ "\"path\":\"asyncapi/mqtt.yaml\"" +
+ "}" +
+ "}" +
+ "}";
+
+ FilesystemOptionsConfig catalog = jsonb.fromJson(text, FilesystemOptionsConfig.class);
+
+ assertThat(catalog, not(nullValue()));
+ FilesystemSchemaConfig schema = catalog.subjects.get(0);
+ assertThat(schema.subject, equalTo("subject1"));
+ assertThat(schema.path, equalTo("asyncapi/mqtt.yaml"));
+ }
+
+ @Test
+ public void shouldWriteCondition()
+ {
+ String expectedJson = "{" +
+ "\"subjects\":" +
+ "{" +
+ "\"subject1\":" +
+ "{" +
+ "\"path\":\"asyncapi/mqtt.yaml\"" +
+ "}" +
+ "}" +
+ "}";
+
+ FilesystemOptionsConfig catalog = (FilesystemOptionsConfig) new FilesystemOptionsConfigBuilder<>(identity())
+ .subjects()
+ .subject("subject1")
+ .path("asyncapi/mqtt.yaml")
+ .build()
+ .build();
+
+ String json = jsonb.toJson(catalog);
+
+ assertThat(json, not(nullValue()));
+ assertThat(json, equalTo(expectedJson));
+ }
+}
diff --git a/incubator/command-dump/pom.xml b/incubator/command-dump/pom.xml
index ce8c31d6b9..f2fb397d84 100644
--- a/incubator/command-dump/pom.xml
+++ b/incubator/command-dump/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/incubator/command-generate/pom.xml b/incubator/command-generate/pom.xml
index 54b8b1ce15..5d21938023 100644
--- a/incubator/command-generate/pom.xml
+++ b/incubator/command-generate/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/incubator/command-log/pom.xml b/incubator/command-log/pom.xml
index 4424b46608..3d744fdef0 100644
--- a/incubator/command-log/pom.xml
+++ b/incubator/command-log/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/incubator/command-tune/pom.xml b/incubator/command-tune/pom.xml
index 4b2b36479a..e825cd9bba 100644
--- a/incubator/command-tune/pom.xml
+++ b/incubator/command-tune/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
incubator
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/incubator/pom.xml b/incubator/pom.xml
index 11d3de581e..39560cbeef 100644
--- a/incubator/pom.xml
+++ b/incubator/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.78
+ 0.9.79
../pom.xml
@@ -21,6 +21,9 @@
binding-amqp
+ catalog-filesystem.spec
+ catalog-filesystem
+
command-log
command-dump
command-generate
@@ -34,6 +37,11 @@
binding-amqp
${project.version}
+
+ ${project.groupId}
+ catalog-filesystem
+ ${project.version}
+
${project.groupId}
command-log
diff --git a/manager/pom.xml b/manager/pom.xml
index c368137d22..b35ea225b9 100644
--- a/manager/pom.xml
+++ b/manager/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/pom.xml b/pom.xml
index e4ff722f06..5634a743ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
4.0.0
io.aklivity.zilla
zilla
- 0.9.78
+ 0.9.79
pom
zilla
https://github.com/aklivity/zilla
diff --git a/runtime/binding-asyncapi/pom.xml b/runtime/binding-asyncapi/pom.xml
index 7ec80278a6..8f5cbd55b3 100644
--- a/runtime/binding-asyncapi/pom.xml
+++ b/runtime/binding-asyncapi/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-echo/pom.xml b/runtime/binding-echo/pom.xml
index a432acdbe9..59a307226e 100644
--- a/runtime/binding-echo/pom.xml
+++ b/runtime/binding-echo/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-fan/pom.xml b/runtime/binding-fan/pom.xml
index 671c921563..146b79f7a7 100644
--- a/runtime/binding-fan/pom.xml
+++ b/runtime/binding-fan/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-filesystem/pom.xml b/runtime/binding-filesystem/pom.xml
index 1dcdc7c579..4325d6eb50 100644
--- a/runtime/binding-filesystem/pom.xml
+++ b/runtime/binding-filesystem/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-grpc-kafka/pom.xml b/runtime/binding-grpc-kafka/pom.xml
index 6ec48492e5..f953e4fa1b 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.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-grpc/pom.xml b/runtime/binding-grpc/pom.xml
index 392c7a99ba..74ada33109 100644
--- a/runtime/binding-grpc/pom.xml
+++ b/runtime/binding-grpc/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-http-filesystem/pom.xml b/runtime/binding-http-filesystem/pom.xml
index 23c2fd5e39..73c97743f2 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.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-http-kafka/pom.xml b/runtime/binding-http-kafka/pom.xml
index 27cc0a2d45..42ca77af4c 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.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-http/pom.xml b/runtime/binding-http/pom.xml
index eb8b2add48..fb4f00e238 100644
--- a/runtime/binding-http/pom.xml
+++ b/runtime/binding-http/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-kafka-grpc/pom.xml b/runtime/binding-kafka-grpc/pom.xml
index d7a1bf025b..d5999cd0f4 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.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-kafka/pom.xml b/runtime/binding-kafka/pom.xml
index 4a765a27e0..1264e1ac87 100644
--- a/runtime/binding-kafka/pom.xml
+++ b/runtime/binding-kafka/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaConfiguration.java b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaConfiguration.java
index 3a7901da9b..6786f38ffc 100644
--- a/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaConfiguration.java
+++ b/runtime/binding-kafka/src/main/java/io/aklivity/zilla/runtime/binding/kafka/internal/KafkaConfiguration.java
@@ -443,6 +443,13 @@ private static InstanceIdSupplier decodeInstanceId(
private static InstanceIdSupplier defaultInstanceId(
Configuration config)
{
- return () -> String.format("%s-%s", KAFKA_CLIENT_ID.get(config), UUID.randomUUID());
+ return () -> String.format("%s-%s", clientIdWithDefault(config), UUID.randomUUID());
+ }
+
+ private static String clientIdWithDefault(
+ Configuration config)
+ {
+ String clientId = KAFKA_CLIENT_ID.get(config);
+ return clientId != null ? clientId : KAFKA_CLIENT_ID_DEFAULT;
}
}
diff --git a/runtime/binding-mqtt-kafka/pom.xml b/runtime/binding-mqtt-kafka/pom.xml
index 323287da22..f6e06bedae 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.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-mqtt/pom.xml b/runtime/binding-mqtt/pom.xml
index 09b3011474..f0e80fa1d0 100644
--- a/runtime/binding-mqtt/pom.xml
+++ b/runtime/binding-mqtt/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/MqttConfiguration.java b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/MqttConfiguration.java
index 48f2ec524d..d236979080 100644
--- a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/MqttConfiguration.java
+++ b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/MqttConfiguration.java
@@ -24,6 +24,7 @@
import org.agrona.LangUtil;
+import io.aklivity.zilla.runtime.binding.mqtt.internal.types.MqttQoS;
import io.aklivity.zilla.runtime.engine.Configuration;
public class MqttConfiguration extends Configuration
@@ -44,6 +45,7 @@ public class MqttConfiguration extends Configuration
public static final IntPropertyDef SESSION_EXPIRY_GRACE_PERIOD;
public static final PropertyDef CLIENT_ID;
public static final PropertyDef SUBSCRIPTION_ID;
+ public static final PropertyDef PUBLISH_QOS_MAX;
public static final int GENERATED_SUBSCRIPTION_ID_MASK = 0x70;
static
@@ -66,6 +68,8 @@ public class MqttConfiguration extends Configuration
CLIENT_ID = config.property("client.id");
SUBSCRIPTION_ID = config.property(IntSupplier.class, "subscription.id",
MqttConfiguration::decodeIntSupplier, MqttConfiguration::defaultSubscriptionId);
+ PUBLISH_QOS_MAX = config.property(MqttQoS.class, "publish.qos.max",
+ MqttConfiguration::decodePublishQosMax, MqttQoS.EXACTLY_ONCE);
MQTT_CONFIG = config;
}
@@ -130,12 +134,22 @@ public String clientId()
return CLIENT_ID.get(this);
}
-
public IntSupplier subscriptionId()
{
return SUBSCRIPTION_ID.get(this);
}
+ public MqttQoS publishQosMax()
+ {
+ return PUBLISH_QOS_MAX.get(this);
+ }
+
+ private static MqttQoS decodePublishQosMax(
+ String value)
+ {
+ return MqttQoS.valueOf(value.toUpperCase());
+ }
+
private static IntSupplier decodeIntSupplier(
String fullyQualifiedMethodName)
{
diff --git a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttServerFactory.java b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttServerFactory.java
index fdf18819aa..ff18bfa0d4 100644
--- a/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttServerFactory.java
+++ b/runtime/binding-mqtt/src/main/java/io/aklivity/zilla/runtime/binding/mqtt/internal/stream/MqttServerFactory.java
@@ -406,6 +406,7 @@ public final class MqttServerFactory implements MqttStreamFactory
private final Map decodersByPacketTypeV4;
private final Map decodersByPacketTypeV5;
private final IntSupplier supplySubscriptionId;
+ private final MqttQoS publishQosMax;
private final EngineContext context;
private int maximumPacketSize = Integer.MAX_VALUE;
@@ -520,6 +521,7 @@ public MqttServerFactory(
this.validator = new MqttValidator();
this.utf8Decoder = StandardCharsets.UTF_8.newDecoder();
this.supplySubscriptionId = config.subscriptionId();
+ this.publishQosMax = config.publishQosMax();
final Optional clientId = Optional.ofNullable(config.clientId()).map(String16FW::new);
this.supplyClientId = clientId.isPresent() ? clientId::get : () -> new String16FW(UUID.randomUUID().toString());
this.decodePacketTypeByVersion = new Int2ObjectHashMap<>();
@@ -2938,7 +2940,7 @@ else if (this.authField.equals(MqttConnectProperty.PASSWORD))
.session(s -> s
.flags(connectFlags & (CLEAN_START_FLAG_MASK | WILL_FLAG_MASK))
.expiry(sessionExpiry)
- .publishQosMax(MqttQoS.EXACTLY_ONCE.value())
+ .publishQosMax(publishQosMax.value())
.capabilities(capabilities)
.clientId(clientId));
diff --git a/runtime/binding-openapi-asyncapi/pom.xml b/runtime/binding-openapi-asyncapi/pom.xml
index 74d35a9212..21fd07e4e8 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.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-openapi/pom.xml b/runtime/binding-openapi/pom.xml
index ed6231533d..23c63cc997 100644
--- a/runtime/binding-openapi/pom.xml
+++ b/runtime/binding-openapi/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-proxy/pom.xml b/runtime/binding-proxy/pom.xml
index 655c09a794..cb79d828e5 100644
--- a/runtime/binding-proxy/pom.xml
+++ b/runtime/binding-proxy/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-sse-kafka/pom.xml b/runtime/binding-sse-kafka/pom.xml
index 2bcf8cbd4d..ff2e94c7df 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.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-sse/pom.xml b/runtime/binding-sse/pom.xml
index f1484c4a68..1e8ebfb0c1 100644
--- a/runtime/binding-sse/pom.xml
+++ b/runtime/binding-sse/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-tcp/pom.xml b/runtime/binding-tcp/pom.xml
index 3adcc8126d..9416520a76 100644
--- a/runtime/binding-tcp/pom.xml
+++ b/runtime/binding-tcp/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-tls/pom.xml b/runtime/binding-tls/pom.xml
index edb95e7c55..8a7fc639b2 100644
--- a/runtime/binding-tls/pom.xml
+++ b/runtime/binding-tls/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/binding-ws/pom.xml b/runtime/binding-ws/pom.xml
index b9bdb07def..819018cc67 100644
--- a/runtime/binding-ws/pom.xml
+++ b/runtime/binding-ws/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/catalog-apicurio/pom.xml b/runtime/catalog-apicurio/pom.xml
index 085b84014b..8eb963425d 100644
--- a/runtime/catalog-apicurio/pom.xml
+++ b/runtime/catalog-apicurio/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/catalog-inline/pom.xml b/runtime/catalog-inline/pom.xml
index 1ecd817ffd..3913b280fe 100644
--- a/runtime/catalog-inline/pom.xml
+++ b/runtime/catalog-inline/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/catalog-karapace/pom.xml b/runtime/catalog-karapace/pom.xml
index d6566a9b4d..e20601cd23 100644
--- a/runtime/catalog-karapace/pom.xml
+++ b/runtime/catalog-karapace/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/command-metrics/pom.xml b/runtime/command-metrics/pom.xml
index 474b69dd5f..b8a5d062d9 100644
--- a/runtime/command-metrics/pom.xml
+++ b/runtime/command-metrics/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/command-start/pom.xml b/runtime/command-start/pom.xml
index 7ccb607d68..d3c8a7be68 100644
--- a/runtime/command-start/pom.xml
+++ b/runtime/command-start/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/command-stop/pom.xml b/runtime/command-stop/pom.xml
index 581354c2dd..9c840eb0fe 100644
--- a/runtime/command-stop/pom.xml
+++ b/runtime/command-stop/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/command/pom.xml b/runtime/command/pom.xml
index 4b878d1f12..c179aab3fb 100644
--- a/runtime/command/pom.xml
+++ b/runtime/command/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/common/pom.xml b/runtime/common/pom.xml
index 55ec404338..9a00c5b9b3 100644
--- a/runtime/common/pom.xml
+++ b/runtime/common/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/engine/pom.xml b/runtime/engine/pom.xml
index b2c12187ce..8f71bfe53a 100644
--- a/runtime/engine/pom.xml
+++ b/runtime/engine/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/config/ExporterConfig.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/config/ExporterConfig.java
index e582d2c1bf..4517c938d0 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/config/ExporterConfig.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/config/ExporterConfig.java
@@ -24,9 +24,11 @@ public class ExporterConfig
public final String name;
public final String qname;
public final String type;
+ public final String vault;
public final OptionsConfig options;
public transient long id;
+ public transient long vaultId;
public static ExporterConfigBuilder builder()
{
@@ -37,12 +39,14 @@ public static ExporterConfigBuilder builder()
String namespace,
String name,
String type,
+ String vault,
OptionsConfig options)
{
this.namespace = requireNonNull(namespace);
this.name = requireNonNull(name);
this.qname = String.format("%s:%s", namespace, name);
this.type = requireNonNull(type);
+ this.vault = vault;
this.options = options;
}
}
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/config/ExporterConfigBuilder.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/config/ExporterConfigBuilder.java
index f3ccb02a8f..db31c22175 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/config/ExporterConfigBuilder.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/config/ExporterConfigBuilder.java
@@ -24,6 +24,7 @@ public final class ExporterConfigBuilder extends ConfigBuilder name(
return this;
}
+ public ExporterConfigBuilder vault(
+ String vault)
+ {
+ this.vault = vault;
+ return this;
+ }
+
public ExporterConfigBuilder type(
String type)
{
@@ -76,6 +84,6 @@ public ExporterConfigBuilder options(
@Override
public T build()
{
- return mapper.apply(new ExporterConfig(namespace, name, type, options));
+ return mapper.apply(new ExporterConfig(namespace, name, type, vault, options));
}
}
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/config/ExporterAdapter.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/config/ExporterAdapter.java
index 378d5199bd..9d68c968c3 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/config/ExporterAdapter.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/config/ExporterAdapter.java
@@ -31,6 +31,7 @@
public class ExporterAdapter implements JsonbAdapter
{
private static final String TYPE_NAME = "type";
+ private static final String VAULT_NAME = "vault";
private static final String OPTIONS_NAME = "options";
private final OptionsConfigAdapter options;
@@ -60,6 +61,10 @@ public JsonObject adaptToJson(
JsonObjectBuilder item = Json.createObjectBuilder();
item.add(TYPE_NAME, exporter.type);
+ if (exporter.vault != null)
+ {
+ item.add(VAULT_NAME, exporter.vault);
+ }
if (exporter.options != null)
{
item.add(OPTIONS_NAME, options.adaptToJson(exporter.options));
@@ -82,11 +87,17 @@ public ExporterConfig[] adaptFromJson(
String type = item.getString(TYPE_NAME);
options.adaptType(type);
+ String vault = null;
+ if (item.containsKey(VAULT_NAME))
+ {
+ vault = item.getString(VAULT_NAME);
+ }
exporters.add(ExporterConfig.builder()
.namespace(namespace)
.name(name)
.type(type)
+ .vault(vault)
.options(options.adaptFromJson(item.getJsonObject(OPTIONS_NAME)))
.build());
}
diff --git a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineManager.java b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineManager.java
index db46a6bb17..4d8da63eff 100644
--- a/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineManager.java
+++ b/runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/internal/registry/EngineManager.java
@@ -253,6 +253,10 @@ private void process(
for (ExporterConfig exporter : namespace.telemetry.exporters)
{
exporter.id = resolver.resolve(exporter.name);
+ if (exporter.vault != null)
+ {
+ exporter.vaultId = resolver.resolve(exporter.vault);
+ }
}
for (BindingConfig binding : namespace.bindings)
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/config/TelemetryConfigsAdapterTest.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/config/TelemetryConfigsAdapterTest.java
index 9219f0249a..8972ea7280 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/config/TelemetryConfigsAdapterTest.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/internal/config/TelemetryConfigsAdapterTest.java
@@ -153,6 +153,7 @@ public void shouldReadTelemetryWithExporterOptions()
"\"test0\": " +
"{" +
"\"type\": \"test\"," +
+ "\"vault\": \"vault0\"," +
"\"options\": {" +
"\"mode\": \"test42\"" +
"}" +
@@ -173,6 +174,7 @@ public void shouldReadTelemetryWithExporterOptions()
assertThat(telemetry.metrics.get(1).name, equalTo("test.histogram"));
assertThat(telemetry.exporters.get(0).name, equalTo("test0"));
assertThat(telemetry.exporters.get(0).type, equalTo("test"));
+ assertThat(telemetry.exporters.get(0).vault, equalTo("vault0"));
assertThat(telemetry.exporters.get(0).options, instanceOf(TestExporterOptionsConfig.class));
assertThat(((TestExporterOptionsConfig)telemetry.exporters.get(0).options).mode, equalTo("test42"));
}
@@ -198,6 +200,7 @@ public void shouldWriteTelemetryWithExporterOptions()
.namespace("test")
.name("test0")
.type("test")
+ .vault("vault0")
.options(TestExporterOptionsConfig::builder)
.inject(identity())
.mode("test42")
@@ -213,6 +216,6 @@ public void shouldWriteTelemetryWithExporterOptions()
assertThat(text, equalTo(
"{\"attributes\":{\"test.attribute\":\"example\"}," +
"\"metrics\":[\"test.counter\"]," +
- "\"exporters\":{\"test0\":{\"type\":\"test\",\"options\":{\"mode\":\"test42\"}}}}"));
+ "\"exporters\":{\"test0\":{\"type\":\"test\",\"vault\":\"vault0\",\"options\":{\"mode\":\"test42\"}}}}"));
}
}
diff --git a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/k3po/ext/behavior/LabelManager.java b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/k3po/ext/behavior/LabelManager.java
index af6c0a9219..2966823b92 100644
--- a/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/k3po/ext/behavior/LabelManager.java
+++ b/runtime/engine/src/test/java/io/aklivity/zilla/runtime/engine/test/internal/k3po/ext/behavior/LabelManager.java
@@ -98,7 +98,7 @@ private void checkSnapshot()
this.sizeInBytes = -1L;
}
- if (this.sizeInBytes == -1L || this.sizeInBytes < Files.size(labelsPath))
+ if (this.sizeInBytes == -1L || this.sizeInBytes != Files.size(labelsPath))
{
Files.createDirectories(labelsPath.getParent());
try (FileChannel channel = FileChannel.open(labelsPath, CREATE, READ, WRITE))
diff --git a/runtime/exporter-otlp/pom.xml b/runtime/exporter-otlp/pom.xml
index 888c0ad6cf..85ac746f1b 100644
--- a/runtime/exporter-otlp/pom.xml
+++ b/runtime/exporter-otlp/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/exporter-prometheus/pom.xml b/runtime/exporter-prometheus/pom.xml
index c58fe48b5a..9b0cb1090b 100644
--- a/runtime/exporter-prometheus/pom.xml
+++ b/runtime/exporter-prometheus/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/exporter-stdout/pom.xml b/runtime/exporter-stdout/pom.xml
index 803acd92a7..0a5e339404 100644
--- a/runtime/exporter-stdout/pom.xml
+++ b/runtime/exporter-stdout/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/guard-jwt/pom.xml b/runtime/guard-jwt/pom.xml
index 5b0e58268c..886072141d 100644
--- a/runtime/guard-jwt/pom.xml
+++ b/runtime/guard-jwt/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/metrics-grpc/pom.xml b/runtime/metrics-grpc/pom.xml
index a7a4789db1..50b3c0f859 100644
--- a/runtime/metrics-grpc/pom.xml
+++ b/runtime/metrics-grpc/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/metrics-http/pom.xml b/runtime/metrics-http/pom.xml
index 5b3b7bb81e..41e13a00e8 100644
--- a/runtime/metrics-http/pom.xml
+++ b/runtime/metrics-http/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/metrics-stream/pom.xml b/runtime/metrics-stream/pom.xml
index 724b97f466..331ce57e60 100644
--- a/runtime/metrics-stream/pom.xml
+++ b/runtime/metrics-stream/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/model-avro/pom.xml b/runtime/model-avro/pom.xml
index d9305320f9..8f3f284639 100644
--- a/runtime/model-avro/pom.xml
+++ b/runtime/model-avro/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/model-core/pom.xml b/runtime/model-core/pom.xml
index 4588bb3e03..aa9f3094df 100644
--- a/runtime/model-core/pom.xml
+++ b/runtime/model-core/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/model-json/pom.xml b/runtime/model-json/pom.xml
index 0b84cec7d5..de86de429a 100644
--- a/runtime/model-json/pom.xml
+++ b/runtime/model-json/pom.xml
@@ -6,7 +6,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/model-protobuf/pom.xml b/runtime/model-protobuf/pom.xml
index 847be076c7..fe4f58ad46 100644
--- a/runtime/model-protobuf/pom.xml
+++ b/runtime/model-protobuf/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/pom.xml b/runtime/pom.xml
index 53cf8cd75d..e1ff133846 100644
--- a/runtime/pom.xml
+++ b/runtime/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/resolver-env/pom.xml b/runtime/resolver-env/pom.xml
index 436687a1af..0714a44e51 100644
--- a/runtime/resolver-env/pom.xml
+++ b/runtime/resolver-env/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/runtime/vault-filesystem/pom.xml b/runtime/vault-filesystem/pom.xml
index d464f70bb2..8697572219 100644
--- a/runtime/vault-filesystem/pom.xml
+++ b/runtime/vault-filesystem/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
runtime
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-asyncapi.spec/pom.xml b/specs/binding-asyncapi.spec/pom.xml
index d725f1c355..6a10af9e3b 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-echo.spec/pom.xml b/specs/binding-echo.spec/pom.xml
index 197fda7724..75060b8aa2 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-fan.spec/pom.xml b/specs/binding-fan.spec/pom.xml
index c5ccb0c2af..0804b04ef4 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-filesystem.spec/pom.xml b/specs/binding-filesystem.spec/pom.xml
index a1b6516720..56403d8c9b 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-grpc-kafka.spec/pom.xml b/specs/binding-grpc-kafka.spec/pom.xml
index ef50523024..e086ece5e2 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-grpc.spec/pom.xml b/specs/binding-grpc.spec/pom.xml
index feed4412ed..a8fd02813b 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-grpc.spec/src/main/scripts/io/aklivity/zilla/specs/binding/grpc/schema/grpc.schema.patch.json b/specs/binding-grpc.spec/src/main/scripts/io/aklivity/zilla/specs/binding/grpc/schema/grpc.schema.patch.json
index b1b14db7d9..514b16bf6b 100644
--- a/specs/binding-grpc.spec/src/main/scripts/io/aklivity/zilla/specs/binding/grpc/schema/grpc.schema.patch.json
+++ b/specs/binding-grpc.spec/src/main/scripts/io/aklivity/zilla/specs/binding/grpc/schema/grpc.schema.patch.json
@@ -44,7 +44,8 @@
{
"title": "Service",
"type": "string"
- }
+ },
+ "deprecated": true
}
},
"additionalProperties": false
diff --git a/specs/binding-http-filesystem.spec/pom.xml b/specs/binding-http-filesystem.spec/pom.xml
index 210a970ecf..dc2b971c1a 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-http-kafka.spec/pom.xml b/specs/binding-http-kafka.spec/pom.xml
index 2382ea9336..d25f88278c 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-http.spec/pom.xml b/specs/binding-http.spec/pom.xml
index fec148d3f8..a8109e782f 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-kafka-grpc.spec/pom.xml b/specs/binding-kafka-grpc.spec/pom.xml
index b4a6502b9e..31f2ae007e 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-kafka.spec/pom.xml b/specs/binding-kafka.spec/pom.xml
index feed6ec20a..4e0ae33879 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-mqtt-kafka.spec/pom.xml b/specs/binding-mqtt-kafka.spec/pom.xml
index ef5a19fb06..32b677ac9d 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-mqtt.spec/pom.xml b/specs/binding-mqtt.spec/pom.xml
index 2f19f4171c..f95f2d4ea5 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-openapi-asyncapi.spec/pom.xml b/specs/binding-openapi-asyncapi.spec/pom.xml
index f2422e604c..365cc8b344 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-openapi.spec/pom.xml b/specs/binding-openapi.spec/pom.xml
index dec9db48c7..194a1912d2 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-proxy.spec/pom.xml b/specs/binding-proxy.spec/pom.xml
index 9aee8ee651..2ffaf85ef3 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-sse-kafka.spec/pom.xml b/specs/binding-sse-kafka.spec/pom.xml
index 4f11b0215b..a240c25d38 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-sse.spec/pom.xml b/specs/binding-sse.spec/pom.xml
index b7c382da26..f44e0c38cd 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-tcp.spec/pom.xml b/specs/binding-tcp.spec/pom.xml
index d7fff1a98f..f653f1f395 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-tls.spec/pom.xml b/specs/binding-tls.spec/pom.xml
index a3457b1e3f..d872fb25cf 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/binding-ws.spec/pom.xml b/specs/binding-ws.spec/pom.xml
index d402d2e44b..6b4f7a34f7 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/catalog-apicurio.spec/pom.xml b/specs/catalog-apicurio.spec/pom.xml
index 795a28c1ab..b20a71c459 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/catalog-inline.spec/pom.xml b/specs/catalog-inline.spec/pom.xml
index 05b9aa806b..cf526db5e8 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/catalog-karapace.spec/pom.xml b/specs/catalog-karapace.spec/pom.xml
index e52c3891ed..5447eca216 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/engine.spec/pom.xml b/specs/engine.spec/pom.xml
index 777572e8c8..011b6983e4 100644
--- a/specs/engine.spec/pom.xml
+++ b/specs/engine.spec/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
specs
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/specs/exporter-otlp.spec/pom.xml b/specs/exporter-otlp.spec/pom.xml
index 292f6600c9..3f5135a878 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/exporter-prometheus.spec/pom.xml b/specs/exporter-prometheus.spec/pom.xml
index c9e09711d5..0220427a7c 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/exporter-stdout.spec/pom.xml b/specs/exporter-stdout.spec/pom.xml
index c30c2aa964..42c31bf9a5 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/guard-jwt.spec/pom.xml b/specs/guard-jwt.spec/pom.xml
index 641c62c12b..ba82420718 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/metrics-grpc.spec/pom.xml b/specs/metrics-grpc.spec/pom.xml
index f72c5d00c5..add4bef29e 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/metrics-http.spec/pom.xml b/specs/metrics-http.spec/pom.xml
index 060f96d3d2..ec94b5f491 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/metrics-stream.spec/pom.xml b/specs/metrics-stream.spec/pom.xml
index 6f44f121ba..c1f3f50592 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/model-avro.spec/pom.xml b/specs/model-avro.spec/pom.xml
index 2e9caf992d..4c46b646d3 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/model-core.spec/pom.xml b/specs/model-core.spec/pom.xml
index b2513c982e..ab2710097c 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/model-json.spec/pom.xml b/specs/model-json.spec/pom.xml
index cc855a64d6..c2a992fbee 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/model-protobuf.spec/pom.xml b/specs/model-protobuf.spec/pom.xml
index 0cdf6bcc8b..fa0c9dfc9b 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.78
+ 0.9.79
../pom.xml
diff --git a/specs/pom.xml b/specs/pom.xml
index 7daaa735b6..35224b78ee 100644
--- a/specs/pom.xml
+++ b/specs/pom.xml
@@ -8,7 +8,7 @@
io.aklivity.zilla
zilla
- 0.9.78
+ 0.9.79
../pom.xml
diff --git a/specs/vault-filesystem.spec/pom.xml b/specs/vault-filesystem.spec/pom.xml
index 2f12bd64df..a370282fd3 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.78
+ 0.9.79
../pom.xml