├── .vscode
├── settings.json
└── launch.json
├── key.snk
├── .DS_Store
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
└── workflows
│ ├── integration.yml
│ └── gh-pages.yml
├── docs
├── favicon.ico
└── assets
│ ├── state-store.png
│ ├── async-topology.png
│ ├── request-response.png
│ ├── threading-model.png
│ └── logo-kafka-stream-net.png
├── resources
├── streamiz_v1.0.ai
├── Untitled.drawio
├── logo-kafka-stream-net.png
└── old_logo-kafka-stream-net-1.0.png
├── global.json
├── core
├── Processors
│ ├── ICloneableProcessor.cs
│ ├── IProcessorSupplier.cs
│ ├── Internal
│ │ ├── TaskStateTransitionValidator.cs
│ │ ├── ThreadStateTransitionValidator.cs
│ │ ├── IGlobalStateManager.cs
│ │ ├── IChangelogReader.cs
│ │ ├── IChangelogRegister.cs
│ │ ├── IGlobalStateMaintainer.cs
│ │ ├── StaticTopicNameExtractor.cs
│ │ ├── WrapperTopicNameExtractor.cs
│ │ ├── DefaultRecordTimestampExtractor.cs
│ │ ├── StateRestoreCallback.cs
│ │ ├── WrapperRecordTimestampExtractor.cs
│ │ ├── ObjectDeserialized.cs
│ │ ├── GlobalProcessorContext.cs
│ │ ├── ExtractRecordMetadataTimestamp.cs
│ │ ├── WrapperStreamPartitioner.cs
│ │ ├── IStateManager.cs
│ │ ├── FailOnInvalidTimestamp.cs
│ │ └── TaskId.cs
│ ├── PassThroughProcessor.cs
│ ├── ThreadStateListener.cs
│ ├── IKTableProcessorSupplier.cs
│ ├── ITopicManager.cs
│ ├── IKStreamAggProcessorSupplier.cs
│ ├── IAsyncProcessor.cs
│ ├── IThread.cs
│ ├── Public
│ │ ├── WrappedProcessor.cs
│ │ ├── WrappedTransformer.cs
│ │ └── PunctuationType.cs
│ ├── KStreamMapProcessor.cs
│ ├── KStreamPrintProcessor.cs
│ ├── KStreamPeekProcessor.cs
│ ├── KStreamFilterProcessor.cs
│ ├── KStreamTimestampProcessor.cs
│ ├── IRecordTimestampExtractor.cs
│ ├── KStreamJoinWindowProcessor.cs
│ ├── KStreamProcessor.cs
│ ├── UnwindowedChangelogTopicConfig.cs
│ ├── KStreamBranchProcessor.cs
│ ├── KStreamFlatMapProcessor.cs
│ ├── KStreamForeachAsyncProcessor.cs
│ ├── ITopicNameExtractor.cs
│ ├── KStreamFlatMapValuesProcessor.cs
│ ├── IStreamPartitioner.cs
│ ├── RepartitionTopicConfig.cs
│ ├── AbstractKTableKTableJoinProcessor.cs
│ ├── KStreamFlatMapAsyncProcessor.cs
│ ├── InternalTopicConfig.cs
│ ├── KStreamPAPI.cs
│ ├── IProcessor.cs
│ ├── KTableKTableJoinMergeProcessor.cs
│ └── IRecordQueue.cs
├── Metrics
│ ├── Stats
│ │ ├── IStat.cs
│ │ ├── IMeasurable.cs
│ │ ├── IMetricValueProvider.cs
│ │ ├── IMeasurableStat.cs
│ │ ├── CumulativeCount.cs
│ │ ├── IGauge.cs
│ │ ├── WindowedCount.cs
│ │ ├── Value.cs
│ │ ├── ImmutableMetricValue.cs
│ │ ├── ProviderMetricValue.cs
│ │ ├── CumulativeSum.cs
│ │ ├── WindowedSum.cs
│ │ ├── Avg.cs
│ │ ├── Min.cs
│ │ └── Max.cs
│ ├── Librdkafka
│ │ ├── IStatisticsHandler.cs
│ │ ├── TopicStatistic.cs
│ │ ├── ConsumerGroupStatistic.cs
│ │ └── IdempotentProducerStatistic.cs
│ ├── MetricUtils.cs
│ ├── MetricsRecordingLevel.cs
│ └── Internal
│ │ ├── NoRunnableSensor.cs
│ │ └── RocksDBMetricsRecordingTrigger.cs
├── Streamiz.Kafka.Net.csproj.user
├── State
│ ├── Internal
│ │ ├── ISegment.cs
│ │ ├── ITimestampedStore.cs
│ │ ├── ISegments.cs
│ │ ├── GlobalStateStoreProviderFacade.cs
│ │ ├── IKeySchema.cs
│ │ ├── TimestampedWindowStoreMaterializer.cs
│ │ └── ISegmentedBytesStore.cs
│ ├── IReadOnlySessionStore.cs
│ ├── Supplier
│ │ ├── ISessionBytesStoreSupplier.cs
│ │ ├── IKeyValueBytesStoreSupplier.cs
│ │ └── IStoreSupplier.cs
│ ├── Cache
│ │ ├── ICachedStateStore.cs
│ │ ├── ICacheFunction.cs
│ │ ├── Internal
│ │ │ ├── IClockTime.cs
│ │ │ ├── PostEvictionDelegate.cs
│ │ │ └── PostEvictionCallbackRegistration.cs
│ │ └── CacheEntryValue.cs
│ ├── ISessionStore.cs
│ ├── ITimestampedKeyValueStore.cs
│ ├── RocksDb
│ │ ├── Internal
│ │ │ ├── RocksDbSegmentedBytesStore.cs
│ │ │ └── RocksDbKeyValueSegment.cs
│ │ └── IRocksDbAdapter.cs
│ ├── Enumerator
│ │ ├── EnumeratorExtensions.cs
│ │ ├── IWindowStoreEnumerator.cs
│ │ ├── IKeyValueEnumerator.cs
│ │ └── EmptyEnumerator.cs
│ ├── Suppress
│ │ ├── ITimeOrderedKeyValueBuffer.cs
│ │ ├── Internal
│ │ │ ├── BufferKey.cs
│ │ │ └── Maybe.cs
│ │ └── InMemoryTimeOrderedKeyValueChangeBufferBuilder.cs
│ ├── ITimestampedWindowStore.cs
│ ├── Logging
│ │ ├── ChangeLoggingTimestampedWindowBytesStore.cs
│ │ └── ChangeLoggingTimestampedKeyValueBytesStore.cs
│ ├── IWindowStore.cs
│ ├── InMemory
│ │ └── Internal
│ │ │ └── InMemoryKeyValueEnumerator.cs
│ └── Metered
│ │ └── MeteredTimestampedKeyValueStore.cs
├── Stream
│ ├── Internal
│ │ ├── INameProvider.cs
│ │ ├── Graph
│ │ │ ├── PassThrough.cs
│ │ │ ├── Nodes
│ │ │ │ ├── RootNode.cs
│ │ │ │ ├── StreamSourceNode.cs
│ │ │ │ ├── ProcessorParameters.cs
│ │ │ │ ├── StateStoreNode.cs
│ │ │ │ ├── ProcessorGraphNode.cs
│ │ │ │ └── AbstractRepartitionNode.cs
│ │ │ ├── KStreamJoinWindow.cs
│ │ │ ├── KStreamMap.cs
│ │ │ ├── KStreamFlatMapValues.cs
│ │ │ ├── KStreamFlatMap.cs
│ │ │ ├── KStreamFilter.cs
│ │ │ ├── KStreamTimestampExtractor.cs
│ │ │ ├── KStreamProcessorSupplier.cs
│ │ │ ├── KStreamPeek.cs
│ │ │ ├── KStreamBranch.cs
│ │ │ ├── KStreamMapValues.cs
│ │ │ ├── KStreamTransformerSupplier.cs
│ │ │ ├── KStreamForeachAsync.cs
│ │ │ ├── KStreamMapAsync.cs
│ │ │ ├── KStreamFlatMapAsync.cs
│ │ │ ├── KStreamDropDuplicate.cs
│ │ │ ├── KStreamKStreamJoin.cs
│ │ │ ├── KStreamReduce.cs
│ │ │ ├── KStreamKTableJoin.cs
│ │ │ ├── KStreamGlobalKTableJoin.cs
│ │ │ └── KStreamMapValuesAsync.cs
│ │ ├── Joined.cs
│ │ └── ConsumedInternal.cs
│ ├── Initializer.cs
│ └── ExternalContext.cs
├── Crosscutting
│ ├── LongComparer.cs
│ ├── WatermarkOffsetsByTopicPartition.cs
│ ├── ICloneable.cs
│ └── ActionHelper.cs
├── Table
│ └── Internal
│ │ ├── IKTableValueGetterSupplier.cs
│ │ ├── IKTableValueGetter.cs
│ │ ├── Change.cs
│ │ ├── Graph
│ │ ├── Nodes
│ │ │ ├── TableProcessorParameters.cs
│ │ │ └── GroupedTableRepartitionNode.cs
│ │ ├── KTableKTableInnerJoin.cs
│ │ ├── KTableKTableLeftJoin.cs
│ │ ├── KTableKTableOuterJoin.cs
│ │ ├── KTableKTableRightJoin.cs
│ │ ├── KTableSource.cs
│ │ ├── KTableReduce.cs
│ │ └── AbstractKTableKTableJoin.cs
│ │ ├── GlobalKTable.cs
│ │ ├── GenericKTableValueGetterSupplier.cs
│ │ ├── TimestampedKeyValueStoreGetter.cs
│ │ ├── WindowKeyValueStoreGetter.cs
│ │ └── AbstractKTableKTableJoinValueGetterSupplier.cs
├── Errors
│ ├── TaskMigratedException.cs
│ ├── NotEnoughtTimeException.cs
│ ├── StreamConfigException.cs
│ ├── NoneRetryableException.cs
│ ├── NotMoreValueException.cs
│ ├── StreamProducerException.cs
│ ├── TopologyException.cs
│ ├── ProductionException.cs
│ ├── ProcessorStateException.cs
│ ├── IllegalStateException.cs
│ └── DeserializationException.cs
├── Mock
│ ├── Sync
│ │ └── ISyncPublisher.cs
│ ├── Pipes
│ │ ├── IPipeBuilder.cs
│ │ ├── IPipeInput.cs
│ │ ├── IPipeOutput.cs
│ │ └── SyncPipeInput.cs
│ ├── ConcurrentTestInputTopic.cs
│ ├── MockChangelogRegister.cs
│ ├── MockOffsetCheckpointManager.cs
│ ├── IBehaviorTopologyTestDriver.cs
│ └── Kafka
│ │ └── KafkaPipeBuilder.cs
├── SerDes
│ ├── Internal
│ │ └── BytesSerDes.cs
│ ├── SerDesContext.cs
│ ├── CharSerDes.cs
│ ├── Int32SerDes.cs
│ ├── ByteArraySerDes.cs
│ ├── Int64SerDes.cs
│ ├── FloatSerDes.cs
│ └── DoubleSerDes.cs
├── Kafka
│ └── IRecordCollector.cs
├── EnumerableExtensions.cs
├── ExceptionHandlerResponse.cs
├── StreamOptions.cs
└── RandomGenerator.cs
├── update-client-kafka.sh
├── environment
├── confs
│ ├── prometheus.yaml
│ └── otel-collector-config.yaml
└── start.sh
├── .gitignore
├── test
└── Streamiz.Kafka.Net.Tests
│ ├── Helpers
│ ├── Proto
│ │ ├── order.proto
│ │ └── person.proto
│ ├── SerdesThrowException.cs
│ ├── MockProcessorContext.cs
│ ├── DictionaryExtensionsTests.cs
│ └── StreamConfigExtension.cs
│ ├── Private
│ ├── RocksDbWindowKeySchemaTests.cs
│ ├── ConcurrentSortedDictionaryTests.cs
│ ├── TestLogger.cs
│ ├── InternalTopologyBuilderTests.cs
│ ├── SerDes
│ │ ├── CharSerDesTests.cs
│ │ └── Int32SerDesTests.cs
│ └── OrderedBytesTests.cs
│ ├── Processors
│ └── KStreamKStreamWindowed
│ │ ├── Base
│ │ └── JoinSlidingWindowOptions.cs
│ │ └── KStreamKStreamWindowedInnerJoinTests.cs
│ ├── Public
│ ├── TopologyBuilderTests.cs
│ └── StreamTableJoinPropsTests.cs
│ ├── log4net.config
│ ├── Stores
│ ├── CachingInMemoryWindowStoreTests.cs
│ └── CachingPersistentWindowStoreTests.cs
│ └── Metrics
│ └── Stats
│ ├── ProviderMetricValueTests.cs
│ └── ImmutableMetricValueTests.cs
├── .gitpod.Dockerfile
├── launcher
├── sample-stream
│ ├── .dockerignore
│ ├── Dockerfile
│ └── log4net.config
└── sample-stream-demo
│ ├── .dockerignore
│ ├── sample-stream-demo.csproj
│ └── Dockerfile
├── remote
└── Streamiz.Kafka.Net.Azure.RemoteStorage
│ ├── Internal
│ └── AzureTableEntity.cs
│ ├── AzureRemoteStorageOptions.cs
│ └── AzureRemoteStorageSupplier.cs
├── metrics
└── Streamiz.Kafka.Net.Metrics.Prometheus
│ └── Internal
│ ├── Gauge.cs
│ └── PrometheusMetricsExporter.cs
├── Makefile
├── roadmap.md
└── LICENSE
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | }
--------------------------------------------------------------------------------
/key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/key.snk
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/.DS_Store
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: LGouellec
2 | custom: https://www.paypal.me/slegouellec
3 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/assets/state-store.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/docs/assets/state-store.png
--------------------------------------------------------------------------------
/resources/streamiz_v1.0.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/resources/streamiz_v1.0.ai
--------------------------------------------------------------------------------
/resources/Untitled.drawio:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/assets/async-topology.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/docs/assets/async-topology.png
--------------------------------------------------------------------------------
/docs/assets/request-response.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/docs/assets/request-response.png
--------------------------------------------------------------------------------
/docs/assets/threading-model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/docs/assets/threading-model.png
--------------------------------------------------------------------------------
/docs/assets/logo-kafka-stream-net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/docs/assets/logo-kafka-stream-net.png
--------------------------------------------------------------------------------
/resources/logo-kafka-stream-net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/resources/logo-kafka-stream-net.png
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "6.0",
4 | "rollForward": "latestMajor",
5 | "allowPrerelease": true
6 | }
7 | }
--------------------------------------------------------------------------------
/resources/old_logo-kafka-stream-net-1.0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LGouellec/streamiz/HEAD/resources/old_logo-kafka-stream-net-1.0.png
--------------------------------------------------------------------------------
/core/Processors/ICloneableProcessor.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Processors
2 | {
3 | internal interface ICloneableProcessor
4 | {
5 | object Clone();
6 | }
7 | }
--------------------------------------------------------------------------------
/core/Processors/IProcessorSupplier.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Processors
2 | {
3 | internal interface IProcessorSupplier
4 | {
5 | IProcessor Get();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/core/Metrics/Stats/IStat.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | internal interface IStat
4 | {
5 | void Record(MetricConfig config, double value, long timeMs);
6 | }
7 | }
--------------------------------------------------------------------------------
/core/Streamiz.Kafka.Net.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/update-client-kafka.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | for file in `find . -type f -name "*.csproj"`; do
4 | sed -i '' -e "s/Include=\"Confluent\(.*\)\" Version=\"\(.*\)\"/Include=\"Confluent\1\" Version=\"$1\"/g" $file
5 | done
--------------------------------------------------------------------------------
/core/Metrics/Stats/IMeasurable.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | internal interface IMeasurable : IMetricValueProvider
4 | {
5 | double Measure(MetricConfig config, long now);
6 | }
7 | }
--------------------------------------------------------------------------------
/environment/confs/prometheus.yaml:
--------------------------------------------------------------------------------
1 | scrape_configs:
2 | - job_name: 'otel-collector'
3 | scrape_interval: 10s
4 | static_configs:
5 | - targets: ['otel-collector:8889']
6 | - targets: ['otel-collector:8888']
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | obj
3 | .vs
4 | coverage.*opencover.xml
5 | coverage.json
6 | kafka-stream-net.sln.DotSettings.user
7 | _build
8 | build
9 | TestResults
10 |
11 | .idea/
12 | .vscode/
13 |
14 | confidential
15 | roadmap.md
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Helpers/Proto/order.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package Streamiz.Kafka.Net.Tests.Helpers.Proto;
4 |
5 | message Order {
6 | int32 order_id = 1;
7 | float price = 2;
8 | int32 product_id = 3;
9 | }
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Helpers/Proto/person.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package Streamiz.Kafka.Net.Tests.Helpers.Proto;
4 |
5 | message Person {
6 | string firstName = 1;
7 | string lastName= 2;
8 | int32 age = 3;
9 | }
--------------------------------------------------------------------------------
/core/State/Internal/ISegment.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Crosscutting;
2 |
3 | namespace Streamiz.Kafka.Net.State.Internal
4 | {
5 | internal interface ISegment : IKeyValueStore
6 | {
7 | void Destroy();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/core/Processors/Internal/TaskStateTransitionValidator.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Processors.Internal
2 | {
3 | internal interface TaskStateTransitionValidator
4 | {
5 | bool IsValidTransition(TaskStateTransitionValidator newState);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/core/Processors/Internal/ThreadStateTransitionValidator.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Processors.Internal
2 | {
3 | internal interface ThreadStateTransitionValidator
4 | {
5 | bool IsValidTransition(ThreadStateTransitionValidator newState);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/core/Stream/Internal/INameProvider.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Stream.Internal
2 | {
3 | internal interface INameProvider
4 | {
5 | string NewProcessorName(string prefix);
6 |
7 | string NewStoreName(string prefix);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/core/Metrics/Librdkafka/IStatisticsHandler.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Librdkafka
2 | {
3 | internal interface IStatisticsHandler
4 | {
5 | void Register(StreamMetricsRegistry metricsRegistry);
6 | void Publish(Statistics statistics);
7 | }
8 | }
--------------------------------------------------------------------------------
/core/State/Internal/ITimestampedStore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace Streamiz.Kafka.Net.State.Internal
3 | {
4 | ///
5 | /// Empty interface used by timestamped state store.
6 | ///
7 | public interface ITimestampedStore
8 | {
9 | }
10 | }
--------------------------------------------------------------------------------
/core/Metrics/Stats/IMetricValueProvider.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | ///
4 | /// Super interface for and
5 | ///
6 | internal interface IMetricValueProvider
7 | {
8 | }
9 | }
--------------------------------------------------------------------------------
/core/Crosscutting/LongComparer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Streamiz.Kafka.Net.Crosscutting
4 | {
5 | internal class LongComparer : IComparer
6 | {
7 | public int Compare(long x, long y)
8 | => x.CompareTo(y);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.gitpod.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM gitpod/workspace-full:latest
2 |
3 | USER gitpod
4 | #.NET installed via .gitpod.yml task until the following issue is fixed: https://github.com/gitpod-io/gitpod/issues/5090
5 | ENV DOTNET_ROOT=/tmp/dotnet
6 | ENV PATH=$PATH:/tmp/dotnet
7 |
8 | RUN sudo apt-get -y install librocksdb-dev
--------------------------------------------------------------------------------
/core/Table/Internal/IKTableValueGetterSupplier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Table.Internal
4 | {
5 | internal interface IKTableValueGetterSupplier
6 | {
7 | IKTableValueGetter Get();
8 |
9 | String[] StoreNames { get; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/core/Errors/TaskMigratedException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Errors
4 | {
5 | internal class TaskMigratedException : Exception
6 | {
7 | public TaskMigratedException(string message)
8 | : base(message)
9 | {
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/core/Metrics/Stats/IMeasurableStat.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | ///
4 | /// Used for , , ...
5 | ///
6 | internal interface IMeasurableStat : IStat, IMeasurable
7 | {
8 |
9 | }
10 | }
--------------------------------------------------------------------------------
/core/Processors/PassThroughProcessor.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Processors
2 | {
3 | internal class PassThroughProcessor : AbstractProcessor
4 | {
5 | public override void Process(K key, V value)
6 | {
7 | this.Forward(key, value);
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/PassThrough.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 |
3 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
4 | {
5 | internal class PassThrough : IProcessorSupplier
6 | {
7 | public IProcessor Get() => new PassThroughProcessor();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/core/Metrics/Stats/CumulativeCount.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | internal class CumulativeCount : CumulativeSum
4 | {
5 | public override void Record(MetricConfig config, double value, long timeMs)
6 | {
7 | base.Record(config, 1, timeMs);
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Private/RocksDbWindowKeySchemaTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 |
3 | namespace Streamiz.Kafka.Net.Tests.Private
4 | {
5 | public class RocksDbWindowKeySchemaTests
6 | {
7 | [Test]
8 | public void test()
9 | {
10 | // TODOTEST
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/core/State/IReadOnlySessionStore.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.State
2 | {
3 | ///
4 | /// NOT IMPLEMENTED FOR MOMENT
5 | ///
6 | ///
7 | ///
8 | public interface IReadOnlySessionStore
9 | {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/core/Table/Internal/IKTableValueGetter.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.State;
2 |
3 | namespace Streamiz.Kafka.Net.Table.Internal
4 | {
5 | internal interface IKTableValueGetter
6 | {
7 | void Init(ProcessorContext context);
8 |
9 | ValueAndTimestamp Get(K key);
10 |
11 | void Close();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/Metrics/Stats/IGauge.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | internal interface IGauge
4 | {
5 | object Value(MetricConfig config, long now);
6 | }
7 |
8 | internal interface IGauge : IMetricValueProvider, IGauge
9 | {
10 | new T Value(MetricConfig config, long now);
11 | }
12 | }
--------------------------------------------------------------------------------
/core/Metrics/Stats/WindowedCount.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | internal class WindowedCount : WindowedSum
4 | {
5 | protected override void Update(Sample sample, MetricConfig config, double value, long timeMs)
6 | {
7 | base.Update(sample, config, 1.0, timeMs);
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/core/Processors/Internal/IGlobalStateManager.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Streamiz.Kafka.Net.Processors.Internal
4 | {
5 | internal interface IGlobalStateManager : IStateManager
6 | {
7 | ISet Initialize();
8 |
9 | void SetGlobalProcessorContext(ProcessorContext processorContext);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/core/State/Supplier/ISessionBytesStoreSupplier.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Crosscutting;
2 |
3 | namespace Streamiz.Kafka.Net.State.Supplier
4 | {
5 | ///
6 | /// NOT IMPLEMENTED FOR MOMENT
7 | ///
8 | public interface ISessionBytesStoreSupplier : IStoreSupplier>
9 | {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/core/State/Cache/ICachedStateStore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Streamiz.Kafka.Net.Table.Internal;
4 |
5 | namespace Streamiz.Kafka.Net.State.Cache
6 | {
7 | internal interface ICachedStateStore
8 | {
9 | bool SetFlushListener(Action>> listener, bool sendOldChanges);
10 | }
11 | }
--------------------------------------------------------------------------------
/core/Mock/Sync/ISyncPublisher.cs:
--------------------------------------------------------------------------------
1 | using Confluent.Kafka;
2 | using System;
3 |
4 | namespace Streamiz.Kafka.Net.Mock.Sync
5 | {
6 | internal interface ISyncPublisher
7 | {
8 | public void PublishRecord(string topic, byte[] key, byte[] value, DateTime timestamp, Headers headers);
9 | public void Flush();
10 | public void Close();
11 | }
12 | }
--------------------------------------------------------------------------------
/core/Mock/Pipes/IPipeBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace Streamiz.Kafka.Net.Mock.Pipes
5 | {
6 | internal interface IPipeBuilder
7 | {
8 | IPipeInput Input(string topic, IStreamConfig configuration);
9 |
10 | IPipeOutput Output(string topic, TimeSpan consumeTimeout, IStreamConfig configuration, CancellationToken token = default);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/core/State/ISessionStore.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 |
3 | namespace Streamiz.Kafka.Net.State
4 | {
5 | ///
6 | /// NOT IMPLEMENTED FOR MOMENT
7 | ///
8 | ///
9 | ///
10 | public interface ISessionStore : IStateStore, IReadOnlySessionStore
11 | {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/Errors/NotEnoughtTimeException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Errors
4 | {
5 | internal class NotEnoughtTimeException : Exception
6 | {
7 | private long ElapsedTime { get; }
8 |
9 | public NotEnoughtTimeException(string message, long elapsedTime)
10 | : base(message)
11 | {
12 | ElapsedTime = elapsedTime;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/core/Processors/Internal/IChangelogReader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Confluent.Kafka;
3 |
4 | namespace Streamiz.Kafka.Net.Processors.Internal
5 | {
6 | internal interface IChangelogReader : IChangelogRegister
7 | {
8 | void Restore();
9 | void Clear();
10 | bool IsEmpty { get; }
11 | IEnumerable CompletedChangelogs { get; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/Processors/Internal/IChangelogRegister.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Confluent.Kafka;
3 |
4 | namespace Streamiz.Kafka.Net.Processors.Internal
5 | {
6 | internal interface IChangelogRegister
7 | {
8 | void Register(TopicPartition topicPartition, ProcessorStateManager processorStateManager);
9 | void Unregister(IEnumerable topicPartitions);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/core/Metrics/Stats/Value.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | internal class Value : IMeasurableStat
4 | {
5 | private double value = 0.0;
6 |
7 | public void Record(MetricConfig config, double value, long timeMs)
8 | {
9 | this.value = value;
10 | }
11 |
12 | public double Measure(MetricConfig config, long now)
13 | => value;
14 | }
15 | }
--------------------------------------------------------------------------------
/core/Processors/ThreadStateListener.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors.Internal;
2 |
3 | namespace Streamiz.Kafka.Net.Processors
4 | {
5 | internal delegate void ThreadStateListener(IThread thread, ThreadStateTransitionValidator old, ThreadStateTransitionValidator @new);
6 |
7 | internal delegate void GlobalThreadStateListener(GlobalStreamThread thread, ThreadStateTransitionValidator old, ThreadStateTransitionValidator @new);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/core/Table/Internal/Change.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Table.Internal
2 | {
3 | internal class Change
4 | {
5 | public T OldValue { get; }
6 | public T NewValue { get; }
7 |
8 | public Change(T old, T @new)
9 | {
10 | OldValue = old;
11 | NewValue = @new;
12 | }
13 |
14 | public override string ToString() => $"OldValue:{OldValue}|NewValue:{NewValue}";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/Mock/Pipes/IPipeInput.cs:
--------------------------------------------------------------------------------
1 | using Confluent.Kafka;
2 | using System;
3 |
4 | namespace Streamiz.Kafka.Net.Mock.Pipes
5 | {
6 | internal delegate void PipeFlushed();
7 |
8 | internal interface IPipeInput : IDisposable
9 | {
10 | string TopicName { get; }
11 | event PipeFlushed Flushed;
12 | void Pipe(byte[] key, byte[] value, DateTime timestamp, Headers headers);
13 | void Flush();
14 |
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/Processors/IKTableProcessorSupplier.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Table.Internal;
2 |
3 | namespace Streamiz.Kafka.Net.Processors
4 | {
5 | internal interface IKTableProcessorSupplier
6 | {
7 | void EnableSendingOldValues();
8 | }
9 |
10 | internal interface IKTableProcessorSupplier : IKTableProcessorSupplier, IProcessorSupplier>
11 | {
12 | IKTableValueGetterSupplier View { get; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/launcher/sample-stream/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.dockerignore
2 | **/.env
3 | **/.git
4 | **/.gitignore
5 | **/.project
6 | **/.settings
7 | **/.toolstarget
8 | **/.vs
9 | **/.vscode
10 | **/.idea
11 | **/*.*proj.user
12 | **/*.dbmdl
13 | **/*.jfm
14 | **/azds.yaml
15 | **/bin
16 | **/charts
17 | **/docker-compose*
18 | **/Dockerfile*
19 | **/node_modules
20 | **/npm-debug.log
21 | **/obj
22 | **/secrets.dev.yaml
23 | **/values.dev.yaml
24 | LICENSE
25 | README.md
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/Nodes/RootNode.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors.Internal;
2 |
3 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph.Nodes
4 | {
5 | internal class RootNode : StreamGraphNode
6 | {
7 | public RootNode() : base("ROOT-NODE")
8 | {
9 | HasWrittenToTopology = true;
10 | }
11 |
12 | public override void WriteToTopology(InternalTopologyBuilder builder)
13 | {
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/launcher/sample-stream-demo/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.dockerignore
2 | **/.env
3 | **/.git
4 | **/.gitignore
5 | **/.project
6 | **/.settings
7 | **/.toolstarget
8 | **/.vs
9 | **/.vscode
10 | **/.idea
11 | **/*.*proj.user
12 | **/*.dbmdl
13 | **/*.jfm
14 | **/azds.yaml
15 | **/bin
16 | **/charts
17 | **/docker-compose*
18 | **/Dockerfile*
19 | **/node_modules
20 | **/npm-debug.log
21 | **/obj
22 | **/secrets.dev.yaml
23 | **/values.dev.yaml
24 | LICENSE
25 | README.md
--------------------------------------------------------------------------------
/core/Processors/ITopicManager.cs:
--------------------------------------------------------------------------------
1 | using Confluent.Kafka;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Threading.Tasks;
5 |
6 | namespace Streamiz.Kafka.Net.Processors
7 | {
8 | internal interface ITopicManager : IDisposable
9 | {
10 | IAdminClient AdminClient { get; }
11 |
12 | Task> ApplyAsync(int topologyId, IDictionary topics, bool allowAutoCreateTopicsIsEnabled);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/Processors/Internal/IGlobalStateMaintainer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Confluent.Kafka;
3 |
4 | namespace Streamiz.Kafka.Net.Processors.Internal
5 | {
6 | internal interface IGlobalStateMaintainer
7 | {
8 | public void Update(ConsumeResult record);
9 |
10 | public void FlushState(bool force = false);
11 |
12 | public void Close();
13 |
14 | public IDictionary Initialize();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/Processors/Internal/StaticTopicNameExtractor.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Processors.Internal
2 | {
3 | internal class StaticTopicNameExtractor : ITopicNameExtractor
4 | {
5 | public string TopicName { get; }
6 |
7 | public StaticTopicNameExtractor(string topicName)
8 | {
9 | TopicName = topicName;
10 | }
11 |
12 | public string Extract(K key, V value, IRecordContext recordContext) => TopicName;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/SerDes/Internal/BytesSerDes.cs:
--------------------------------------------------------------------------------
1 | using Confluent.Kafka;
2 | using Streamiz.Kafka.Net.Crosscutting;
3 |
4 | namespace Streamiz.Kafka.Net.SerDes.Internal
5 | {
6 | internal class BytesSerDes : AbstractSerDes
7 | {
8 | public override Bytes Deserialize(byte[] data, SerializationContext context)
9 | => Bytes.Wrap(data);
10 |
11 | public override byte[] Serialize(Bytes data, SerializationContext context)
12 | => data?.Get;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Processors/KStreamKStreamWindowed/Base/JoinSlidingWindowOptions.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Stream;
2 |
3 | namespace Streamiz.Kafka.Net.Tests.Processors
4 | {
5 | internal class JoinSlidingWindowOptions : JoinWindowOptions
6 | {
7 | public JoinSlidingWindowOptions(long beforeMs, long afterMs, long graceMs, long maintainDurationMs)
8 | : base(beforeMs, afterMs, graceMs, maintainDurationMs)
9 | {
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/core/Metrics/Stats/ImmutableMetricValue.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | internal class ImmutableMetricValue : IGauge
4 | {
5 | private T value;
6 |
7 | public ImmutableMetricValue(T value)
8 | {
9 | this.value = value;
10 | }
11 |
12 | public T Value(MetricConfig config, long now)
13 | => value;
14 |
15 | object IGauge.Value(MetricConfig config, long now)
16 | => Value(config, now);
17 | }
18 | }
--------------------------------------------------------------------------------
/core/State/ITimestampedKeyValueStore.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.State.Internal;
2 |
3 | namespace Streamiz.Kafka.Net.State
4 | {
5 | ///
6 | /// A key-(value/timestamp) store that supports put/get/delete and range queries.
7 | ///
8 | /// key type
9 | /// value type
10 | public interface ITimestampedKeyValueStore : IKeyValueStore>, ITimestampedStore
11 | {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/Metrics/MetricUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace Streamiz.Kafka.Net.Metrics
4 | {
5 | internal class MetricUtils
6 | {
7 | public static void ExportMetrics(
8 | StreamMetricsRegistry registry,
9 | IStreamConfig config,
10 | string threadName)
11 | {
12 | var sensors = registry.GetThreadScopeSensor(threadName);
13 | Task.Factory.StartNew(() => config.MetricsReporter?.Invoke(sensors));
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamJoinWindow.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 |
3 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
4 | {
5 | internal class KStreamJoinWindow : IProcessorSupplier
6 | {
7 | private readonly string storeName;
8 |
9 | public KStreamJoinWindow(string storeName)
10 | {
11 | this.storeName = storeName;
12 | }
13 |
14 | public IProcessor Get() => new KStreamJoinWindowProcessor(storeName);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/Table/Internal/Graph/Nodes/TableProcessorParameters.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using Streamiz.Kafka.Net.Stream.Internal.Graph.Nodes;
3 |
4 | namespace Streamiz.Kafka.Net.Table.Internal.Graph.Nodes
5 | {
6 | internal class TableProcessorParameters : ProcessorParameters>
7 | {
8 | public TableProcessorParameters(IProcessorSupplier> processorSupplier, string processorName)
9 | : base(processorSupplier, processorName)
10 | {
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/Processors/IKStreamAggProcessorSupplier.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Table.Internal;
2 |
3 | namespace Streamiz.Kafka.Net.Processors
4 | {
5 | internal interface IKStreamAggProcessorSupplier
6 | {
7 | IKTableValueGetterSupplier View();
8 | void EnableSendingOldValues();
9 | }
10 |
11 | internal interface IKStreamAggProcessorSupplier :
12 | IProcessorSupplier, IKStreamAggProcessorSupplier
13 | {
14 | new void EnableSendingOldValues();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/Crosscutting/WatermarkOffsetsByTopicPartition.cs:
--------------------------------------------------------------------------------
1 | using Confluent.Kafka;
2 |
3 | namespace Streamiz.Kafka.Net.Crosscutting
4 | {
5 | internal class WatermarkOffsetsByTopicPartition : WatermarkOffsets
6 | {
7 | public string Topic { get; }
8 | public int Partition { get; }
9 |
10 | public WatermarkOffsetsByTopicPartition(string topic, int partition, Offset low, Offset high)
11 | : base(low, high)
12 | {
13 | Topic = topic;
14 | Partition = partition;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/Metrics/Stats/ProviderMetricValue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Metrics.Stats
4 | {
5 | internal class ProviderMetricValue : IGauge
6 | {
7 | private readonly Func provider;
8 |
9 | public ProviderMetricValue(Func provider)
10 | {
11 | this.provider = provider;
12 | }
13 |
14 | public T Value(MetricConfig config, long now)
15 | => provider();
16 |
17 | object IGauge.Value(MetricConfig config, long now)
18 | => Value(config, now);
19 | }
20 | }
--------------------------------------------------------------------------------
/core/Table/Internal/GlobalKTable.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Table.Internal
2 | {
3 | internal class GlobalKTable : IGlobalKTable
4 | {
5 | public GlobalKTable(IKTableValueGetterSupplier valueGetterSupplier, string queryableStoreName)
6 | {
7 | ValueGetterSupplier = valueGetterSupplier;
8 | QueryableStoreName = queryableStoreName;
9 | }
10 |
11 | public IKTableValueGetterSupplier ValueGetterSupplier { get; }
12 |
13 | public string QueryableStoreName { get; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/remote/Streamiz.Kafka.Net.Azure.RemoteStorage/Internal/AzureTableEntity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Azure;
3 | using Azure.Data.Tables;
4 |
5 | namespace Streamiz.Kafka.Net.Azure.RemoteStorage.Internal
6 | {
7 | internal class AzureTableEntity : ITableEntity
8 | {
9 | public string PartitionKey { get; set; }
10 | public string RowKey { get; set; }
11 | public DateTimeOffset? Timestamp { get; set; }
12 | public ETag ETag { get; set; }
13 | public byte[] Value { get; set; }
14 | public byte[] Key { get; set; }
15 | }
16 | }
--------------------------------------------------------------------------------
/core/State/Cache/ICacheFunction.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Crosscutting;
2 |
3 | namespace Streamiz.Kafka.Net.State.Cache
4 | {
5 | internal interface ICacheFunction
6 | {
7 | byte[] BytesFromCacheKey(Bytes cacheKey);
8 | Bytes Key(Bytes cacheKey);
9 | Bytes CacheKey(Bytes cacheKey);
10 | Bytes CacheKey(Bytes key, long segmentId);
11 | long SegmentId(Bytes key);
12 | long SegmentId(long timestamp);
13 | long SegmentInterval { get; }
14 | int CompareSegmentedKeys(Bytes cacheKey, Bytes storeKey);
15 | }
16 | }
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Public/TopologyBuilderTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using Streamiz.Kafka.Net.Errors;
3 |
4 | namespace Streamiz.Kafka.Net.Tests.Public
5 | {
6 | public class TopologyBuilderTests
7 | {
8 | [Test]
9 | public void SourceTopicAlreadyAdded()
10 | {
11 | var builder = new StreamBuilder();
12 | builder.Stream("table");
13 | builder.Stream("table");
14 | Assert.Throws(() => builder.Build());
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/Processors/IAsyncProcessor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using Confluent.Kafka;
4 | using Streamiz.Kafka.Net.Stream;
5 |
6 | namespace Streamiz.Kafka.Net.Processors
7 | {
8 | internal interface IAsyncProcessor
9 | {
10 | public RetryPolicy Policy { get; }
11 | }
12 |
13 | internal interface IAsyncProcessor : IAsyncProcessor
14 | {
15 | public Task>> ProcessAsync(K key, V value, Headers headers, long timestamp, ExternalContext context);
16 | }
17 | }
--------------------------------------------------------------------------------
/core/Processors/IThread.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 |
5 | namespace Streamiz.Kafka.Net.Processors
6 | {
7 | interface IThread : IDisposable
8 | {
9 | int Id { get; }
10 | ThreadState State { get; }
11 | bool IsDisposable { get; }
12 | string Name { get; }
13 | bool IsRunning { get; }
14 | void Run();
15 | void Start(CancellationToken token);
16 | IEnumerable ActiveTasks { get; }
17 | event ThreadStateListener StateChanged;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/log4net.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/core/Crosscutting/ICloneable.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Crosscutting
2 | {
3 | ///
4 | /// Supports cloning, which creates a new instance of a class with the same value as an existing instance.
5 | ///
6 | /// Type of clone object
7 | public interface ICloneable
8 | {
9 | ///
10 | /// Clone current object to an another instance of T.
11 | ///
12 | /// Return an instance
13 | T Clone();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/core/Errors/StreamConfigException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Errors
4 | {
5 | ///
6 | /// Signals that the configuration in your stream is incorrect or maybe a property is missing
7 | ///
8 | public class StreamConfigException : Exception
9 | {
10 | ///
11 | /// Constructor with exception message
12 | ///
13 | /// Message
14 | public StreamConfigException(string message)
15 | : base(message)
16 | {
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/core/Processors/Internal/WrapperTopicNameExtractor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Processors.Internal
4 | {
5 | internal class WrapperTopicNameExtractor : ITopicNameExtractor
6 | {
7 | private readonly Func inner;
8 |
9 | public WrapperTopicNameExtractor(Func inner)
10 | {
11 | this.inner = inner;
12 | }
13 |
14 | public string Extract(K key, V value, IRecordContext recordContext)
15 | => inner.Invoke(key, value, recordContext);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamMap.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using System.Collections.Generic;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamMap : IProcessorSupplier
7 | {
8 | public IKeyValueMapper> Mapper { get; }
9 |
10 | public KStreamMap(IKeyValueMapper> mapper)
11 | {
12 | this.Mapper = mapper;
13 | }
14 |
15 | public IProcessor Get() => new KStreamMapProcessor(this.Mapper);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Stores/CachingInMemoryWindowStoreTests.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Crosscutting;
2 | using Streamiz.Kafka.Net.State;
3 | using Streamiz.Kafka.Net.State.InMemory;
4 |
5 | namespace Streamiz.Kafka.Net.Tests.Stores;
6 |
7 | public class CachingInMemoryWindowStoreTests
8 | : AbstractPersistentWindowStoreTests
9 | {
10 | protected override IWindowStore GetBackWindowStore()
11 | {
12 | return new InMemoryWindowStore(
13 | "test-w-store",
14 | RETENTION_MS,
15 | WINDOW_SIZE,
16 | false
17 | );
18 | }
19 | }
--------------------------------------------------------------------------------
/environment/confs/otel-collector-config.yaml:
--------------------------------------------------------------------------------
1 | receivers:
2 | otlp:
3 | protocols:
4 | grpc:
5 | endpoint: 0.0.0.0:4317
6 |
7 | exporters:
8 | debug:
9 | prometheus:
10 | endpoint: "0.0.0.0:8889"
11 | const_labels:
12 | label1: value1
13 |
14 | processors:
15 | batch:
16 |
17 | extensions:
18 | health_check:
19 | pprof:
20 | endpoint: :1888
21 | zpages:
22 | endpoint: :55679
23 |
24 | service:
25 | extensions: [pprof, zpages, health_check]
26 | pipelines:
27 | metrics:
28 | receivers: [otlp]
29 | processors: [batch]
30 | exporters: [debug, prometheus]
--------------------------------------------------------------------------------
/core/Errors/NoneRetryableException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Errors
4 | {
5 | internal class NoneRetryableException : Exception
6 | {
7 | private int NumberRetry { get; }
8 | private long ElapsedTime { get; }
9 |
10 | public NoneRetryableException(
11 | string message,
12 | int numberRetry,
13 | long ellapsedTime,
14 | Exception innerException)
15 | : base(message, innerException)
16 | {
17 | NumberRetry = numberRetry;
18 | ElapsedTime = ellapsedTime;
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/core/Processors/Internal/DefaultRecordTimestampExtractor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Processors.Internal
4 | {
5 | internal class DefaultRecordTimestampExtractor : IRecordTimestampExtractor
6 | {
7 | private readonly Func timestampExtractor;
8 |
9 | public DefaultRecordTimestampExtractor()
10 | {
11 | this.timestampExtractor = (k, v, ctx) => ctx.Timestamp;
12 | }
13 |
14 | public long Extract(K key, V value, IRecordContext recordContext) => timestampExtractor(key, value, recordContext);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/Table/Internal/GenericKTableValueGetterSupplier.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Table.Internal
2 | {
3 | internal class GenericKTableValueGetterSupplier : IKTableValueGetterSupplier
4 | {
5 | private readonly IKTableValueGetter getter;
6 |
7 | public GenericKTableValueGetterSupplier(string[] storeName, IKTableValueGetter getter)
8 | {
9 | this.StoreNames = storeName;
10 | this.getter = getter;
11 | }
12 |
13 | public string[] StoreNames { get; }
14 |
15 | public IKTableValueGetter Get() => getter;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/Metrics/MetricsRecordingLevel.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics
2 | {
3 | ///
4 | /// MetricsRecordingLevel enum
5 | ///
6 | /// - INFO = list high level metrics (client, thread, task)
7 | /// - DEBUG = list all metrics (client, thread, task, processor, state-store)
8 | ///
9 | ///
10 | public enum MetricsRecordingLevel
11 | {
12 | ///
13 | /// Info level metrics
14 | ///
15 | INFO,
16 | ///
17 | /// Debug level metrics
18 | ///
19 | DEBUG
20 | }
21 | }
--------------------------------------------------------------------------------
/core/Processors/Internal/StateRestoreCallback.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Crosscutting;
2 |
3 | namespace Streamiz.Kafka.Net.Processors.Internal
4 | {
5 | ///
6 | /// Restoration logic for log-backed state stores upon restart, it takes one record at a time from the logs to apply to the restoring state.
7 | ///
8 | /// Record's key
9 | /// Record's value
10 | /// /// Record's timestamp in Unix milliseconds long format
11 | public delegate void StateRestoreCallback(Bytes key, byte[] value, long timestamp);
12 | }
13 |
--------------------------------------------------------------------------------
/core/State/RocksDb/Internal/RocksDbSegmentedBytesStore.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.State.Internal
2 | {
3 | internal class RocksDbSegmentedBytesStore :
4 | AbstractRocksDBSegmentedBytesStore
5 | {
6 | public RocksDbSegmentedBytesStore(
7 | string name,
8 | string metricScope,
9 | long retention,
10 | long segmentInterval, IKeySchema keySchema)
11 | : base(name,
12 | keySchema,
13 | new RocksDbKeyValueSegments(name, retention, segmentInterval, metricScope))
14 | {
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/launcher/sample-stream-demo/sample-stream-demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | sample_stream_demo
7 | Linux
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/core/Errors/NotMoreValueException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 |
4 | namespace Streamiz.Kafka.Net.Errors
5 | {
6 | ///
7 | /// Exception throws on a empty rocksdb enumerator when is called.
8 | ///
9 | public class NotMoreValueException : Exception
10 | {
11 | ///
12 | /// Constructor with error message
13 | ///
14 | /// Exception message
15 | public NotMoreValueException(string message)
16 | : base(message)
17 | {
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/core/Metrics/Stats/CumulativeSum.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Metrics.Stats
2 | {
3 | internal class CumulativeSum : IMeasurableStat
4 | {
5 | private double total;
6 |
7 | public CumulativeSum() : this(0.0)
8 | { }
9 |
10 | public CumulativeSum(double total)
11 | {
12 | this.total = total;
13 | }
14 |
15 | public virtual void Record(MetricConfig config, double value, long timeMs)
16 | {
17 | total += value;
18 | }
19 |
20 | public double Measure(MetricConfig config, long now)
21 | => total;
22 | }
23 | }
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamFlatMapValues.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using System.Collections.Generic;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamFlatMapValues : IProcessorSupplier
7 | {
8 | private IValueMapperWithKey> Mapper { get; }
9 |
10 | public KStreamFlatMapValues(IValueMapperWithKey> mapper)
11 | {
12 | this.Mapper = mapper;
13 | }
14 |
15 | public IProcessor Get() => new KStreamFlatMapValuesProcessor(this.Mapper);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Private/ConcurrentSortedDictionaryTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using Streamiz.Kafka.Net.Crosscutting;
3 | using Streamiz.Kafka.Net.State.Cache.Internal;
4 |
5 | namespace Streamiz.Kafka.Net.Tests.Private;
6 |
7 | // TODO :
8 | public class ConcurrentSortedDictionaryTests
9 | {
10 | private ConcurrentSortedDictionary concurrentSet;
11 |
12 | [SetUp]
13 | public void Init()
14 | {
15 | concurrentSet = new ConcurrentSortedDictionary();
16 | }
17 |
18 | [TearDown]
19 | public void Dispose()
20 | {
21 | concurrentSet.Clear();
22 | }
23 | }
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamFlatMap.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using System.Collections.Generic;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamFlatMap : IProcessorSupplier
7 | {
8 | public IKeyValueMapper>> Mapper { get; }
9 |
10 | public KStreamFlatMap(IKeyValueMapper>> mapper)
11 | {
12 | this.Mapper = mapper;
13 | }
14 |
15 | public IProcessor Get() => new KStreamFlatMapProcessor(this.Mapper);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/Errors/StreamProducerException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Confluent.Kafka;
3 |
4 | namespace Streamiz.Kafka.Net.Errors
5 | {
6 | internal class StreamProducerException : Exception
7 | {
8 | public ProduceException OriginalProduceException { get; set; }
9 | public ProductionExceptionHandlerResponse Response { get; set; }
10 |
11 | public StreamProducerException(ProduceException originalProduceException, ProductionExceptionHandlerResponse response)
12 | {
13 | OriginalProduceException = originalProduceException;
14 | Response = response;
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/core/Processors/Internal/WrapperRecordTimestampExtractor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Processors.Internal
4 | {
5 | internal class WrapperRecordTimestampExtractor : IRecordTimestampExtractor
6 | {
7 | private readonly Func timestampExtractor;
8 |
9 | public WrapperRecordTimestampExtractor(Func timestampExtractor)
10 | {
11 | this.timestampExtractor = timestampExtractor;
12 | }
13 |
14 | public long Extract(K key, V value, IRecordContext recordContext) => timestampExtractor(key, value ,recordContext);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/SerDes/SerDesContext.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.SerDes
2 | {
3 | ///
4 | /// is using for configure instance.
5 | /// It is notably used SchemaAvroSerDes to configure ISchemaRegistryClient with url, auto registry schema, etc ..
6 | ///
7 | public class SerDesContext
8 | {
9 | ///
10 | /// Stream application configuration instance
11 | ///
12 | public IStreamConfig Config { get; }
13 |
14 | internal SerDesContext(IStreamConfig config)
15 | {
16 | Config = config;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/core/State/Enumerator/EnumeratorExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Streamiz.Kafka.Net.State.Enumerator
5 | {
6 | internal static class EnumeratorExtensions
7 | {
8 | public static IKeyValueEnumerator ToWrap(this IEnumerable> enumerable)
9 | => new WrapEnumerableKeyValueEnumerator(enumerable);
10 |
11 | public static IKeyValueEnumerator Transform(this IKeyValueEnumerator enumerator, Func> function)
12 | => new TransformKeyValueEnumerator(enumerator, function);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamFilter.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using System;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamFilter : IProcessorSupplier
7 | {
8 | public Func Predicate { get; }
9 | public bool Not { get; }
10 |
11 |
12 | public KStreamFilter(Func predicate, bool not = false)
13 | {
14 | Predicate = predicate;
15 | Not = not;
16 | }
17 |
18 | public IProcessor Get() => new KStreamFilterProcessor(this.Predicate, this.Not);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamTimestampExtractor.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using System;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamTimestampExtractor : IProcessorSupplier
7 | {
8 | private readonly Func timestampExtractor;
9 |
10 | public KStreamTimestampExtractor(Func timestampExtractor)
11 | {
12 | this.timestampExtractor = timestampExtractor;
13 | }
14 |
15 | public IProcessor Get() => new KStreamTimestampProcessor(timestampExtractor);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/State/Enumerator/IWindowStoreEnumerator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Streamiz.Kafka.Net.State.Enumerator
5 | {
6 | ///
7 | /// Iterator interface of with key typed long used for .
8 | /// Users must call its Dispose() method explicitly upon completeness to release resources,
9 | /// or use "using" keyword.
10 | ///
11 | /// Type of values
12 | public interface IWindowStoreEnumerator : IKeyValueEnumerator
13 | {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamProcessorSupplier.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using Streamiz.Kafka.Net.Processors.Public;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamProcessorSupplier : IProcessorSupplier
7 | {
8 | private readonly ProcessorSupplier processorSupplier;
9 |
10 | public KStreamProcessorSupplier(ProcessorSupplier processorSupplier)
11 | {
12 | this.processorSupplier = processorSupplier;
13 | }
14 |
15 | public Processors.IProcessor Get()
16 | => new KStreamProcessor(processorSupplier);
17 | }
18 | }
--------------------------------------------------------------------------------
/core/Metrics/Internal/NoRunnableSensor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Streamiz.Kafka.Net.Metrics.Stats;
3 |
4 | namespace Streamiz.Kafka.Net.Metrics.Internal
5 | {
6 | ///
7 | /// No runnable sensor for test
8 | ///
9 | internal class NoRunnableSensor : Sensor
10 | {
11 | internal NoRunnableSensor(string name, string description, MetricsRecordingLevel metricsRecording)
12 | : base(name, description, metricsRecording)
13 | {
14 | NoRunnable = true;
15 | }
16 |
17 | internal static NoRunnableSensor Empty =>
18 | new NoRunnableSensor("unknown", "unknown", MetricsRecordingLevel.INFO);
19 | }
20 | }
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Private/TestLogger.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Logging;
2 | using NUnit.Framework;
3 |
4 | namespace Streamiz.Kafka.Net.Tests.Private
5 | {
6 | public class TestLogger
7 | {
8 | [Test]
9 | public void test()
10 | {
11 | var loggerFactory = LoggerFactory.Create(builder =>
12 | {
13 | builder.SetMinimumLevel(LogLevel.Debug);
14 | builder.AddConsole();
15 | });
16 |
17 | var logger = loggerFactory.CreateLogger();
18 | logger.LogInformation("Coucou test");
19 | logger.LogDebug("Debug Coucou test");
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/core/Processors/Internal/ObjectDeserialized.cs:
--------------------------------------------------------------------------------
1 | namespace Streamiz.Kafka.Net.Processors.Internal
2 | {
3 | internal class ObjectDeserialized
4 | {
5 | public object Bean { get; private set; }
6 | public bool MustBeSkipped { get; private set; }
7 |
8 | public static ObjectDeserialized ObjectSkipped => new ObjectDeserialized(true);
9 |
10 | public ObjectDeserialized(object bean, bool mustBeSkipped)
11 | {
12 | Bean = bean;
13 | MustBeSkipped = mustBeSkipped;
14 | }
15 |
16 | private ObjectDeserialized(bool mustBeSkipped)
17 | {
18 | MustBeSkipped = mustBeSkipped;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamPeek.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using System;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamPeek : IProcessorSupplier
7 | {
8 | public bool ForwardDownStream { get; }
9 | public Action Action { get; }
10 |
11 | public KStreamPeek(Action action, bool forwardDownStream)
12 | {
13 | this.Action = action;
14 | this.ForwardDownStream = forwardDownStream;
15 | }
16 |
17 | public IProcessor Get() => new KStreamPeekProcessor(this.Action, this.ForwardDownStream);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/core/Table/Internal/Graph/Nodes/GroupedTableRepartitionNode.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.SerDes;
2 | using Streamiz.Kafka.Net.SerDes.Internal;
3 | using Streamiz.Kafka.Net.Stream.Internal.Graph.Nodes;
4 |
5 | namespace Streamiz.Kafka.Net.Table.Internal.Graph.Nodes
6 | {
7 | internal class GroupedTableRepartitionNode : RepartitionNode>
8 | {
9 | public GroupedTableRepartitionNode(string streamGraphNode, string sourceName, ISerDes keySerdes, ISerDes valueSerdes, string sinkName, string repartitionTopic)
10 | : base(streamGraphNode, sourceName, null, keySerdes, new ChangeSerDes(valueSerdes), sinkName, repartitionTopic)
11 | {
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/launcher/sample-stream-demo/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base
2 | WORKDIR /app
3 |
4 | FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
5 | WORKDIR /src
6 | COPY ["samples/sample-stream-demo/sample-stream-demo.csproj", "sample-stream-demo/"]
7 | RUN dotnet restore "samples/sample-stream-demo/sample-stream-demo.csproj"
8 | COPY . .
9 | WORKDIR "/src/sample-stream-demo"
10 | RUN dotnet build "sample-stream-demo.csproj" -c Release -o /app/build
11 |
12 | FROM build AS publish
13 | RUN dotnet publish "sample-stream-demo.csproj" -c Release -o /app/publish
14 |
15 | FROM base AS final
16 | WORKDIR /app
17 | COPY --from=publish /app/publish .
18 | ENTRYPOINT ["dotnet", "sample-stream-demo.dll"]
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE:
--------------------------------------------------------------------------------
1 | Description
2 | ===========
3 |
4 |
5 |
6 |
7 | How to reproduce
8 | ================
9 |
10 |
11 |
12 |
13 | Checklist
14 | =========
15 |
16 | Please provide the following information:
17 | - [ ] A complete (i.e. we can run it), minimal program demonstrating the problem. No need to supply a project file.
18 | - [ ] A code snippet with your topology builder (ex: builder.Stream("topic").to("an-another-topic");)
19 | - [ ] Streamiz.Kafka.Net nuget version.
20 | - [ ] Apache Kafka version.
21 | - [ ] Client configuration.
22 | - [ ] Operating system.
23 | - [ ] Provide logs (with in debug mode (log4net and StreamConfig.Debug) as necessary in configuration).
24 | - [ ] Critical issue.
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamBranch.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using System;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamBranch : IProcessorSupplier
7 | {
8 | public Func[] Predicates { get; }
9 | public String[] ChildNodes { get; }
10 |
11 | public KStreamBranch(Func[] predicates,
12 | String[] childNodes)
13 | {
14 | this.Predicates = predicates;
15 | this.ChildNodes = childNodes;
16 | }
17 |
18 | public IProcessor Get() => new KStreamBranchProcessor(this.Predicates, this.ChildNodes);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/core/Metrics/Stats/WindowedSum.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Streamiz.Kafka.Net.Metrics.Stats
4 | {
5 | internal class WindowedSum : SampledStat
6 | {
7 | public WindowedSum()
8 | : base(0.0)
9 | {
10 | }
11 |
12 | protected override void Update(Sample sample, MetricConfig config, double value, long timeMs)
13 | {
14 | sample.Value += value;
15 | }
16 |
17 | protected override double Combine(List samples, MetricConfig config, long now)
18 | {
19 | double total = 0.0;
20 | foreach (var sample in samples)
21 | total += sample.Value;
22 | return total;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/core/Kafka/IRecordCollector.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Confluent.Kafka;
3 | using Streamiz.Kafka.Net.SerDes;
4 |
5 | namespace Streamiz.Kafka.Net.Kafka
6 | {
7 | internal interface IRecordCollector
8 | {
9 | IDictionary CollectorOffsets { get; }
10 | void Initialize();
11 | void Flush();
12 | void Close(bool dirty);
13 | void Send(string topic, K key, V value, Headers headers, long timestamp, ISerDes keySerializer, ISerDes valueSerializer);
14 | void Send(string topic, K key, V value, Headers headers, int partition, long timestamp, ISerDes keySerializer, ISerDes valueSerializer);
15 | int PartitionsFor(string topic);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/core/Stream/Internal/Graph/KStreamMapValues.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Processors;
2 | using System.Collections.Generic;
3 |
4 | namespace Streamiz.Kafka.Net.Stream.Internal.Graph
5 | {
6 | internal class KStreamMapValues : IProcessorSupplier
7 | {
8 | private readonly IValueMapperWithKey mapper;
9 |
10 | public KStreamMapValues(IValueMapperWithKey mapper)
11 | {
12 | this.mapper = mapper;
13 | }
14 |
15 | public IProcessor Get() => new KStreamMapProcessor(
16 | new WrappedKeyValueMapper>(
17 | (key, value, c) => new KeyValuePair(key, mapper.Apply(key, value, c))));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/launcher/sample-stream/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:6.0-alpine AS base
2 | WORKDIR /app
3 |
4 | FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build
5 | WORKDIR /src
6 | COPY ["sample-stream.csproj", "sample-stream/"]
7 | RUN dotnet restore "sample-stream/sample-stream.csproj"
8 | COPY . .
9 | COPY ["Program.cs", "sample-stream/"]
10 | COPY ["log4net.config", "sample-stream/"]
11 | WORKDIR "/src/sample-stream"
12 | RUN dotnet build "sample-stream.csproj" -c Release -o /app/build
13 |
14 | FROM build AS publish
15 | RUN dotnet publish "sample-stream.csproj" -c Release -o /app/publish
16 |
17 | FROM base AS final
18 | WORKDIR /app
19 | COPY --from=publish /app/publish .
20 | RUN mkdir /app/store
21 | ENTRYPOINT ["dotnet", "sample-stream.dll"]
22 |
--------------------------------------------------------------------------------
/core/State/Supplier/IKeyValueBytesStoreSupplier.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Crosscutting;
2 |
3 | namespace Streamiz.Kafka.Net.State.Supplier
4 | {
5 | ///
6 | /// A store supplier that can be used to create one or more instances of type <Bytes, byte[]>.
7 | /// For any stores implementing the IKeyValueStore<Byte, byte[]> interface, null value bytes are considered as "not exist". This means:
8 | /// 1. Null value bytes in put operations should be treated as delete.
9 | /// 2. If the key does not exist, get operations should return null value bytes.
10 | ///
11 | public interface IKeyValueBytesStoreSupplier : IStoreSupplier>
12 | {
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/Processors/Internal/GlobalProcessorContext.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using Streamiz.Kafka.Net.Metrics;
3 |
4 | namespace Streamiz.Kafka.Net.Processors.Internal
5 | {
6 | internal class GlobalProcessorContext : ProcessorContext
7 | {
8 | internal GlobalProcessorContext(
9 | IStreamConfig configuration,
10 | IStateManager stateManager,
11 | StreamMetricsRegistry streamMetricsRegistry)
12 | : base(null, configuration, stateManager, streamMetricsRegistry)
13 | {
14 | }
15 |
16 | public override TaskId Id => new TaskId { Id = -1, Partition = -1 };
17 |
18 | public override string StateDir => $"{Path.Combine(Configuration.StateDir, Configuration.ApplicationId, "global")}";
19 | }
20 | }
--------------------------------------------------------------------------------
/core/Errors/TopologyException.cs:
--------------------------------------------------------------------------------
1 | using Streamiz.Kafka.Net.Stream;
2 | using Streamiz.Kafka.Net.Stream.Internal;
3 | using System;
4 |
5 | namespace Streamiz.Kafka.Net.Errors
6 | {
7 | ///
8 | /// Indicates a pre run time error occurred while parsing the logical topology
9 | /// to construct the physical processor topology.
10 | ///
11 | public class TopologyException : Exception
12 | {
13 | ///
14 | /// Constructor with exception message
15 | ///
16 | /// Exception message
17 | public TopologyException(string message)
18 | : base(message)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/core/Processors/Public/WrappedProcessor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Streamiz.Kafka.Net.Processors.Public
4 | {
5 | internal class WrappedProcessor : IProcessor, ICloneableProcessor
6 | {
7 | private readonly Action> intern;
8 |
9 | public WrappedProcessor(Action> intern)
10 | {
11 | this.intern = intern;
12 | }
13 |
14 | public void Init(ProcessorContext context)
15 | { }
16 |
17 | public void Process(Record record)
18 | => intern.Invoke(record);
19 |
20 | public void Close()
21 | { }
22 |
23 | public object Clone()
24 | {
25 | return new WrappedProcessor(intern);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/test/Streamiz.Kafka.Net.Tests/Helpers/SerdesThrowException.cs:
--------------------------------------------------------------------------------
1 | using Confluent.Kafka;
2 | using Streamiz.Kafka.Net.SerDes;
3 | using System;
4 | using System.Text;
5 |
6 | namespace Streamiz.Kafka.Net.Tests.Helpers
7 | {
8 | internal class SerdesThrowException : AbstractSerDes
9 | {
10 | public override string Deserialize(byte[] data, SerializationContext context)
11 | {
12 | if (data.Length % 2 == 0)
13 | throw new NotImplementedException();
14 | else
15 | return Encoding.UTF8.GetString(data);
16 | }
17 |
18 | public override byte[] Serialize(string data, SerializationContext context)
19 | {
20 | return Encoding.UTF8.GetBytes(data);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/Mock/Pipes/IPipeOutput.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Confluent.Kafka;
4 |
5 | namespace Streamiz.Kafka.Net.Mock.Pipes
6 | {
7 | internal class PipeOutputInfo
8 | {
9 | public string Topic { get; set; }
10 | public int Partition { get; set; }
11 | public long Offset { get; set; }
12 | public long Low { get; set; }
13 | public long High { get; set; }
14 | }
15 |
16 | internal interface IPipeOutput : IDisposable
17 | {
18 | string TopicName { get; }
19 | ConsumeResult Read();
20 | IEnumerable> ReadList();
21 | List GetInfos();
22 | int Size { get; }
23 | bool IsEmpty { get; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/core/Processors/Internal/ExtractRecordMetadataTimestamp.cs:
--------------------------------------------------------------------------------
1 | using Confluent.Kafka;
2 |
3 | namespace Streamiz.Kafka.Net.Processors.Internal
4 | {
5 | internal abstract class ExtractRecordMetadataTimestamp : ITimestampExtractor
6 | {
7 | public long Extract(ConsumeResult