mq-bridge-basic 0.4.18__tar.gz → 0.4.19__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/CHANGELOG.md +137 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/Cargo.lock +4 -4
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/Cargo.toml +1 -1
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/PKG-INFO +1 -1
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/README.md +5 -8
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/REFERENCE.md +130 -12
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/mq-bridge.schema.json +165 -11
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/mq_bridge/config.py +10 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/mq_bridge/config.pyi +22 -0
- mq_bridge_basic-0.4.19/src/endpoints/file/csv_dialect.rs +322 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/file/mod.rs +547 -165
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/file/tests.rs +452 -35
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/publisher.rs +5 -1
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/server.rs +8 -10
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http/tests.rs +45 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/memory/endpoint.rs +35 -46
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mod.rs +66 -1
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mqtt.rs +1 -1
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/nats.rs +10 -13
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/object_store.rs +222 -28
- mq_bridge_basic-0.4.19/src/endpoints/sqlx/columns.rs +597 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/sqlx/mod.rs +186 -53
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/sqlx/tests.rs +286 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/mod.rs +511 -130
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/tests.rs +298 -4
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/filter.rs +55 -2
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/models/builders.rs +1 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/models/serde_support.rs +1 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/models/tests.rs +22 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/models.rs +127 -11
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/route.rs +165 -30
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/postgres.rs +45 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration_test.rs +9 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.cargo/config.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.coderabbit.yaml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.dockerignore +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/dependabot.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/app.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/benchmark.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/build-node.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/ci.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/conda.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/docs.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/ibm-mq.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/node.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/publish-node.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/publish-python.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/python.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/release.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.github/workflows/test-matrix.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.gitignore +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/.justfile +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/AGENTS.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/CLAUDE.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/CONTRIBUTING.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/LICENSE +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/LICENSE-APACHE +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/LICENSE-APACHE.python +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/LICENSE-MIT +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/LICENSE-MIT.python +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/LICENSE.python +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/SECURITY.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/THIRD_PARTY_LICENSES.txt +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/benches/ETL_BENCHMARKS.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/benches/csv_to_json_bench.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/benches/middleware_expr_bench.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/benches/pack_bench.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/benches/performance_bench.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/benches/router_bench.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/benches/zeromq_backends.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/bindings-common/Cargo.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/bindings-common/src/lib.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/bindings-common/src/logging.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/build.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/deny.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/ARCHITECTURE.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/CONFIGURATION.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/DELIVERY.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/EXTENDING.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/GRPC.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/PLUGINS.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/THIRD_PARTY_LICENSES.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/docs/assets/copy-demo.png +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/c-plugin/CMakeLists.txt +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/c-plugin/README.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/c-plugin/legacy_ledger.c +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/c-plugin/legacy_ledger.h +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/c-plugin/legacy_parser.c +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/c-plugin/legacy_parser.h +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/c-plugin/minimal.c +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/c-plugin/plugin.c +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/examples/ipc_worker_queue.yaml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/include/cbindgen.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/include/mq_bridge_plugin.h +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/include/mq_bridge_plugin_helpers.h +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/llms.txt +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/mq_bridge/__init__.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/mq_bridge/__init__.pyi +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/mq_bridge/plugin_packaging.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/mq_bridge/py.typed +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/package-lock.json +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/pyproject.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/Cargo.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/LICENSE-APACHE.python +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/LICENSE-MIT.python +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/LICENSE.python +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/README.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/THIRD_PARTY_LICENSES.txt +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/example.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/IBM_MQ.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/bench_memory.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/consume_pull.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/dlt_source.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/ibm-mq-input.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/json_route.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/memory.yaml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/examples/raw_route.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/pyproject-basic.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/pyproject-reduced.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/scripts/gen_config_types.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/src/lib.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_config_types.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_custom_endpoint.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_logging.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_packaging.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_plugin_package.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_public_api.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_routes.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/tests/test_shutdown.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/python/mq-bridge-py/uv.lock +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/analysis/benches/metadata_bench.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/analysis/http/http_flamegraph.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/analysis/http/run_http_ladder.sh +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/ci/format_bench_output.sh +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/httparena/README.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/httparena/frameworks/mq-bridge-py/server.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/httparena/frameworks/mq-bridge-py/templates/fortunes.html +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/mqb-agent.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/sync-version.mjs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/techempower/README.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/techempower/postgres.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/techempower/seed.sql +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/techempower/verify.sh +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/the-benchmarker/README.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/canonical_message.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/checkpoint.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/command_handler.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/config_file.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/amqp.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/aws.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/clickhouse.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/dir_spool/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/dir_spool/tests.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/consumer.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/dynamic.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/proto/mqbridge/bridge.proto +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/grpc/tests.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http/publisher.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http/stream.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http_bulk/auth.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http_bulk/consumer.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http_bulk/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http_bulk/presets.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http_bulk/publisher.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/http_bulk/query.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/ibm_mq.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/kafka.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/memory/framed.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/memory/ipc_unix.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/memory/ipc_windows.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/memory/memory_transport.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/memory/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/memory/transport.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/aggregate.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/consumer.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/dedup.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/publisher.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/readers.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/mongodb/tests.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/poll.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/VENDORED.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/pgoutput/values.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/replication.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/postgres/state.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/redis_streams.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/sled.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/sqlx/aggregate.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/sqlx/dedup.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/fanout.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/null.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/reader.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/request.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/response.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/sequence.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/static_endpoint.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/stream_buffer.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/structural/switch.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/websocket.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/zeromq/codec.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/zeromq/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/zeromq/omq.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/endpoints/zeromq/zmq.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/errors.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/event_handler.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/event_store.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/extensions.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/lib.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/states.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/store.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/aggregate/writer.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/buffer.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/compression.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/cookie_jar.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/deduplication/memory.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/deduplication.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/deferred_commit.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/delay.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/dlq.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/encryption.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/id.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/limiter.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/lookup.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/metrics.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/otel.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/pack.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/random_panic.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/raw_json.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/retry.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/timeout.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/transform/coerce.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/transform/compiled.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/transform/error.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/transform/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/transform/path.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/transform/schema.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/transform/tests.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/middleware/weak_join.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/models/defaults.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/models/secrets.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/outcomes.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/completion.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/conformance.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/crash.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/discovery.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/endpoint.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/forward.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/host.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/message.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/middleware.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/sdk.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/plugin/test_support.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/publisher.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/response.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/shutdown.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/base64_engine.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/change_op.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/compression.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/compression_pool.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/config_schema.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/connection_registry.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/crypto.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/crypto_envelope.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/http_status.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/interpolation.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/lookup_batch.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/ndjson.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/pack.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/parallel.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/parquet.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/plugin_abi.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/poll_job.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/source_ranges.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/support/stream_batch.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/test_utils.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/traits.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/src/type_handler.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/README.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/armature_integration.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/compat/python/bridge_client.py +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/dedup_store_bench.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/delivery_guarantee_test.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/amqp.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/aws.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/clickhouse.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/config.toml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/amqp.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/aws.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/clickhouse.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm_mq.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/kafka-tls.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/kafka.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mariadb.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mongodb.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mosquitto.conf +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mq_init.mqsc +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mqtt.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/mysql.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/nats.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/object_store.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/postgres.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/docker-compose/redis.yml +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/file.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/grpc.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/grpc_tls.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/http.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/http_tls.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/ibm_mq.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/ibm_mq_tls.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/ipc.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/kafka.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/kafka_tls.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/logic_test.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/mariadb.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/memory.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/mod.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/mongodb.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/mongodb_raw.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/mongodb_tls.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/mqtt.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/mysql.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/nats.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/object_store.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/performance_static.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/postgres_cdc.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/redis_streams.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/route.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/scripts/gen_certs.sh +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/sqlite.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/tls_helpers.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/websocket.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/integration/zeromq.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/memory_leak_test.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/otel_test.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/ref_test.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/reference_docs_test.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/sqlite_test.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/tls_example.rs +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/unit_tests.md +0 -0
- {mq_bridge_basic-0.4.18 → mq_bridge_basic-0.4.19}/tests/websocket_test.rs +0 -0
|
@@ -2,6 +2,143 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `mq-bridge`. Newest first.
|
|
4
4
|
|
|
5
|
+
## 0.4.19
|
|
6
|
+
|
|
7
|
+
CSV in more shapes: the reader takes other separators and quoting, and a CSV sink no longer
|
|
8
|
+
mixes JSON into its cells. The second is a behaviour change, listed below.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **CSV dialects.** `format: csv` took only comma-separated, `"`-quoted files with a header. A
|
|
13
|
+
`csv` block on the `file` endpoint and on an `object_store` source now sets `separator` (one
|
|
14
|
+
character, `tab`, `space`, hex, or `auto`), `quote` (a character or `none`), `header` and
|
|
15
|
+
`columns`. `separator: auto` is for sources and takes whichever of `,` `;` tab `|` occurs
|
|
16
|
+
most often outside quotes in the first record. That covers Excel's semicolon exports, TSV
|
|
17
|
+
from `mongoexport` and `psql`, and headerless dumps; the book's file page lists the setting
|
|
18
|
+
per tool. On the command line it is one parameter, `csv={"separator":"auto"}`.
|
|
19
|
+
`FileConfig` and `ObjectStoreConfig` gain the field `csv`, and `models` the types
|
|
20
|
+
`CsvConfig` and `CsvNested`; code that builds either struct without `..Default::default()`
|
|
21
|
+
needs the new field.
|
|
22
|
+
- **CSV to object storage.** An `object_store` sink rejected `format: csv`. It now writes each
|
|
23
|
+
batch as a CSV file with its own header, taken from that batch's first row, in the dialect
|
|
24
|
+
the `csv` block sets. Set `csv.columns` when every object must have the same columns.
|
|
25
|
+
- **A warning for short CSV rows.** A row with fewer fields than the header was read with the
|
|
26
|
+
missing ones empty and nothing said, which is what a wrong `separator` looks like. It is now
|
|
27
|
+
warned about once per process, as a row with too many fields already was.
|
|
28
|
+
|
|
29
|
+
- **`aggregate`: `on_error`, time-based averages, late-message detection, `read_only`.**
|
|
30
|
+
- `on_error: drop | fail | skip` says what happens to a message that cannot be folded.
|
|
31
|
+
`drop` is the default and what happened before: an input logs, acks and drops it, so an
|
|
32
|
+
HTTP caller gets `202`. `fail` nacks it instead (HTTP `500`). `skip` leaves out only the
|
|
33
|
+
entries that cannot be computed, runs the others, passes the message on and names the
|
|
34
|
+
skipped entries in the metadata `mqb.aggregate.skipped`. Before, one missing field in one
|
|
35
|
+
entry discarded the message for all entries.
|
|
36
|
+
- `ema`, `ema_stddev` and `ema_variance` take a half-life in place of `alpha`
|
|
37
|
+
(`ema(reading, 5m)`): a value counts half after that time, however many messages came.
|
|
38
|
+
The new `time` names the payload field with the event time (epoch seconds or
|
|
39
|
+
milliseconds, or RFC 3339); without it the clock is used.
|
|
40
|
+
- With `time`, a message older than the newest one its state has seen is folded without
|
|
41
|
+
decay and marked with the metadata `mqb.aggregate.late`. It is detected, not reordered.
|
|
42
|
+
- `read_only: true` reads the states from the `store` and never changes them, for a dry run
|
|
43
|
+
or a second route that only reads.
|
|
44
|
+
- The error for a missing field now says `is missing or not a number`.
|
|
45
|
+
- `AggregateMiddleware` gains the fields `time`, `on_error` and `read_only`, and `models`
|
|
46
|
+
the enum `AggregateOnError`; code that builds the struct without `..Default::default()`
|
|
47
|
+
needs the new fields.
|
|
48
|
+
- **Descriptive names for the file formats.** `format: raw` writes only the payload, which
|
|
49
|
+
for JSON payloads is plain JSON lines, while `format: json` writes the whole message
|
|
50
|
+
envelope; the names suggested the opposite. `payload`, `envelope_json`, `envelope_text`
|
|
51
|
+
and `envelope` are now accepted for `raw`, `json`, `text` and `normal`, on `file`,
|
|
52
|
+
`object_store` and `mongodb`. The old names keep working and are what is written back.
|
|
53
|
+
- **`mqb copy`: pipes, `--limit`, progress, compression by file name.**
|
|
54
|
+
- `-` is stdin as the source and stdout as the target (`-?format=csv` takes parameters). A
|
|
55
|
+
`file` source on a pipe, FIFO or terminal is read once without seeking, and its end ends
|
|
56
|
+
the copy, with or without `--drain`. Before, `file:///dev/stdin` failed with `Illegal seek`.
|
|
57
|
+
With stdout as the target the `copied …` summary goes to stderr.
|
|
58
|
+
- `--limit N` stops after `N` rows reached the destination; with `--filter`, `N` matching rows.
|
|
59
|
+
- On a terminal, a running row count is shown on stderr every two seconds.
|
|
60
|
+
- A `file://` path ending in `.gz`, `.zst` or `.lz4` sets `compression`; `compression=none`
|
|
61
|
+
overrides. A sink named `out.jsonl.gz` used to be written uncompressed.
|
|
62
|
+
- A copy without `--drain` now exits when its route ends by itself, on a permanent error or
|
|
63
|
+
the end of a stream. It used to wait for Ctrl-C.
|
|
64
|
+
- **SQL sink: `columns: auto` and `key`.** A SQL sink could write a record's fields into columns
|
|
65
|
+
only through a hand-written `insert_query`, percent-encoded on the command line, and an upsert
|
|
66
|
+
needed its own `ON CONFLICT` clause. With `columns: auto` each top-level JSON field goes into
|
|
67
|
+
the table column of the same name, and `key: id` turns the insert into an upsert, so
|
|
68
|
+
`mqb copy --from 'postgres://…?table=orders&cursor_column=id' --to 'postgres://…?table=orders&columns=auto&key=id'`
|
|
69
|
+
copies a table and can be rerun.
|
|
70
|
+
- The table must exist. A column a record does not name keeps its default (insert) or its
|
|
71
|
+
value (update). A field without a column is not written and is logged once; with
|
|
72
|
+
`extra_column: <name>` those fields go into that column as one JSON object.
|
|
73
|
+
- PostgreSQL casts each value to the column type, so `numeric`, `timestamptz`, `uuid`,
|
|
74
|
+
`jsonb`, enum and array columns take the text a SQL or CSV source delivers.
|
|
75
|
+
- `bulk_copy` works with `columns: auto`, not with `key`. `columns` cannot be combined with
|
|
76
|
+
`insert_query` or `auto_create_table`.
|
|
77
|
+
- `SqlxConfig` gains the fields `columns`, `key` and `extra_column`, and `models` the type `SqlColumns`.
|
|
78
|
+
- **SQL source: `timestamps: rfc3339`.** A Postgres `timestamptz` column is read in Postgres's
|
|
79
|
+
text form, `2026-10-04 09:15:23.923277+00`, which few other systems parse. With
|
|
80
|
+
`timestamps: rfc3339` a `cursor_column` source renders it in UTC as
|
|
81
|
+
`2026-10-04T09:15:23.923277Z`; a `timestamp` without zone gets the `T` and no offset. The
|
|
82
|
+
default is unchanged. `SqlxConfig` gains the field `timestamps` and `models` the type
|
|
83
|
+
`SqlTimestamps`.
|
|
84
|
+
|
|
85
|
+
### Behaviour changes
|
|
86
|
+
|
|
87
|
+
- **`aggregate`: states in memory only are opt-in.** An `aggregate` without
|
|
88
|
+
a `store` kept its states in the process, lost on restart and wrong with two instances, and
|
|
89
|
+
that was the default. It now needs `consistency: single_writer` next to it; with neither a
|
|
90
|
+
`store` nor that, the route fails to start with an error naming both. Add
|
|
91
|
+
`consistency: single_writer` to a config from 0.4.17 or 0.4.18 that has no `store` to keep
|
|
92
|
+
what it did.
|
|
93
|
+
- **A CSV sink flattens nested objects.** A nested object used to be written as JSON text in
|
|
94
|
+
one cell, so the output of `aggregate` (`{"stats":{"n":3,"avg":2.5}}`) came out as a mix of
|
|
95
|
+
CSV and JSON. It now becomes one column per leaf, named by its path: `stats.n`, `stats.avg`.
|
|
96
|
+
**A new file gets different columns than before; a file that already has a header keeps
|
|
97
|
+
it.** Set `csv.nested: json` for the previous output. Arrays are still written as JSON text.
|
|
98
|
+
- **A drain does not wait for an endpoint.** With `exit_on_empty` (`mqb copy --drain`) a route
|
|
99
|
+
that failed reconnected up to ten times, 5 s apart, before it gave up: about 50 s against a
|
|
100
|
+
closed port, a WebSocket path that answers 404, a NATS subject outside every stream or a gRPC
|
|
101
|
+
topic nobody serves. It now ends on the first failure when nothing has been delivered yet,
|
|
102
|
+
with the endpoint's error. A drain that has delivered something keeps the ten reconnects, so
|
|
103
|
+
a short outage in the middle of a long copy does not end it. Routes without `exit_on_empty`
|
|
104
|
+
reconnect without limit, as before. Add a `retry` middleware to a drain that should wait for
|
|
105
|
+
its sink.
|
|
106
|
+
- **A CSV file that ends inside a quoted field fails a drain.** The reader took everything
|
|
107
|
+
after the open quote as one field and reported success. A drain now writes the records before
|
|
108
|
+
it and fails, naming the byte offset of the open record; a tailing route waits for the writer
|
|
109
|
+
to finish the record.
|
|
110
|
+
- **Blank lines in a line-based file are skipped.** `raw`, `json`, `text` and `normal` sources
|
|
111
|
+
emitted an empty line as a message with an empty payload, which a SQL or Parquet sink then
|
|
112
|
+
rejected. The CSV reader already skipped them. Row counts change for files with blank lines.
|
|
113
|
+
- **A `file` route whose source and sink are the same path is refused.** It doubled the file
|
|
114
|
+
under a drain and would grow it without end otherwise.
|
|
115
|
+
- **SQLite `has no column named` is not retried.** A sink writing to a table without the
|
|
116
|
+
expected columns retried for ever; it is now a non-retryable error like the same case on
|
|
117
|
+
Postgres and MySQL.
|
|
118
|
+
- **An `object_store` source on a local path that does not exist fails a drain.** It reported
|
|
119
|
+
`copied 0 rows`. An empty directory or cloud prefix still does. A drain of a local path also
|
|
120
|
+
ends after one listing instead of waiting out the idle interval.
|
|
121
|
+
- **NATS: a missing `subject` or `stream` stops the route.** It was retried as a connection
|
|
122
|
+
error until the start timeout.
|
|
123
|
+
- **Clearer errors and quieter logs.** A queue read on a plain SQL table names
|
|
124
|
+
`cursor_column`; Postgres errors no longer end in `at line N` (a line of the server's source);
|
|
125
|
+
a closed database port reports `Connection refused` at once; a `filter` that does not compile
|
|
126
|
+
lists the operators, and one with a single `=` says so; a gRPC server names the topic it has
|
|
127
|
+
no consumer for; the drop summary counts messages per cause; an unknown `aggregate` field
|
|
128
|
+
lists the built-ins; `csv` settings without `format: csv` and an `insert_query` token that
|
|
129
|
+
binds NULL each warn once. The WebSocket "falling back to routed mode" line is now DEBUG and
|
|
130
|
+
the MQTT note on restart loss INFO.
|
|
131
|
+
|
|
132
|
+
### Fixed
|
|
133
|
+
|
|
134
|
+
- **`mqb copy --wait` reports a failed route at once.** A route that failed before it delivered
|
|
135
|
+
anything was retried until the wait ran out, and a later empty attempt could then report
|
|
136
|
+
success. `--wait` now retries only a drain that ended cleanly with nothing to copy.
|
|
137
|
+
- **`aggregate` with a shared `store` no longer keeps the state of a message it rejects.** A
|
|
138
|
+
message whose result had no place in the payload (`into: a.b` where `a` is not an object) was
|
|
139
|
+
counted in the store and then failed, so under `on_error: fail` every redelivery counted it
|
|
140
|
+
again. It now fails before any state changes, as it already did without a shared store.
|
|
141
|
+
|
|
5
142
|
## 0.4.18
|
|
6
143
|
|
|
7
144
|
A new generic output for search engines, plus documentation and packaging work. This release
|
|
@@ -3689,7 +3689,7 @@ dependencies = [
|
|
|
3689
3689
|
|
|
3690
3690
|
[[package]]
|
|
3691
3691
|
name = "mq-bridge"
|
|
3692
|
-
version = "0.4.
|
|
3692
|
+
version = "0.4.19"
|
|
3693
3693
|
dependencies = [
|
|
3694
3694
|
"aes-gcm",
|
|
3695
3695
|
"anyhow",
|
|
@@ -3792,7 +3792,7 @@ dependencies = [
|
|
|
3792
3792
|
|
|
3793
3793
|
[[package]]
|
|
3794
3794
|
name = "mq-bridge-bindings-common"
|
|
3795
|
-
version = "0.4.
|
|
3795
|
+
version = "0.4.19"
|
|
3796
3796
|
dependencies = [
|
|
3797
3797
|
"anyhow",
|
|
3798
3798
|
"fast-uuid-v7",
|
|
@@ -3806,7 +3806,7 @@ dependencies = [
|
|
|
3806
3806
|
|
|
3807
3807
|
[[package]]
|
|
3808
3808
|
name = "mq-bridge-node"
|
|
3809
|
-
version = "0.4.
|
|
3809
|
+
version = "0.4.19"
|
|
3810
3810
|
dependencies = [
|
|
3811
3811
|
"anyhow",
|
|
3812
3812
|
"async-trait",
|
|
@@ -3861,7 +3861,7 @@ dependencies = [
|
|
|
3861
3861
|
|
|
3862
3862
|
[[package]]
|
|
3863
3863
|
name = "mq-bridge-py"
|
|
3864
|
-
version = "0.4.
|
|
3864
|
+
version = "0.4.19"
|
|
3865
3865
|
dependencies = [
|
|
3866
3866
|
"anyhow",
|
|
3867
3867
|
"async-trait",
|
|
@@ -93,7 +93,7 @@ Every row works from the Rust crate, the Python and Node.js packages, and the ze
|
|
|
93
93
|
| **MongoDB** as source or sink | `mongodb` endpoint · `mongodb` | [MongoDB](https://marcomq.github.io/mq-bridge/connectors/mongodb.html) |
|
|
94
94
|
| **ClickHouse** bulk insert and resumable reads | `clickhouse` endpoint · `clickhouse` | [ClickHouse](https://marcomq.github.io/mq-bridge/connectors/clickhouse.html) |
|
|
95
95
|
| **Search engines** and other bulk document APIs (Meilisearch, Typesense, Elasticsearch, Qdrant, PostgREST / Supabase) | `http_bulk` endpoint · `http-bulk` | [HTTP bulk](https://marcomq.github.io/mq-bridge/connectors/http-bulk.html) |
|
|
96
|
-
| **Object storage**: S3 (and S3-compatible, e.g. R2), GCS, Azure Blob, or a local directory, as **Parquet** or **
|
|
96
|
+
| **Object storage**: S3 (and S3-compatible, e.g. R2), GCS, Azure Blob, or a local directory, as **Parquet**, **JSONL** or **CSV** | `object_store` endpoint with `format: parquet \| raw \| json \| csv` · `object-store`, `parquet` | [Object storage](https://marcomq.github.io/mq-bridge/connectors/object-store.html) |
|
|
97
97
|
| **Files**: CSV and JSONL, read and write | `file` endpoint · built in | [File](https://marcomq.github.io/mq-bridge/connectors/file.html) |
|
|
98
98
|
| **Analytics / warehouses**: Snowflake, BigQuery, Databricks / Spark, Athena / Trino, DuckDB **via Parquet on S3/GCS/Azure**. These are not native connectors: mq-bridge writes the Parquet files, the warehouse loads or queries them | `object_store` with `format: parquet` · `parquet` | [Snowflake](https://marcomq.github.io/mq-bridge/cookbook/snowflake.html) · [BigQuery](https://marcomq.github.io/mq-bridge/cookbook/bigquery.html) · [Databricks / Spark](https://marcomq.github.io/mq-bridge/cookbook/databricks.html) · [Athena / Trino](https://marcomq.github.io/mq-bridge/cookbook/athena.html) · [DuckDB](https://marcomq.github.io/mq-bridge/cookbook/duckdb.html) |
|
|
99
99
|
| **HTTP, gRPC, WebSocket** as server or client, including request/reply | `http`, `grpc`, `websocket` endpoints · `http`, `grpc`, `websocket` | [HTTP](https://marcomq.github.io/mq-bridge/connectors/http.html) · [gRPC](https://marcomq.github.io/mq-bridge/connectors/grpc.html) · [Request / reply](https://marcomq.github.io/mq-bridge/tutorials/request-reply.html) |
|
|
@@ -116,6 +116,8 @@ Throughput is tracked continuously on the public [benchmark dashboard](https://m
|
|
|
116
116
|
| CSV → JSONL, 1M mixed-type rows (~116 MiB) | **2,824,858 rows/s**, ~28 MiB RAM | Meltano (`tap-csv` → `target-jsonl`): ~19,500 rows/s, ~444 MiB RAM — **~145x slower**<br>DuckDB, all cores: 2,036,659 rows/s — mq-bridge **~1.4x faster**, ~17x less memory |
|
|
117
117
|
| Kafka → file, 1M rows, no transform | **~65% faster** than Sea Streamer | Sea Streamer, both on mimalloc (~80% faster vs. its default-allocator build) |
|
|
118
118
|
|
|
119
|
+
The CSV row reuses an existing, independently published 1M-row CSV → JSONL workload, on a byte-identical fixture: 7 mixed-type columns, seed 42, 121,981,421 bytes, SHA-256 `a84894e0…0c45b221` ([full definition](apps/mq-bridge-app/benches/etl/README.md#6--csv--jsonl-vs-meltano)). Whole-process wall-clock, no transformation, Meltano run on the same machine and file.
|
|
120
|
+
|
|
119
121
|
CSV figures: mq-bridge 0.4.12. DuckDB is a throughput ceiling for the conversion itself, not an ETL tool. Methodology and reporting rules are in [`benches/ETL_BENCHMARKS.md`](benches/ETL_BENCHMARKS.md); the raw numbers, baselines and reproducible helpers are in the [ETL benchmark harness](apps/mq-bridge-app/benches/etl/README.md).
|
|
120
122
|
|
|
121
123
|
|
|
@@ -170,17 +172,12 @@ tuning use the same settings in both.
|
|
|
170
172
|
|
|
171
173
|
## Status
|
|
172
174
|
|
|
173
|
-
`mq-bridge`
|
|
175
|
+
`mq-bridge` was created in 2025. Its reliability behavior is exercised by an automated integration and performance suite across supported endpoints, in each of the queue and subscriber modes that endpoint supports:
|
|
174
176
|
|
|
175
177
|
* All endpoints showed **no data loss during in-flight broker restarts**; MQTT publish confirmation was hardened until a chaos test drove in-flight loss to **zero**.
|
|
176
178
|
* Postgres CDC has a **restart-safety test**: an un-acked, in-flight batch is redelivered after a database restart with no loss and no gap.
|
|
177
179
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
- old or very new broker-server versions, or unusual broker settings
|
|
181
|
-
- subscribe/event and response patterns where the backend has no native equivalent (emulated); MongoDB request/reply is only covered by automated tests so far
|
|
182
|
-
- NATS without JetStream (integration tests run with JetStream only)
|
|
183
|
-
- **TLS**: one `TlsConfig` shape is shared by all transports and covered by automated tests, but per-backend certificate matrices are still being expanded, so verify non-trivial TLS setups yourself
|
|
180
|
+
It is used as rust library in [armature](https://github.com/quinnjr/armature) and as python lib in [omniload](https://github.com/panodata/omniload).
|
|
184
181
|
|
|
185
182
|
## Running Tests
|
|
186
183
|
The project includes integration and performance tests. Most backend tests require Docker.
|
|
@@ -700,7 +700,43 @@ stream. File compression/encryption supports only the default `consume` mode. `c
|
|
|
700
700
|
too: the header row is written into the first member, so the decoded stream is a normal CSV
|
|
701
701
|
file.
|
|
702
702
|
|
|
703
|
-
A `csv` sink takes its columns from the first row it writes, in that row's field order.
|
|
703
|
+
A `csv` sink takes its columns from the first row it writes, in that row's field order. An
|
|
704
|
+
`object_store` sink writes each batch as a CSV file of its own, with its own header taken from
|
|
705
|
+
that batch's first row; set `columns` when every object must have the same ones.
|
|
706
|
+
|
|
707
|
+
`csv` on its own means comma-separated, `"`-quoted, with a header record. The `csv` block
|
|
708
|
+
describes any other dialect, for the `file` and `object_store` endpoints:
|
|
709
|
+
|
|
710
|
+
```yaml endpoint
|
|
711
|
+
input:
|
|
712
|
+
file:
|
|
713
|
+
path: "export.csv"
|
|
714
|
+
format: csv
|
|
715
|
+
csv:
|
|
716
|
+
separator: ";" # one character, `tab`, `space`, hex (`0x1f`), or `auto`
|
|
717
|
+
quote: "'" # one character, or `none`; default `"`
|
|
718
|
+
header: false # first record is data; a source then needs `columns`
|
|
719
|
+
columns: [id, name] # replaces the header's names; a sink writes exactly these
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
| Field | Default | Meaning |
|
|
723
|
+
| --- | --- | --- |
|
|
724
|
+
| `separator` | `,` | Field separator. `auto` (sources only) picks whichever of `,` `;` tab `\|` occurs most often outside quotes in the first record, and `,` on a tie. |
|
|
725
|
+
| `quote` | `"` | Quote character; a doubled one inside a quoted field is a literal. `none` reads every byte as data and makes a sink fail a value it would have to quote. |
|
|
726
|
+
| `header` | `true` | Whether the first record names the columns. A sink with `false` writes rows only. |
|
|
727
|
+
| `columns` | — | Source: the keys to use, instead of the header's. Sink: the columns to write, in this order; other keys are dropped. |
|
|
728
|
+
| `nested` | `flatten` | Sink only. `flatten` writes a nested object as one `parent.child` column per leaf; `json` writes its JSON text into one cell. Arrays are always JSON text. |
|
|
729
|
+
|
|
730
|
+
`delimiter` stays the *record* separator and is independent of all this; it only must not
|
|
731
|
+
contain the separator or the quote character. Common exports: Excel "CSV UTF-8" in a
|
|
732
|
+
semicolon locale is `separator: ";"` (the byte-order mark and CRLF are handled already),
|
|
733
|
+
`mongoexport --type=tsv` and `psql -A -F $'\t'` are `separator: tab`, and `psql --csv` and
|
|
734
|
+
`COPY … WITH (FORMAT csv)` are the default. PostgreSQL's `COPY` *text* format (backslash
|
|
735
|
+
escapes, `\N`) and UTF-16 files are not CSV dialects and are not read.
|
|
736
|
+
|
|
737
|
+
A row with more fields than the header drops the extras, and one with fewer reads the missing
|
|
738
|
+
ones as empty. Each is warned about once per process; a short row is the usual sign of a wrong
|
|
739
|
+
`separator`.
|
|
704
740
|
|
|
705
741
|
A file **source** must declare the same `compression`/`encryption` the data was written with.
|
|
706
742
|
A mismatch (wrong key, wrong codec, or a missing field) is a permanent decode failure: the
|
|
@@ -1151,12 +1187,16 @@ to keep a counter: the arithmetic runs here, so no request is made per message.
|
|
|
1151
1187
|
| `output` | expression | the state itself; shapes what is written to the message |
|
|
1152
1188
|
| `emit` | `updated` \| `previous` | `updated` |
|
|
1153
1189
|
| `entries` | list of `{key, expression, fields, into, output, emit}` | `[]`; further aggregates |
|
|
1154
|
-
| `store` | URL |
|
|
1155
|
-
| `consistency` | `shared` \| `single_writer` | `shared`;
|
|
1190
|
+
| `store` | URL | –; `postgres://…/db[/table]`, `sqlite://…`, `mongodb://host/db[/collection]`. Without it `consistency: single_writer` is required |
|
|
1191
|
+
| `consistency` | `shared` \| `single_writer` | `shared`, which needs a `store`; `single_writer` without a `store` keeps the states in memory only |
|
|
1156
1192
|
| `max_keys` | integer | `1000000`; states kept in memory per entry, `0` is unlimited |
|
|
1193
|
+
| `time` | dotted payload path | – (the clock); the message's event time, for `fields` entries |
|
|
1194
|
+
| `on_error` | `drop` \| `fail` \| `skip` | `drop`; what happens to a message that cannot be folded |
|
|
1195
|
+
| `read_only` | bool | `false`; reads the states of the `store` and never changes them |
|
|
1157
1196
|
|
|
1158
1197
|
```yaml middleware
|
|
1159
1198
|
- aggregate:
|
|
1199
|
+
consistency: single_writer
|
|
1160
1200
|
key: "${payload:sensor_id}"
|
|
1161
1201
|
into: sensor
|
|
1162
1202
|
expression: "{ total: (state.total ?? 0) + reading, count: (state.count ?? 0) + 1 }"
|
|
@@ -1166,6 +1206,11 @@ to keep a counter: the arithmetic runs here, so no request is made per message.
|
|
|
1166
1206
|
`{"sensor_id": 7, "reading": 20, "sensor": {"total": 20, "count": 1}}`; the next message for sensor 7
|
|
1167
1207
|
continues from that state.
|
|
1168
1208
|
|
|
1209
|
+
**States in memory only are opt-in.** Without a `store` the states are lost on restart and
|
|
1210
|
+
not shared between instances, so that has to be asked for with `consistency: single_writer`,
|
|
1211
|
+
as above. An `aggregate` with neither a `store` nor `consistency: single_writer` is a startup
|
|
1212
|
+
error.
|
|
1213
|
+
|
|
1169
1214
|
**Expressions** are the ones [`filter`](#filter) and [`transform`](#transform) use. They read
|
|
1170
1215
|
payload fields by name and metadata as `meta.<key>`, plus `state`: the value `expression`
|
|
1171
1216
|
returned for the previous message with the same key. For a key seen for the first time
|
|
@@ -1184,6 +1229,7 @@ to forget it. Keep the weighted sum and the weight instead and divide when writi
|
|
|
1184
1229
|
|
|
1185
1230
|
```yaml middleware
|
|
1186
1231
|
- aggregate:
|
|
1232
|
+
consistency: single_writer
|
|
1187
1233
|
key: "${payload:sensor_id}"
|
|
1188
1234
|
into: sensor.avg_reading
|
|
1189
1235
|
expression: "{ s: (state.s ?? 0) * 0.99 + reading, w: (state.w ?? 0) * 0.99 + 1 }"
|
|
@@ -1197,6 +1243,7 @@ the usual form still reads 216.
|
|
|
1197
1243
|
|
|
1198
1244
|
```yaml middleware
|
|
1199
1245
|
- aggregate:
|
|
1246
|
+
consistency: single_writer
|
|
1200
1247
|
entries:
|
|
1201
1248
|
- key: "${payload:sensor_id}"
|
|
1202
1249
|
into: features.sensor
|
|
@@ -1212,6 +1259,7 @@ times faster, because no expression runs and the payload is not parsed into a tr
|
|
|
1212
1259
|
|
|
1213
1260
|
```yaml middleware
|
|
1214
1261
|
- aggregate:
|
|
1262
|
+
consistency: single_writer
|
|
1215
1263
|
key: "${payload:sensor_id}"
|
|
1216
1264
|
into: sensor
|
|
1217
1265
|
fields:
|
|
@@ -1228,14 +1276,84 @@ times faster, because no expression runs and the payload is not parsed into a tr
|
|
|
1228
1276
|
| `mean(path)` | arithmetic mean |
|
|
1229
1277
|
| `stddev(path)`, `variance(path)` | sample standard deviation and variance (divided by n − 1) of all values; `null` for the first message |
|
|
1230
1278
|
| `ema(path, alpha)` | moving average weighting each new value with `alpha` (0 < alpha ≤ 1), without a start bias: the first message reads its own value |
|
|
1231
|
-
| `
|
|
1279
|
+
| `ema(path, half_life)` | the same, weighted by time: a value counts half after `half_life`, e.g. `ema(reading, 5m)`. Units: `ms`, `s`, `m`, `h`, `d` |
|
|
1280
|
+
| `ema_stddev(path, alpha)`, `ema_variance(path, alpha)` | the same over values weighted like `ema`, so old values fade; `null` for the first message. Both take a half-life in place of `alpha` too |
|
|
1232
1281
|
|
|
1233
1282
|
`path` is a dotted payload path such as `reading` or `device.reading`. Its value must be a
|
|
1234
|
-
number or a numeric string (what a CSV source delivers); a message without one
|
|
1235
|
-
|
|
1283
|
+
number or a numeric string (what a CSV source delivers); a message without one cannot be
|
|
1284
|
+
folded, see [`on_error`](#aggregate-on-error). The result is an object with the field names in
|
|
1236
1285
|
alphabetical order, e.g. `{"avg": 20.0, "high": 20.0, "n": 1, "total": 20.0}`. An entry takes
|
|
1237
1286
|
either `expression` or `fields`; entries of both kinds can be mixed. `fields` takes no `output`.
|
|
1238
1287
|
|
|
1288
|
+
**Time.** `ema(path, alpha)` counts messages: ten messages in one second fade a value as
|
|
1289
|
+
much as ten messages in one day. With a half-life the weight follows the time between two
|
|
1290
|
+
messages of a key instead. `time` names the payload field holding the message's time: epoch
|
|
1291
|
+
seconds, epoch milliseconds (any number above 1e11), or an RFC 3339 text such as
|
|
1292
|
+
`2026-10-03T12:00:00Z`; a text without a zone is read as UTC. Without `time` the clock of
|
|
1293
|
+
this process is used, which makes a replay compute different values.
|
|
1294
|
+
|
|
1295
|
+
```yaml middleware
|
|
1296
|
+
- aggregate:
|
|
1297
|
+
consistency: single_writer
|
|
1298
|
+
key: "${payload:sensor_id}"
|
|
1299
|
+
into: sensor
|
|
1300
|
+
time: measured_at
|
|
1301
|
+
fields:
|
|
1302
|
+
n: count
|
|
1303
|
+
avg: ema(reading, 5m)
|
|
1304
|
+
spread: ema_stddev(reading, 1h)
|
|
1305
|
+
```
|
|
1306
|
+
|
|
1307
|
+
**Late messages are detected, not corrected.** With `time` set, every `fields` state
|
|
1308
|
+
remembers the newest time it has seen. A message with an older time is folded as if it had
|
|
1309
|
+
arrived at that newest time (nothing decays for it), and it carries the metadata
|
|
1310
|
+
`mqb.aggregate.late` naming the entries concerned by their `into`, comma-separated. A
|
|
1311
|
+
[`filter`](#filter) or a `switch` can act on it as `meta["mqb.aggregate.late"]`. The first
|
|
1312
|
+
occurrence is logged as a warning. `time` adds one slot to each `fields` state; states stored
|
|
1313
|
+
before it was set are read and extended. Expression entries do not use `time`.
|
|
1314
|
+
|
|
1315
|
+
<a id="aggregate-on-error"></a>
|
|
1316
|
+
**A message that cannot be folded.** Its payload is not a JSON object, a `key` has no value,
|
|
1317
|
+
a field read by `fields` or `time` is missing or not a number, or an expression fails. One
|
|
1318
|
+
entry that cannot be computed is enough. `on_error` decides what follows; no state changes
|
|
1319
|
+
for an entry that was not computed.
|
|
1320
|
+
|
|
1321
|
+
| `on_error` | On an input | On an output |
|
|
1322
|
+
|---|---|---|
|
|
1323
|
+
| `drop` (default) | logged, acked and dropped. **The source sees a success**: an HTTP caller gets `202` | only that message fails, as non-retryable |
|
|
1324
|
+
| `fail` | logged and nacked, so the source sees the failure: an HTTP caller gets `500`. A source that redelivers nacked messages (a broker) delivers it again | as `drop` |
|
|
1325
|
+
| `skip` | the entries that cannot be computed are left out, the others run, and the message goes on. A message no entry can fold goes on unchanged | the same |
|
|
1326
|
+
|
|
1327
|
+
A message that left entries out under `skip` carries the metadata `mqb.aggregate.skipped`
|
|
1328
|
+
with their `into` paths, comma-separated, and the first occurrence is logged as a warning;
|
|
1329
|
+
the reason for each is logged at debug level.
|
|
1330
|
+
|
|
1331
|
+
```yaml middleware
|
|
1332
|
+
- aggregate:
|
|
1333
|
+
consistency: single_writer
|
|
1334
|
+
on_error: skip
|
|
1335
|
+
entries:
|
|
1336
|
+
- { key: "${payload:sensor_id}", into: sensor, fields: { avg: "ema(reading, 0.01)" } }
|
|
1337
|
+
- { key: "${payload:site_id}", into: site, fields: { high: max(reading) } }
|
|
1338
|
+
```
|
|
1339
|
+
|
|
1340
|
+
**Reading without writing.** `read_only: true` computes and writes into the message as
|
|
1341
|
+
usual but stores nothing, so a dry run or a second route can use the states another route
|
|
1342
|
+
maintains. `emit: updated` shows what the state would become with this message,
|
|
1343
|
+
`emit: previous` the stored state as it is. It needs a `store`; states are loaded per batch
|
|
1344
|
+
whatever `consistency` says, and each message of a batch sees the stored state, not the
|
|
1345
|
+
messages before it.
|
|
1346
|
+
|
|
1347
|
+
```yaml middleware
|
|
1348
|
+
- aggregate:
|
|
1349
|
+
store: "postgres://localhost/telemetry/sensor_states"
|
|
1350
|
+
read_only: true
|
|
1351
|
+
emit: previous
|
|
1352
|
+
key: "${payload:sensor_id}"
|
|
1353
|
+
into: sensor
|
|
1354
|
+
fields: { n: count, avg: "ema(reading, 0.01)" }
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1239
1357
|
**Keeping the states in a store.** With `store` the states survive a restart. The table or
|
|
1240
1358
|
collection defaults to `mqb_aggregate_<route>` and is created on start; PostgreSQL, SQLite
|
|
1241
1359
|
and MongoDB are supported.
|
|
@@ -1283,7 +1401,7 @@ and MongoDB are supported.
|
|
|
1283
1401
|
**What to expect.**
|
|
1284
1402
|
|
|
1285
1403
|
- **Without `store`, state lives in memory only.** It is lost on restart and it is not shared
|
|
1286
|
-
between instances
|
|
1404
|
+
between instances, which is why it needs `consistency: single_writer`.
|
|
1287
1405
|
- **Memory is bounded by `max_keys`.** An entry keeps at most that many states in memory,
|
|
1288
1406
|
one million unless set. When it is full, the half that was used least recently is dropped.
|
|
1289
1407
|
Without a `store` those states are forgotten: their key starts again from an empty state,
|
|
@@ -1295,13 +1413,13 @@ and MongoDB are supported.
|
|
|
1295
1413
|
first: on an input, list it *after* `aggregate` (see [Ordering](#ordering--read-this-before-combining-middleware)).
|
|
1296
1414
|
- **Order matters for order-dependent states** such as a moving average. Within a batch
|
|
1297
1415
|
messages are folded in order; with a route `concurrency` above 1 the order across batches
|
|
1298
|
-
is not guaranteed.
|
|
1299
|
-
- **A message that cannot be folded fails alone** and changes no state
|
|
1300
|
-
|
|
1301
|
-
|
|
1416
|
+
is not guaranteed. With `time`, a message older than its state is marked, not reordered.
|
|
1417
|
+
- **A message that cannot be folded fails alone** and changes no state. By default an input
|
|
1418
|
+
drops it and still acks it, so an HTTP caller gets `202`; see
|
|
1419
|
+
[`on_error`](#aggregate-on-error) for `fail` and `skip`.
|
|
1302
1420
|
- **No windows and no expiry by time.** There is no "last hour" and no time to live: a state
|
|
1303
1421
|
covers every message of its key, and a row in the store is never removed. `ema` and
|
|
1304
|
-
`ema_stddev` stand in for a sliding window. For fixed windows put the window into the key,
|
|
1422
|
+
`ema_stddev` stand in for a sliding window, by message count or with a half-life by time. For fixed windows put the window into the key,
|
|
1305
1423
|
e.g. `key: "${payload:sensor_id}:${payload:hour}"`, and use a `store` with `shared`, which
|
|
1306
1424
|
keeps no state in memory; the rows of past windows stay until you delete them.
|
|
1307
1425
|
- **No exactly-once and no key ownership.** A stream processor commits state and input
|