├── logo.png
├── .gitignore
├── da-streamingledger-runtime-serial
├── src
│ └── main
│ │ ├── resources
│ │ └── META-INF
│ │ │ └── services
│ │ │ └── com.dataartisans.streamingledger.sdk.spi.StreamingLedgerRuntimeProvider
│ │ └── java
│ │ └── com
│ │ └── dataartisans
│ │ └── streamingledger
│ │ └── runtime
│ │ └── serial
│ │ ├── SideOutputContext.java
│ │ ├── SerialStateAccess.java
│ │ ├── SerialStreamingLedgerRuntimeProvider.java
│ │ ├── SerialTransactor.java
│ │ └── SingleStreamSerialTransactor.java
└── pom.xml
├── da-streamingledger-examples
├── src
│ └── main
│ │ ├── resources
│ │ └── log4j.properties
│ │ └── java
│ │ └── com
│ │ └── dataartisans
│ │ └── streamingledger
│ │ └── examples
│ │ └── simpletrade
│ │ ├── generator
│ │ ├── Throttler.java
│ │ ├── SyntheticSources.java
│ │ └── DepositsThenTransactionsSource.java
│ │ ├── DepositEvent.java
│ │ ├── TransactionResult.java
│ │ ├── TransactionEvent.java
│ │ └── SimpleTradeExample.java
└── pom.xml
├── da-streamingledger-sdk
├── src
│ ├── main
│ │ └── java
│ │ │ └── com
│ │ │ └── dataartisans
│ │ │ └── streamingledger
│ │ │ └── sdk
│ │ │ ├── api
│ │ │ ├── package-info.java
│ │ │ ├── StateNotReadableException.java
│ │ │ ├── StateNotWritableException.java
│ │ │ ├── StateAccessException.java
│ │ │ ├── AccessType.java
│ │ │ ├── TransactionProcessFunction.java
│ │ │ └── StateAccess.java
│ │ │ ├── common
│ │ │ ├── reflection
│ │ │ │ ├── ProcessFunctionInvoker.java
│ │ │ │ ├── Methods.java
│ │ │ │ └── ByteBuddyProcessFunctionInvoker.java
│ │ │ └── union
│ │ │ │ ├── UnionSerializerConfigSnapshot.java
│ │ │ │ ├── TaggedElement.java
│ │ │ │ ├── UnionTypeInfo.java
│ │ │ │ ├── Union.java
│ │ │ │ └── UnionSerializer.java
│ │ │ └── spi
│ │ │ ├── StreamingLedgerRuntimeProvider.java
│ │ │ ├── InputAndSpec.java
│ │ │ ├── StreamingLedgerSpec.java
│ │ │ ├── StreamingLedgerRuntimeLoader.java
│ │ │ └── StreamingLedgerSpecFactory.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── dataartisans
│ │ └── streamingledger
│ │ └── sdk
│ │ ├── common
│ │ ├── union
│ │ │ └── UnionSerializerTest.java
│ │ └── reflection
│ │ │ └── ByteBuddyProcessFunctionInvokerTest.java
│ │ └── api
│ │ └── StreamingLedgerSpecTest.java
└── pom.xml
├── tools
├── maven
│ ├── checkstyle-suppressions.xml
│ ├── spotbugs-exclude.xml
│ └── checkstyle.xml
└── intellij
│ ├── codestyle-java.xml
│ └── inspections.xml
├── README.md
├── LICENSE
└── pom.xml
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dataArtisans/da-streamingledger/HEAD/logo.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | .DS_Store
26 | *.iml
27 | .idea
28 |
29 | # maven shade plugin
30 | dependency-reduced-pom.xml
31 | target
32 |
--------------------------------------------------------------------------------
/da-streamingledger-runtime-serial/src/main/resources/META-INF/services/com.dataartisans.streamingledger.sdk.spi.StreamingLedgerRuntimeProvider:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2018 Data Artisans GmbH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | com.dataartisans.streamingledger.runtime.serial.SerialStreamingLedgerRuntimeProvider
18 |
--------------------------------------------------------------------------------
/da-streamingledger-examples/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2018 Data Artisans GmbH
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | log4j.rootLogger=INFO, console
17 | log4j.appender.console=org.apache.log4j.ConsoleAppender
18 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
19 | log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p %-60c %x - %m%n
20 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/api/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * The API package for the dA-StreamingLedger support
19 | * for Apache Flink.
20 | */
21 |
22 | package com.dataartisans.streamingledger.sdk.api;
23 |
--------------------------------------------------------------------------------
/tools/maven/checkstyle-suppressions.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/api/StateNotReadableException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.api;
18 |
19 | /**
20 | * An exception that indicates that state was accessed for read, without being
21 | * declared as readable.
22 | */
23 | public class StateNotReadableException extends StateAccessException {
24 |
25 | private static final long serialVersionUID = 1L;
26 |
27 | public StateNotReadableException(StateAccess> state) {
28 | super(String.format("State access %s for state %s has not declared read access.",
29 | state.getStateAccessName(), state.getStateName()));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/api/StateNotWritableException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.api;
18 |
19 | /**
20 | * An exception that indicates that state was accessed for write, without being
21 | * declared as writable.
22 | */
23 | public class StateNotWritableException extends StateAccessException {
24 |
25 | private static final long serialVersionUID = 1L;
26 |
27 | public StateNotWritableException(StateAccess> state) {
28 | super(String.format("State access %s for state %s has not declared write access.",
29 | state.getStateAccessName(), state.getStateName()));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/common/reflection/ProcessFunctionInvoker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.common.reflection;
18 |
19 | import com.dataartisans.streamingledger.sdk.api.StateAccess;
20 | import com.dataartisans.streamingledger.sdk.api.TransactionProcessFunction;
21 | import com.dataartisans.streamingledger.sdk.api.TransactionProcessFunction.Context;
22 |
23 | /**
24 | * An auto-generated class that invokes a user provided {@link TransactionProcessFunction}.
25 | *
26 | * @param transaction event type.
27 | * @param transaction result type.
28 | */
29 | public abstract class ProcessFunctionInvoker {
30 |
31 | public abstract void invoke(InT input, Context context, StateAccess[] arguments);
32 | }
33 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/spi/StreamingLedgerRuntimeProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.spi;
18 |
19 | import com.dataartisans.streamingledger.sdk.api.StreamingLedger.ResultStreams;
20 |
21 | import java.util.List;
22 |
23 | /**
24 | * The stream ledger runtime provider is responsible for taking a stream ledger
25 | * program and creating the Flink streaming graph that should execute it.
26 | *
27 | *
The exact way of executing the distributed transactions is implementation specific.
28 | * Some runtime providers instantiate a serial (trivially correct) execution model, some
29 | * a sophisticated parallel data flow.
30 | */
31 | public interface StreamingLedgerRuntimeProvider {
32 |
33 | ResultStreams translate(String name, List> streamLedgerSpecs);
34 | }
35 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/api/StateAccessException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.api;
18 |
19 | /**
20 | * Base exception for failures during a state access.
21 | *
22 | *
This is an unchecked exception, because instances of this exception are raised as a result
23 | * of an incorrect program, for example when read and write accesses are incorrectly declared.
24 | * Instances of this exception are hence rarely expected to be handled explicitly within an user's
25 | * implementation of an application, but rather expected to "bubble up" and report a proper
26 | * application failure.
27 | */
28 | public class StateAccessException extends RuntimeException {
29 |
30 | private static final long serialVersionUID = 1L;
31 |
32 | public StateAccessException(String message) {
33 | super(message);
34 | }
35 |
36 | public StateAccessException(String message, Throwable cause) {
37 | super(message, cause);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/spi/InputAndSpec.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.spi;
18 |
19 | import org.apache.flink.streaming.api.datastream.DataStream;
20 |
21 | import com.dataartisans.streamingledger.sdk.api.StreamingLedger;
22 |
23 | import java.util.List;
24 |
25 | import static java.util.Objects.requireNonNull;
26 |
27 | /**
28 | * An input to {@link StreamingLedgerRuntimeProvider#translate(String, List)}.
29 | * This would be created by {@link StreamingLedger#resultStreams()}.
30 | */
31 | public final class InputAndSpec {
32 |
33 | public final DataStream inputStream;
34 |
35 | public final String streamName;
36 |
37 | public final StreamingLedgerSpec streamSpec;
38 |
39 | public InputAndSpec(DataStream inputStream, String streamName, StreamingLedgerSpec spec) {
40 | this.inputStream = requireNonNull(inputStream);
41 | this.streamName = requireNonNull(streamName);
42 | this.streamSpec = requireNonNull(spec);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/da-streamingledger-runtime-serial/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 |
20 | 4.0.0
21 |
22 |
23 | com.data-artisans.streamingledger
24 | da-streamingledger
25 | 1.1-SNAPSHOT
26 | ..
27 |
28 |
29 | da-streamingledger-runtime-serial
30 | da-streamingledger :: da-streamingledger-runtime-serial
31 |
32 | jar
33 |
34 |
35 |
36 | com.data-artisans.streamingledger
37 | da-streamingledger-sdk
38 | ${project.version}
39 |
40 |
41 | org.apache.flink
42 | flink-streaming-java_2.11
43 | ${flink.version}
44 | provided
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/common/reflection/Methods.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.common.reflection;
18 |
19 | import java.lang.annotation.Annotation;
20 | import java.lang.reflect.Method;
21 | import java.util.Arrays;
22 | import java.util.Iterator;
23 | import java.util.stream.Stream;
24 |
25 | /**
26 | * Reflection utility functions.
27 | */
28 | public final class Methods {
29 | private Methods() {
30 | }
31 |
32 | /**
33 | * Finds all the {@link Method}s that are annotated with the supplied annotation.
34 | *
35 | *
This method will traverse up the superclass hierarchy looking for methods annotated with the supplied
36 | * annotation.
37 | *
38 | * @return an iterator of {@link Method}s found.
39 | */
40 | public static Iterator findAnnotatedMethods(Class> javaClass, Class extends Annotation> annotation) {
41 | return definedMethods(javaClass)
42 | .filter(method -> method.getAnnotation(annotation) != null)
43 | .iterator();
44 | }
45 |
46 | private static Stream definedMethods(Class> javaClass) {
47 | if (javaClass == null || javaClass == Object.class) {
48 | return Stream.empty();
49 | }
50 | Stream selfMethods = Arrays.stream(javaClass.getDeclaredMethods());
51 | Stream superMethods = definedMethods(javaClass.getSuperclass());
52 |
53 | return Stream.concat(selfMethods, superMethods);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/common/union/UnionSerializerConfigSnapshot.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.common.union;
18 |
19 | import org.apache.flink.api.common.typeutils.CompositeTypeSerializerConfigSnapshot;
20 | import org.apache.flink.api.common.typeutils.TypeSerializer;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * UnionSerializerConfigSnapshot - A serializer configuration snapshot for the {@link UnionSerializer}.
26 | */
27 | public final class UnionSerializerConfigSnapshot extends CompositeTypeSerializerConfigSnapshot {
28 |
29 | private static final int VERSION = 1;
30 |
31 | /**
32 | * A default constructor is required by Flink's serialization framework.
33 | */
34 | @SuppressWarnings("unused")
35 | public UnionSerializerConfigSnapshot() {
36 | }
37 |
38 | /**
39 | * Creates a new instance of UnionSerializerConfigSnapshot.
40 | */
41 | @SuppressWarnings("WeakerAccess")
42 | public UnionSerializerConfigSnapshot(List> underlyingSerializers) {
43 | super(toArray(underlyingSerializers));
44 | }
45 |
46 | private static TypeSerializer>[] toArray(List> underlyingSerializers) {
47 | final int n = underlyingSerializers.size();
48 | TypeSerializer>[] rawSerializers = new TypeSerializer[n];
49 | return underlyingSerializers.toArray(rawSerializers);
50 | }
51 |
52 | @Override
53 | public int getVersion() {
54 | return VERSION;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tools/maven/spotbugs-exclude.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/tools/intellij/codestyle-java.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
23 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/da-streamingledger-runtime-serial/src/main/java/com/dataartisans/streamingledger/runtime/serial/SideOutputContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.runtime.serial;
18 |
19 | import org.apache.flink.streaming.api.functions.ProcessFunction;
20 | import org.apache.flink.streaming.api.functions.ProcessFunction.Context;
21 | import org.apache.flink.util.OutputTag;
22 |
23 | import com.dataartisans.streamingledger.sdk.api.TransactionProcessFunction;
24 |
25 | import java.io.Serializable;
26 | import java.util.ArrayList;
27 |
28 | final class SideOutputContext implements TransactionProcessFunction.Context, Serializable {
29 |
30 | private static final long serialVersionUID = 1;
31 | private final ArrayList records = new ArrayList<>();
32 | private transient OutputTag outputTag;
33 | private transient ProcessFunction.Context context;
34 | private boolean aborted;
35 |
36 | void setContext(Context context) {
37 | this.context = context;
38 | }
39 |
40 | void setOutputTag(OutputTag outputTag) {
41 | this.outputTag = outputTag;
42 | }
43 |
44 | void prepare() {
45 | aborted = false;
46 | records.clear();
47 | }
48 |
49 | @Override
50 | public void abort() {
51 | aborted = true;
52 | records.clear();
53 | }
54 |
55 | @SuppressWarnings("unchecked")
56 | @Override
57 | public void emit(T record) {
58 | records.add(record);
59 | }
60 |
61 | boolean wasAborted() {
62 | return aborted;
63 | }
64 |
65 | void emitChanges() {
66 | if (aborted) {
67 | return;
68 | }
69 | for (T record : records) {
70 | context.output(outputTag, record);
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/api/AccessType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.api;
18 |
19 | /**
20 | * The AccessType defines whether certain state is only read or written or both.
21 | *
22 | *
The type of access has an impact on whether accesses to the state (and key) by different
23 | * transactions can execute independent of each other, or whether they need to be coordinated.
24 | * For example, multiple transactions can concurrently read a certain state, if no other
25 | * state currently writes the state.
26 | */
27 | @SuppressWarnings("unused")
28 | public enum AccessType {
29 |
30 | /**
31 | * Indicates that state is only read, but not modified.
32 | * If state is only read, it can never block any other transaction from advancing.
33 | */
34 | READ(false, false),
35 |
36 | /**
37 | * Indicates that state is modified, but not read before. Modifying state means that coordination
38 | * is involved to ensure consistency for the write back.
39 | */
40 | WRITE(true, true),
41 |
42 | /**
43 | * Indicates that state is read and later modified. This access type involves coordination to
44 | * ensure consistency for the write back, and possibly additional messages to read state.
45 | */
46 | READ_WRITE(true, false);
47 |
48 | private final boolean requiresLocking;
49 | private final boolean writeOnly;
50 |
51 | AccessType(boolean requiresLocking, boolean writeOnly) {
52 | this.requiresLocking = requiresLocking;
53 | this.writeOnly = writeOnly;
54 | }
55 |
56 | public boolean requiresLocking() {
57 | return requiresLocking;
58 | }
59 |
60 | public boolean writeOnly() {
61 | return writeOnly;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/common/union/TaggedElement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.common.union;
18 |
19 | import java.util.List;
20 | import java.util.Objects;
21 |
22 | /**
23 | * A simple POJO with a dataStreamTag and an element.
24 | *
25 | *
see {@link Union#apply(List)}.
26 | */
27 | public final class TaggedElement {
28 |
29 | public static final int UNDEFINED_TAG = -1;
30 |
31 | /**
32 | * an index of the original data stream before the union.
33 | */
34 | private int dataStreamTag;
35 |
36 | /**
37 | * an element from one of the original data streams.
38 | */
39 | private Object element;
40 |
41 | public TaggedElement(int dataStreamTag, Object element) {
42 | this.dataStreamTag = dataStreamTag;
43 | this.element = element;
44 | }
45 |
46 | public int getDataStreamTag() {
47 | return dataStreamTag;
48 | }
49 |
50 | public void setDataStreamTag(int dataStreamTag) {
51 | this.dataStreamTag = dataStreamTag;
52 | }
53 |
54 | public Object getElement() {
55 | return element;
56 | }
57 |
58 | public void setElement(Object element) {
59 | this.element = element;
60 | }
61 |
62 | @Override
63 | public boolean equals(Object o) {
64 | if (this == o) {
65 | return true;
66 | }
67 | if (o == null || getClass() != o.getClass()) {
68 | return false;
69 | }
70 | TaggedElement that = (TaggedElement) o;
71 | return dataStreamTag == that.dataStreamTag
72 | && Objects.equals(element, that.element);
73 | }
74 |
75 | @Override
76 | public int hashCode() {
77 | int result = 1;
78 | result = 31 * result + (element == null ? 0 : element.hashCode());
79 | result = 31 * result + Integer.hashCode(dataStreamTag);
80 | return result;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/da-streamingledger-examples/src/main/java/com/dataartisans/streamingledger/examples/simpletrade/generator/Throttler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.examples.simpletrade.generator;
18 |
19 | import static org.apache.flink.util.Preconditions.checkArgument;
20 |
21 | final class Throttler {
22 |
23 | private final long throttleBatchSize;
24 | private final long nanosPerBatch;
25 |
26 | private long endOfNextBatchNanos;
27 | private int currentBatch;
28 |
29 | Throttler(long maxRecordsPerSecond, int numberOfParallelSubtasks) {
30 | checkArgument(maxRecordsPerSecond == -1 || maxRecordsPerSecond > 0,
31 | "maxRecordsPerSecond must be positive or -1 (infinite)");
32 | checkArgument(numberOfParallelSubtasks > 0, "numberOfParallelSubtasks must be greater than 0");
33 |
34 | if (maxRecordsPerSecond == -1) {
35 | // unlimited speed
36 | throttleBatchSize = -1;
37 | nanosPerBatch = 0;
38 | endOfNextBatchNanos = System.nanoTime() + nanosPerBatch;
39 | currentBatch = 0;
40 | return;
41 | }
42 | final float ratePerSubtask =
43 | (float) maxRecordsPerSecond / numberOfParallelSubtasks;
44 |
45 | if (ratePerSubtask >= 10000) {
46 | // high rates: all throttling in intervals of 2ms
47 | throttleBatchSize = (int) ratePerSubtask / 500;
48 | nanosPerBatch = 2_000_000L;
49 | }
50 | else {
51 | throttleBatchSize = ((int) (ratePerSubtask / 20)) + 1;
52 | nanosPerBatch = ((int) (1_000_000_000L / ratePerSubtask)) * throttleBatchSize;
53 | }
54 | this.endOfNextBatchNanos = System.nanoTime() + nanosPerBatch;
55 | this.currentBatch = 0;
56 | }
57 |
58 | void throttle() throws InterruptedException {
59 | if (throttleBatchSize == -1) {
60 | return;
61 | }
62 | if (++currentBatch != throttleBatchSize) {
63 | return;
64 | }
65 | currentBatch = 0;
66 |
67 | final long now = System.nanoTime();
68 | final int millisRemaining = (int) ((endOfNextBatchNanos - now) / 1_000_000);
69 |
70 | if (millisRemaining > 0) {
71 | endOfNextBatchNanos += nanosPerBatch;
72 | Thread.sleep(millisRemaining);
73 | }
74 | else {
75 | endOfNextBatchNanos = now + nanosPerBatch;
76 | }
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/test/java/com/dataartisans/streamingledger/sdk/common/union/UnionSerializerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.common.union;
18 |
19 | import org.apache.flink.api.common.ExecutionConfig;
20 | import org.apache.flink.api.common.typeinfo.BasicTypeInfo;
21 | import org.apache.flink.api.common.typeutils.SerializerTestBase;
22 | import org.apache.flink.api.common.typeutils.TypeSerializer;
23 | import org.apache.flink.util.XORShiftRandom;
24 |
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | /**
29 | * Test {@link UnionSerializer}.
30 | */
31 | public class UnionSerializerTest extends SerializerTestBase {
32 |
33 | @Override
34 | protected TypeSerializer createSerializer() {
35 | List> serializers = new ArrayList<>();
36 | ExecutionConfig config = new ExecutionConfig();
37 |
38 | serializers.add(BasicTypeInfo.LONG_TYPE_INFO.createSerializer(config));
39 | serializers.add(BasicTypeInfo.STRING_TYPE_INFO.createSerializer(config));
40 | serializers.add(BasicTypeInfo.BOOLEAN_TYPE_INFO.createSerializer(config));
41 |
42 | return new UnionSerializer(serializers);
43 | }
44 |
45 | @Override
46 | protected int getLength() {
47 | return -1;
48 | }
49 |
50 | @Override
51 | protected Class getTypeClass() {
52 | return TaggedElement.class;
53 | }
54 |
55 | @Override
56 | protected TaggedElement[] getTestData() {
57 | XORShiftRandom random = new XORShiftRandom();
58 |
59 | TaggedElement[] data = new TaggedElement[100];
60 | for (int i = 0; i < data.length; i++) {
61 | final int tag = random.nextInt(3);
62 | final Object element;
63 | switch (tag) {
64 | case 0: {
65 | element = random.nextLong();
66 | break;
67 | }
68 | case 1: {
69 | byte[] bytes = new byte[random.nextInt(256)];
70 | random.nextBytes(bytes);
71 | element = new String(bytes);
72 | break;
73 | }
74 | case 2: {
75 | element = random.nextBoolean();
76 | break;
77 | }
78 | default: {
79 | element = null;
80 | }
81 | }
82 | data[i] = new TaggedElement(tag, element);
83 | }
84 | return data;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/api/TransactionProcessFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.api;
18 |
19 | import org.apache.flink.api.common.functions.Function;
20 |
21 | import java.lang.annotation.ElementType;
22 | import java.lang.annotation.Retention;
23 | import java.lang.annotation.RetentionPolicy;
24 | import java.lang.annotation.Target;
25 |
26 | /**
27 | * TransactionProcessFunction.
28 | *
29 | * @param The type of the transaction input events.
30 | * @param The type of the transaction result events.
31 | */
32 | public abstract class TransactionProcessFunction implements Function {
33 |
34 | // stable serialVersionUID for compatibility across code updates
35 | private static final long serialVersionUID = 1L;
36 |
37 | // ------------------------------------------------------------------------
38 |
39 | /**
40 | * This interface marks the so called {@code 'process method'}, which processes the
41 | * transaction with the transaction event and the involved states.
42 | *
43 | *
This interface is declared within the TransactionProcessFunction class so that
44 | * users do not need to import anything when writing their process method.
45 | */
46 | @Target(ElementType.METHOD)
47 | @Retention(RetentionPolicy.RUNTIME)
48 | public @interface ProcessTransaction {
49 | }
50 |
51 | // ------------------------------------------------------------------------
52 |
53 | /**
54 | * Annotation for state access parameters in the process method.
55 | *
56 | *
This interface is declared within the TransactionProcessFunction class so that
57 | * users do not need to import anything when writing their process method.
58 | */
59 | @Target(ElementType.PARAMETER)
60 | @Retention(RetentionPolicy.RUNTIME)
61 | public @interface State {
62 |
63 | /**
64 | * The value is the name of the state access.
65 | */
66 | String value();
67 |
68 | }
69 |
70 | // ------------------------------------------------------------------------
71 |
72 | /**
73 | * Transaction Processing Context.
74 | */
75 | public interface Context {
76 |
77 | /**
78 | * Emits a transaction result.
79 | */
80 | void emit(T record);
81 |
82 | /**
83 | * Abort the current transaction.
84 | *
85 | *
Calling abort will undo any change made to a {@link StateAccess}, and will not cause a transaction result
86 | * to be emitted.
87 | */
88 | void abort();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/da-streamingledger-examples/src/main/java/com/dataartisans/streamingledger/examples/simpletrade/DepositEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.examples.simpletrade;
18 |
19 | /**
20 | * A simple data object that describes a deposit event.
21 | */
22 | public class DepositEvent {
23 |
24 | private String accountId;
25 |
26 | private String bookEntryId;
27 |
28 | private long accountTransfer;
29 |
30 | private long bookEntryTransfer;
31 |
32 | /**
33 | * Creates a new DepositEvent.
34 | */
35 | public DepositEvent(
36 | String accountId,
37 | String bookEntryId,
38 | long accountTransfer,
39 | long bookEntryTransfer) {
40 | this.accountId = accountId;
41 | this.bookEntryId = bookEntryId;
42 | this.accountTransfer = accountTransfer;
43 | this.bookEntryTransfer = bookEntryTransfer;
44 | }
45 |
46 | public DepositEvent() {
47 | }
48 |
49 |
50 | // ------------------------------------------------------------------------
51 | // properties
52 | // ------------------------------------------------------------------------
53 |
54 | public String getAccountId() {
55 | return accountId;
56 | }
57 |
58 | public void setAccountId(String accountId) {
59 | this.accountId = accountId;
60 | }
61 |
62 | public String getBookEntryId() {
63 | return bookEntryId;
64 | }
65 |
66 | public void setBookEntryId(String bookEntryId) {
67 | this.bookEntryId = bookEntryId;
68 | }
69 |
70 | public long getAccountTransfer() {
71 | return accountTransfer;
72 | }
73 |
74 | public void setAccountTransfer(long accountTransfer) {
75 | this.accountTransfer = accountTransfer;
76 | }
77 |
78 | public long getBookEntryTransfer() {
79 | return bookEntryTransfer;
80 | }
81 |
82 | public void setBookEntryTransfer(long bookEntryTransfer) {
83 | this.bookEntryTransfer = bookEntryTransfer;
84 | }
85 |
86 | // ------------------------------------------------------------------------
87 | // miscellaneous
88 | // ------------------------------------------------------------------------
89 |
90 | @Override
91 | public String toString() {
92 | return "DepositEvent {"
93 | + "accountId=" + accountId
94 | + ", bookEntryId=" + bookEntryId
95 | + ", accountTransfer=" + accountTransfer
96 | + ", bookEntryTransfer=" + bookEntryTransfer
97 | + '}';
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/api/StateAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.api;
18 |
19 | import com.dataartisans.streamingledger.sdk.api.StreamingLedger.State;
20 | import com.dataartisans.streamingledger.sdk.api.TransactionProcessFunction.Context;
21 |
22 | import java.util.function.Supplier;
23 |
24 | /**
25 | * This interface provides access to values of a {@link State}.
26 | *
27 | *
The state access binds a specific {@link State} value and
28 | * a specific argument to a {@link TransactionProcessFunction} process function.
29 | *
30 | *
35 | * Would bind {@code age} to a specific value (as identified by the input event {@code e}).
36 | * Calling {@link #read()} would return the bound value, and calling {@link #write(Object)} would
37 | * replace the value with the supplied argument.
38 | *
39 | *
Any change to this state access would made visible to other transactions, atomically as soon as the process
40 | * function completes, unless explicitly aborted via {@link Context#abort()}.
41 | *
42 | * @param value parameter type.
43 | */
44 | public interface StateAccess {
45 |
46 | /**
47 | * Reads a value.
48 | *
49 | * @return the value bound to this state access.
50 | * @throws StateAccessException if this state access is not readable. i.e. it is not one of {@link AccessType#READ}
51 | * or {@link AccessType#READ_WRITE}.
52 | */
53 | T read() throws StateAccessException;
54 |
55 | /**
56 | * Reads a value by replacing missing values with a default supplier.
57 | *
58 | * @param defaultSupplier a default value supplier.
59 | * @return the value bound to this state access or default otherwise.
60 | * @throws StateAccessException if this state access is not readable. (only {@link AccessType#WRITE})
61 | */
62 | default T readOr(Supplier defaultSupplier) throws StateAccessException {
63 | T read = read();
64 | if (read != null) {
65 | return read;
66 | }
67 | return defaultSupplier.get();
68 | }
69 |
70 | /**
71 | * Writes a value.
72 | *
73 | * @param newValue the value to bind with this state access.
74 | * @throws StateAccessException if this state access is not writeable. (only {@link AccessType#READ}).
75 | */
76 | void write(T newValue) throws StateAccessException;
77 |
78 | /**
79 | * Deletes a value.
80 | *
81 | *
Please note: that it would also delete the key associated with this value.
82 | *
83 | * @throws StateAccessException if this state access is not writeable. (only {@link AccessType#READ}).
84 | */
85 | void delete() throws StateAccessException;
86 |
87 | /**
88 | * @return the {@link State} name that this state access is referencing.
89 | */
90 | String getStateName();
91 |
92 | /**
93 | * @return the bind name of this state access.
94 | */
95 | String getStateAccessName();
96 | }
97 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/spi/StreamingLedgerSpec.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.spi;
18 |
19 | import org.apache.flink.api.common.typeinfo.TypeInformation;
20 |
21 | import com.dataartisans.streamingledger.sdk.api.StreamingLedger;
22 | import com.dataartisans.streamingledger.sdk.api.StreamingLedger.StateAccessSpec;
23 | import com.dataartisans.streamingledger.sdk.api.TransactionProcessFunction;
24 |
25 | import java.io.Serializable;
26 | import java.util.ArrayList;
27 | import java.util.Collections;
28 | import java.util.List;
29 | import java.util.Objects;
30 |
31 | import static java.util.Objects.requireNonNull;
32 |
33 | /**
34 | * A {@code StreamingLedgerSpec} contains all the necessary information gathered at
35 | * {@link StreamingLedger#usingStream} to execute the process function at runtime.
36 | *
37 | * @param The type of the transaction data events.
38 | * @param The type of the transaction data results.
39 | */
40 | public final class StreamingLedgerSpec implements Serializable {
41 |
42 | private static final long serialVersionUID = 1;
43 |
44 | // ------------------------------------------------------------------------
45 | // Properties
46 | // ------------------------------------------------------------------------
47 |
48 | public final TransactionProcessFunction processFunction;
49 | public final String processMethodName;
50 | public final List> stateBindings;
51 | public final TypeInformation inputType;
52 | public final TypeInformation resultType;
53 |
54 | StreamingLedgerSpec(
55 | TransactionProcessFunction processFunction,
56 | String processMethodName,
57 | List> stateBindings,
58 | TypeInformation inputType,
59 | TypeInformation resultType) {
60 | this.processFunction = requireNonNull(processFunction);
61 | this.processMethodName = requireNonNull(processMethodName);
62 | this.stateBindings = Collections.unmodifiableList(new ArrayList<>(stateBindings));
63 | this.inputType = requireNonNull(inputType);
64 | this.resultType = requireNonNull(resultType);
65 | }
66 |
67 | @Override
68 | public boolean equals(Object o) {
69 | if (this == o) {
70 | return true;
71 | }
72 | if (o == null || getClass() != o.getClass()) {
73 | return false;
74 | }
75 | StreamingLedgerSpec, ?> that = (StreamingLedgerSpec, ?>) o;
76 | return Objects.equals(processFunction, that.processFunction)
77 | && Objects.equals(processMethodName, that.processMethodName)
78 | && Objects.equals(stateBindings, that.stateBindings)
79 | && Objects.equals(inputType, that.inputType)
80 | && Objects.equals(resultType, that.resultType);
81 | }
82 |
83 | @Override
84 | public int hashCode() {
85 | return Objects.hash(processFunction, processMethodName, stateBindings, inputType, resultType);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/common/union/UnionTypeInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.common.union;
18 |
19 | import org.apache.flink.api.common.ExecutionConfig;
20 | import org.apache.flink.api.common.typeinfo.TypeInformation;
21 | import org.apache.flink.api.common.typeutils.TypeSerializer;
22 |
23 | import java.io.Serializable;
24 | import java.util.ArrayList;
25 | import java.util.List;
26 | import java.util.Objects;
27 |
28 | import static java.util.Objects.requireNonNull;
29 |
30 | final class UnionTypeInfo extends TypeInformation implements Serializable {
31 |
32 | private static final long serialVersionUID = 1;
33 |
34 | private final List> underlyingTypes;
35 |
36 | UnionTypeInfo(List> underlyingTypes) {
37 | requireNonNull(underlyingTypes);
38 | this.underlyingTypes = underlyingTypes;
39 | }
40 |
41 | @Override
42 | public boolean isBasicType() {
43 | return false;
44 | }
45 |
46 | @Override
47 | public boolean isTupleType() {
48 | return false;
49 | }
50 |
51 | @Override
52 | public int getArity() {
53 | return 1;
54 | }
55 |
56 | @Override
57 | public int getTotalFields() {
58 | return 1;
59 | }
60 |
61 | @Override
62 | public Class getTypeClass() {
63 | return TaggedElement.class;
64 | }
65 |
66 | @Override
67 | public boolean isKeyType() {
68 | return false;
69 | }
70 |
71 | @Override
72 | public TypeSerializer createSerializer(ExecutionConfig config) {
73 | List> underlyingSerializers = new ArrayList<>(underlyingTypes.size());
74 | for (TypeInformation> underlyingType : underlyingTypes) {
75 | TypeSerializer> serializer = underlyingType.createSerializer(config);
76 | underlyingSerializers.add(serializer);
77 | }
78 | return new UnionSerializer(underlyingSerializers);
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | StringBuilder sb = new StringBuilder();
84 | sb.append("UnionTaggedSerializer {");
85 | final int size = underlyingTypes.size();
86 | for (int i = 0; i < size; i++) {
87 | sb.append(underlyingTypes.get(i).toString());
88 | if (i < size - 1) {
89 | sb.append(", ");
90 | }
91 | }
92 | sb.append(" }");
93 | return sb.toString();
94 | }
95 |
96 | @Override
97 | public boolean equals(Object o) {
98 | if (this == o) {
99 | return true;
100 | }
101 | if (o == null || getClass() != o.getClass()) {
102 | return false;
103 | }
104 | UnionTypeInfo that = (UnionTypeInfo) o;
105 | return Objects.equals(underlyingTypes, that.underlyingTypes);
106 | }
107 |
108 | @Override
109 | public int hashCode() {
110 | return Objects.hash(underlyingTypes);
111 | }
112 |
113 | @Override
114 | public boolean canEqual(Object obj) {
115 | return obj instanceof UnionTypeInfo;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/da-streamingledger-examples/src/main/java/com/dataartisans/streamingledger/examples/simpletrade/generator/SyntheticSources.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.examples.simpletrade.generator;
18 |
19 | import org.apache.flink.api.common.typeinfo.TypeInformation;
20 | import org.apache.flink.streaming.api.datastream.DataStream;
21 | import org.apache.flink.streaming.api.datastream.DataStreamSource;
22 | import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
23 | import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
24 | import org.apache.flink.streaming.api.functions.ProcessFunction;
25 | import org.apache.flink.types.Either;
26 | import org.apache.flink.util.Collector;
27 | import org.apache.flink.util.OutputTag;
28 |
29 | import com.dataartisans.streamingledger.examples.simpletrade.DepositEvent;
30 | import com.dataartisans.streamingledger.examples.simpletrade.TransactionEvent;
31 |
32 | /**
33 | * Creates two synthetic sources for {@link DepositEvent} and {@link TransactionEvent}.
34 | */
35 | public final class SyntheticSources {
36 |
37 | public final DataStream deposits;
38 | public final DataStream transactions;
39 |
40 | /**
41 | * Creates and adds two synthetic sources for {@link DepositEvent} and {@link TransactionEvent}.
42 | *
43 | * @param env the streaming environment to add the sources to.
44 | * @param recordsPerSecond the number of {@link TransactionEvent} per second to generate.
45 | * @return a {@link DataStream} for each event type generated.
46 | */
47 | public static SyntheticSources create(StreamExecutionEnvironment env, int recordsPerSecond) {
48 |
49 | final DataStreamSource> depositsAndTransactions = env.addSource(
50 | new DepositsThenTransactionsSource(recordsPerSecond));
51 |
52 | final OutputTag transactionsSideOutput = new OutputTag<>(
53 | "transactions side output",
54 | TypeInformation.of(TransactionEvent.class));
55 |
56 | final SingleOutputStreamOperator deposits = depositsAndTransactions.process(
57 | new ProcessFunction, DepositEvent>() {
58 |
59 | @Override
60 | public void processElement(
61 | Either depositOrTransaction,
62 | Context context,
63 | Collector out) {
64 |
65 | if (depositOrTransaction.isLeft()) {
66 | out.collect(depositOrTransaction.left());
67 | }
68 | else {
69 | context.output(transactionsSideOutput, depositOrTransaction.right());
70 | }
71 | }
72 | });
73 |
74 | final DataStream transactions = deposits.getSideOutput(transactionsSideOutput);
75 |
76 | return new SyntheticSources(deposits, transactions);
77 | }
78 |
79 | SyntheticSources(DataStream deposits, DataStream transactions) {
80 | this.deposits = deposits;
81 | this.transactions = transactions;
82 | }
83 | }
84 |
85 |
--------------------------------------------------------------------------------
/da-streamingledger-examples/src/main/java/com/dataartisans/streamingledger/examples/simpletrade/TransactionResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.examples.simpletrade;
18 |
19 | import static java.util.Objects.requireNonNull;
20 |
21 | /**
22 | * Data type describing the result of a processed transaction.
23 | * It describes whether the transaction was successful as well as the resulting account balances.
24 | */
25 | public class TransactionResult {
26 |
27 | private TransactionEvent transaction;
28 |
29 | private boolean success;
30 |
31 | private long newSourceAccountBalance;
32 |
33 | private long newTargetAccountBalance;
34 |
35 | /**
36 | * Creates a new transaction result.
37 | *
38 | * @param transaction The original transaction event.
39 | * @param success True, if the transaction was successful, false if not.
40 | * @param newSourceAccountBalance The resulting balance of the source account.
41 | * @param newTargetAccountBalance The resulting balance of the target account.
42 | */
43 | public TransactionResult(
44 | TransactionEvent transaction,
45 | boolean success,
46 | long newSourceAccountBalance,
47 | long newTargetAccountBalance) {
48 |
49 | this.transaction = requireNonNull(transaction);
50 | this.success = success;
51 | this.newSourceAccountBalance = newSourceAccountBalance;
52 | this.newTargetAccountBalance = newTargetAccountBalance;
53 | }
54 |
55 | public TransactionResult() {
56 | }
57 |
58 | // ------------------------------------------------------------------------
59 | // Properties
60 | // ------------------------------------------------------------------------
61 |
62 | public TransactionEvent getTransaction() {
63 | return transaction;
64 | }
65 |
66 | public void setTransaction(TransactionEvent transaction) {
67 | this.transaction = transaction;
68 | }
69 |
70 | public boolean isSuccess() {
71 | return success;
72 | }
73 |
74 | public void setSuccess(boolean success) {
75 | this.success = success;
76 | }
77 |
78 | public long getNewSourceAccountBalance() {
79 | return newSourceAccountBalance;
80 | }
81 |
82 | public void setNewSourceAccountBalance(long newSourceAccountBalance) {
83 | this.newSourceAccountBalance = newSourceAccountBalance;
84 | }
85 |
86 | public long getNewTargetAccountBalance() {
87 | return newTargetAccountBalance;
88 | }
89 |
90 | public void setNewTargetAccountBalance(long newTargetAccountBalance) {
91 | this.newTargetAccountBalance = newTargetAccountBalance;
92 | }
93 |
94 | // ------------------------------------------------------------------------
95 | // Miscellaneous
96 | // ------------------------------------------------------------------------
97 |
98 | @Override
99 | public String toString() {
100 | return "TransactionResult {"
101 | + "transaction=" + transaction
102 | + ", success=" + success
103 | + ", newSourceAccountBalance=" + newSourceAccountBalance
104 | + ", newTargetAccountBalance=" + newTargetAccountBalance
105 | + '}';
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/da-streamingledger-runtime-serial/src/main/java/com/dataartisans/streamingledger/runtime/serial/SerialStateAccess.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.runtime.serial;
18 |
19 | import org.apache.flink.api.common.state.MapState;
20 | import org.apache.flink.api.java.functions.KeySelector;
21 |
22 | import com.dataartisans.streamingledger.sdk.api.AccessType;
23 | import com.dataartisans.streamingledger.sdk.api.StateAccess;
24 | import com.dataartisans.streamingledger.sdk.api.StateAccessException;
25 | import com.dataartisans.streamingledger.sdk.api.StateNotReadableException;
26 | import com.dataartisans.streamingledger.sdk.api.StateNotWritableException;
27 | import com.dataartisans.streamingledger.sdk.api.StreamingLedger.StateAccessSpec;
28 |
29 | import static java.util.Objects.requireNonNull;
30 |
31 | final class SerialStateAccess implements StateAccess {
32 | private final StateAccessSpec spec;
33 | private final MapState state;
34 |
35 | private final KeySelector keySelector;
36 | private final boolean writeOnly;
37 | private final boolean readOnly;
38 |
39 | private K key;
40 | private V value;
41 | private boolean changed;
42 |
43 | SerialStateAccess(StateAccessSpec spec, MapState state) {
44 | this.spec = requireNonNull(spec);
45 | this.state = requireNonNull(state);
46 | this.keySelector = requireNonNull(spec.keyAccess);
47 | this.writeOnly = spec.accessType == AccessType.WRITE;
48 | this.readOnly = spec.accessType == AccessType.READ;
49 | }
50 |
51 | @Override
52 | public V read() throws StateAccessException {
53 | if (writeOnly) {
54 | throw new StateNotReadableException(this);
55 | }
56 | return value;
57 | }
58 |
59 | @Override
60 | public void write(V newValue) throws StateAccessException {
61 | if (readOnly) {
62 | throw new StateNotWritableException(this);
63 | }
64 | this.value = newValue;
65 | this.changed = true;
66 | }
67 |
68 | @Override
69 | public void delete() throws StateAccessException {
70 | if (readOnly) {
71 | throw new StateNotWritableException(this);
72 | }
73 | this.value = null;
74 | this.changed = true;
75 | }
76 |
77 | @Override
78 | public String getStateName() {
79 | return spec.state.getName();
80 | }
81 |
82 | @Override
83 | public String getStateAccessName() {
84 | return spec.bindName;
85 | }
86 |
87 | // -----------------------------------------------------
88 | // For internal use by SerialTransactor
89 | // -----------------------------------------------------
90 |
91 | void prepare(InT input) throws Exception {
92 | final K key = keySelector.getKey(input);
93 | this.key = key;
94 | this.changed = false;
95 | if (!writeOnly) {
96 | this.value = state.get(key);
97 | }
98 | }
99 |
100 | void commit(boolean wasAborted) throws Exception {
101 | if (!changed || wasAborted) {
102 | return;
103 | }
104 | if (value == null) {
105 | state.remove(key);
106 | }
107 | else {
108 | state.put(key, value);
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/tools/intellij/inspections.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
22 |
25 |
26 |
27 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
44 |
45 |
46 |
47 |
49 |
50 |
51 |
52 |
54 |
55 |
56 |
57 |
59 |
61 |
63 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/da-streamingledger-sdk/src/main/java/com/dataartisans/streamingledger/sdk/spi/StreamingLedgerRuntimeLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.sdk.spi;
18 |
19 | import org.apache.flink.util.FlinkRuntimeException;
20 |
21 | import java.util.Iterator;
22 | import java.util.ServiceLoader;
23 | import java.util.concurrent.locks.ReentrantLock;
24 |
25 | import javax.annotation.Nullable;
26 | import javax.annotation.concurrent.GuardedBy;
27 |
28 | /**
29 | * A loader utility to find and load the {@link StreamingLedgerRuntimeProvider} to
30 | * execute the program with.
31 | */
32 | public class StreamingLedgerRuntimeLoader {
33 |
34 | /**
35 | * The lock to make sure only one transaction runtime provider is ever loaded.
36 | */
37 | private static final ReentrantLock LOCK = new ReentrantLock();
38 |
39 | /**
40 | * The transaction runtime provider, null if not yet loaded.
41 | */
42 | @Nullable
43 | private static StreamingLedgerRuntimeProvider runtimeProvider;
44 |
45 | /**
46 | * Gets the runtime provider to execute the transactions. This method will load
47 | * the runtime provider if it has not been loaded before.
48 | *
49 | *
If more than one runtime provider is found, this method throws an
50 | * exception, because it cannot determine which provider to use.
51 | */
52 | public static StreamingLedgerRuntimeProvider getRuntimeProvider() {
53 | LOCK.lock();
54 | try {
55 | if (runtimeProvider == null) {
56 | runtimeProvider = loadRuntimeProvider();
57 | }
58 | return runtimeProvider;
59 | }
60 | finally {
61 | LOCK.unlock();
62 | }
63 | }
64 |
65 | @GuardedBy("LOCK")
66 | private static StreamingLedgerRuntimeProvider loadRuntimeProvider() {
67 | try {
68 | ServiceLoader serviceLoader =
69 | ServiceLoader.load(StreamingLedgerRuntimeProvider.class);
70 |
71 | Iterator iter = serviceLoader.iterator();
72 |
73 | // find the first service implementation
74 | StreamingLedgerRuntimeProvider firstProvider;
75 | if (iter.hasNext()) {
76 | firstProvider = iter.next();
77 | }
78 | else {
79 | throw new FlinkRuntimeException("No StreamingLedgerRuntimeProvider found. "
80 | + "Please make sure you have a transaction runtime implementation in the classpath.");
81 | }
82 |
83 | // check if there is more than one service implementation
84 | if (iter.hasNext()) {
85 | String secondServiceName = "(could not load service implementation)";
86 | try {
87 | secondServiceName = iter.next().getClass().getName();
88 | }
89 | catch (Throwable ignored) {
90 | }
91 |
92 | throw new FlinkRuntimeException("Ambiguous: Found more than one StreamingLedgerRuntimeProvider: "
93 | + firstProvider.getClass().getName() + " and " + secondServiceName);
94 | }
95 |
96 | return firstProvider;
97 | }
98 | catch (FlinkRuntimeException e) {
99 | // simply propagate without further wrapping, for simplicity
100 | throw e;
101 | }
102 | catch (Throwable t) {
103 | throw new FlinkRuntimeException("Could not load StreamingLedgerRuntimeProvider", t);
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/da-streamingledger-runtime-serial/src/main/java/com/dataartisans/streamingledger/runtime/serial/SerialStreamingLedgerRuntimeProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.runtime.serial;
18 |
19 | import org.apache.flink.streaming.api.datastream.DataStream;
20 | import org.apache.flink.streaming.api.datastream.KeyedStream;
21 | import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
22 | import org.apache.flink.util.OutputTag;
23 |
24 | import com.dataartisans.streamingledger.sdk.api.StreamingLedger.ResultStreams;
25 | import com.dataartisans.streamingledger.sdk.common.union.TaggedElement;
26 | import com.dataartisans.streamingledger.sdk.common.union.Union;
27 | import com.dataartisans.streamingledger.sdk.spi.InputAndSpec;
28 | import com.dataartisans.streamingledger.sdk.spi.StreamingLedgerRuntimeProvider;
29 | import com.dataartisans.streamingledger.sdk.spi.StreamingLedgerSpec;
30 |
31 | import java.util.ArrayList;
32 | import java.util.HashMap;
33 | import java.util.List;
34 | import java.util.Map;
35 | import java.util.stream.Collectors;
36 |
37 | /**
38 | * A {@link StreamingLedgerRuntimeProvider} for the default serial transaction implementation.
39 | */
40 | public final class SerialStreamingLedgerRuntimeProvider implements StreamingLedgerRuntimeProvider {
41 |
42 | private static DataStream union(List> inputAndSpecs) {
43 | List> inputs = inputAndSpecs.stream()
44 | .map(inputAndSpec -> inputAndSpec.inputStream)
45 | .collect(Collectors.toList());
46 |
47 | return Union.apply(inputs);
48 | }
49 |
50 | // -------------------------------------------------------------------------------------------------------
51 | // Helpers
52 | // -------------------------------------------------------------------------------------------------------
53 |
54 | private static List> createSideOutputTags(List> specs) {
55 | List> outputTags = new ArrayList<>();
56 | for (InputAndSpec, ?> streamWithSpec : specs) {
57 | OutputTag> outputTag = new OutputTag<>(streamWithSpec.streamName, streamWithSpec.streamSpec.resultType);
58 | outputTags.add(outputTag);
59 | }
60 | return outputTags;
61 | }
62 |
63 | private static List> specs(List> inputAndSpecs) {
64 | return inputAndSpecs.stream()
65 | .map(inputAndSpec -> inputAndSpec.streamSpec)
66 | .collect(Collectors.toList());
67 | }
68 |
69 | @Override
70 | public ResultStreams translate(String name, List> streamLedgerSpecs) {
71 | List> sideOutputTags = createSideOutputTags(streamLedgerSpecs);
72 |
73 | // the input stream is a union of different streams.
74 | KeyedStream input = union(streamLedgerSpecs)
75 | .keyBy(unused -> true);
76 |
77 | // main pipeline
78 | String serialTransactorName = "SerialTransactor(" + name + ")";
79 | SingleOutputStreamOperator resultStream = input
80 | .process(new SerialTransactor(specs(streamLedgerSpecs), sideOutputTags))
81 | .name(serialTransactorName)
82 | .uid(serialTransactorName + "___SERIAL_TX")
83 | .forceNonParallel()
84 | .returns(Void.class);
85 |
86 | // gather the sideOutputs.
87 | Map> output = new HashMap<>();
88 | for (OutputTag> outputTag : sideOutputTags) {
89 | DataStream> rs = resultStream.getSideOutput(outputTag);
90 | output.put(outputTag.getId(), rs);
91 | }
92 | return new ResultStreams(output);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/da-streamingledger-runtime-serial/src/main/java/com/dataartisans/streamingledger/runtime/serial/SerialTransactor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Data Artisans GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.dataartisans.streamingledger.runtime.serial;
18 |
19 | import org.apache.flink.api.common.functions.RuntimeContext;
20 | import org.apache.flink.configuration.Configuration;
21 | import org.apache.flink.streaming.api.functions.ProcessFunction;
22 | import org.apache.flink.util.Collector;
23 | import org.apache.flink.util.OutputTag;
24 |
25 | import com.dataartisans.streamingledger.sdk.common.union.TaggedElement;
26 | import com.dataartisans.streamingledger.sdk.spi.StreamingLedgerSpec;
27 |
28 | import java.util.List;
29 | import java.util.stream.Collectors;
30 |
31 | import static java.util.Objects.requireNonNull;
32 |
33 | final class SerialTransactor extends ProcessFunction {
34 |
35 | private static final long serialVersionUID = 1;
36 |
37 | private final List> specs;
38 | private final List> sideOutputs;
39 | private final SideOutputContext