All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fluxtion.ext.streaming.api.Wrapper Maven / Gradle / Ivy

There is a newer version: 2.10.50
Show newest version
/* 
 * Copyright (C) 2018 V12 Technology Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Server Side Public License, version 1,
 * as published by MongoDB, Inc.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Server Side Public License for more details.
 *
 * You should have received a copy of the Server Side Public License
 * along with this program.  If not, see 
 * .
 */
package com.fluxtion.ext.streaming.api;

import com.fluxtion.api.SepContext;
import com.fluxtion.api.partition.LambdaReflection.SerializableBiFunction;
import com.fluxtion.api.partition.LambdaReflection.SerializableConsumer;
import com.fluxtion.api.partition.LambdaReflection.SerializableFunction;
import com.fluxtion.ext.streaming.api.group.GroupBy;
import com.fluxtion.ext.streaming.api.stream.Argument;
import com.fluxtion.ext.streaming.api.stream.StreamOperator;
import com.fluxtion.ext.streaming.api.window.WindowBuildOperations;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;

/**
 * A wrapper class that holds a reference to a node in the SEP. Any node in SEP
 * can be a source of a stream of values.

* Stream operations are provided to filter and map the underlying wrapped type. * * @author Greg Higgins * @param */ public interface Wrapper extends Stateful{ /** * The wrapped node * * @return the wrapped node */ T event(); /** * The type of the wrapped node * * @return wrapped node class */ Class eventClass(); @Override default void reset(){} default Argument arg(SerializableFunction supplier){ return Argument.arg(this, supplier); } default Argument arg(){ return Argument.arg(this); } /** * Set the default value for this instance. The default value will be set when any call to reset is made. Having a * default value allows an instance to be used by its children before an event has been processed. * * @param defaultValue the default value to use * @return */ default Wrapper defaultVal(T defaultValue){ return StreamOperator.service().defaultVal(this, defaultValue); } default FilterWrapper filter(SerializableFunction filter) { return StreamOperator.service().filter(filter, this, true); } default FilterWrapper filter(SerializableFunction supplier, SerializableFunction filter) { return StreamOperator.service().filter(filter, this, supplier.method(), true); } default Wrapper get(SerializableFunction supplier) { return StreamOperator.service().get(supplier, this); } default WrappedList collect(){ return SepContext.service().add(new ArrayListWrappedCollection<>(this)); } default GroupBy group( SerializableFunction key, SerializableBiFunction functionClass) { return StreamOperator.service().group(this, key, functionClass); } default GroupBy group( SerializableFunction key, SerializableFunction supplier, SerializableBiFunction functionClass) { return StreamOperator.service().group(this, key, supplier, functionClass); } /** * Maps a value using the provided mapping function.The input is the * wrapped instance inside this {@link Wrapper}. * * @param The return type of the mapping function * @param * @param mapper the mapping function * @return A wrapped value containing the result of the mapping operation */ default Wrapper map(SerializableFunction mapper) { return (Wrapper) StreamOperator.service().map((SerializableFunction) mapper, this, true); } /** * Maps a value using the provided mapping function. The input is the return * value of the supplier function invoked on the wrapped instance. * * @param The return type of the mapping function * @param The input type required by the mapping function * @param mapper the mapping function * @param supplier * @return A wrapped value containing the result of the mapping operation */ default Wrapper map(SerializableFunction mapper, SerializableFunction supplier) { return StreamOperator.service().map((SerializableFunction) mapper, this, supplier.method(), true); } default Wrapper map(SerializableBiFunction mapper, Argument arg1, Argument arg2) { return (Wrapper) StreamOperator.service().map((SerializableBiFunction) mapper, arg1, arg2); } default Wrapper map(SerializableBiFunction mapper, SerializableFunction supplier1, SerializableFunction supplier2) { return (Wrapper) StreamOperator.service().map((SerializableBiFunction) mapper, Argument.arg(this, supplier1), Argument.arg(this, supplier2)); } default Wrapper map(SerializableBiFunction mapper, SerializableFunction supplier, Argument arg) { return (Wrapper) StreamOperator.service().map((SerializableBiFunction) mapper, Argument.arg(this, supplier), arg); } default Wrapper map(SerializableBiFunction mapper, Argument arg, SerializableFunction supplier) { return (Wrapper) StreamOperator.service().map((SerializableBiFunction) mapper, arg, Argument.arg(this, supplier)); } default Wrapper map(SerializableBiFunction mapper, SerializableFunction supplier, double arg) { return (Wrapper) StreamOperator.service().map((SerializableBiFunction) mapper, Argument.arg(this, supplier), Argument.arg(arg)); } default Wrapper map(SerializableBiFunction mapper, double arg, SerializableFunction supplier) { return (Wrapper) StreamOperator.service().map((SerializableBiFunction) mapper, Argument.arg(arg), Argument.arg(this, supplier)); } /** * Maps a binary function using the wrapped instance as the first argument * to the binary function. * * @param The result type of the mapping function * @param The type of the supplied argument * @param The input type for first argument to mapping function * @param The input type for second argument to mapping function * @param mapper The mapping function * @param arg1 The second argument of the binary mapping function * @return */ default Wrapper map(SerializableBiFunction mapper, Argument arg1) { return (Wrapper) StreamOperator.service().map((SerializableBiFunction) mapper, Argument.arg(this), arg1); } default Wrapper map(SerializableBiFunction mapper, double arg1) { return (Wrapper) StreamOperator.service().map((SerializableBiFunction) mapper, Argument.arg(this), Argument.arg(arg1)); } //windows reducing /** * Create a time based tumbling window aggregate result expiring after a duration has passed. The window combines the results of the supplied * function for all events that occur within the timed window * @param the result type of the function * @param mapper The function to apply to each event in the window * @param time The duration of the window * @return A result that is updated at the window expiry */ default Wrapper tumbling(SerializableFunction mapper, Duration time) { return WindowBuildOperations.service().tumbling(this, mapper, time); } /** * Create a count based tumbling window aggregate result expiring after receiving a number of events. The window combines the results of the supplied * function for all events that occur within the window * @param the result type of the function * @param mapper The function to apply to each event in the window * @param itemCount the number of events in a window * @return A result that is updated at the window expiry */ default Wrapper tumbling(SerializableFunction mapper, int itemCount) { return WindowBuildOperations.service().tumbling(this, mapper, itemCount); } /** * Create a time based sliding window aggregate result publishing after a duration has passed. The window combines the results of the supplied * function for all events that occur within the number of buckets. The total window time = time per bucket X number of buckets * @param the result type of the function * @param mapper The function to apply to each event in the window * @param time The duration of a bucket * @param numberOfBuckets the number of buckets in the window * @return A result that is updated at the window expiry */ default Wrapper sliding(SerializableFunction mapper, Duration time, int numberOfBuckets) { return WindowBuildOperations.service().sliding(this, mapper, time, numberOfBuckets); } /** * Create a count based sliding window aggregate result publishing after a count has passed. The window combines the results of the supplied * function for all events that occur within the number of buckets. The total window count = the number of events per bucket X number of buckets * @param the result type of the function * @param mapper The function to apply to each event in the window * @param itemCountPerBuket the number of events per bucket * @param numberOfBuckets the number of buckets in the window * @return A result that is updated at the window expiry */ default Wrapper sliding(SerializableFunction mapper, int itemCountPerBuket, int numberOfBuckets) { return WindowBuildOperations.service().sliding(this, mapper, itemCountPerBuket, numberOfBuckets); } //window collecting /** * Collects the events into a WrappedList using a time based sliding window strategy. * @param timePerBucket time per bucket * @param numberOfBuckets number of buckets in sliding window * @return The collection of events in sliding window */ default WrappedList sliding(Duration timePerBucket, int numberOfBuckets){ return WindowBuildOperations.service().sliding(collect(), timePerBucket, numberOfBuckets); } /** * Collects the events into a WrappedList using a count based sliding window strategy. * @param itemCount the count of events per bucket * @param numberOfBuckets number of buckets in sliding window * @return The collection of events in sliding window */ default WrappedList sliding(int itemCount, int numberOfBuckets){ return WindowBuildOperations.service().sliding(collect(), itemCount, numberOfBuckets); } /** * Collects the events into a WrappedList using a time based tumbling window strategy. * @param time duration of the tumbling window * @return The collection of events in sliding window */ default WrappedList tumbling(Duration time){ return WindowBuildOperations.service().tumbling(collect(), time); } /** * Collects the events into a WrappedList using a time based tumbling window strategy. * @param itemCount number of items in the tumbling window * @return The collection of events in sliding window */ default WrappedList tumbling(int itemCount){ return WindowBuildOperations.service().tumbling(collect(), itemCount); } /** * pushes a data item from the current node in the stream to any node.The * target node will become part of the same execution graph as the * source.

* The returned node is the current node in the stream. * * @param * @param * @param supplier * @param mapper * @return this */ default Wrapper push(SerializableFunction supplier, SerializableConsumer mapper) { StreamOperator.service().push(this, supplier.method(), mapper); return (Wrapper) this; } default Wrapper push(SerializableConsumer mapper) { StreamOperator.service().push(this, null, mapper); return (Wrapper) this; } /** * Registers a {@link Consumer} to operate on the current node when an event * wave is passing through this node. The consumer can perform any operation * on the node including mutations. This node, possibly mutated, is passed * as a reference to child nodes. No new nodes are created in the stream as * a side-effect of this processing. * * @param consumer {@link Consumer} of this node * @return The current node */ default Wrapper forEach(SerializableConsumer consumer) { return (Wrapper) StreamOperator.service().forEach(consumer, this, null); } default Wrapper forEach(SerializableConsumer consumer, String consumerId) { return (Wrapper) StreamOperator.service().forEach(consumer, this, consumerId); } LongAdder counter = new LongAdder(); /** * dump this node to log, prefixed with the supplied message.{@link Object#toString()} will be invoked on the node instance. * * @param prefix String prefix for the log message * @param supplier * @return The current node */ default Wrapper log(String prefix, SerializableFunction... supplier) { if (!prefix.contains("{}")) { prefix += " {}"; } return (Wrapper) StreamOperator.service().log(this, prefix, supplier); } default Wrapper log() { return log(""); } /** * Attaches an event notification instance to the current stream node. When * the notifier updates all the child nodes of this stream node will be on * the execution path and invoked following normal SEP rules. * * The existing execution path will be unaltered if either the parent * wrapped node or the eventNotifier updates then the execution path will * progress. * * @param eventNotifier external event notifier * @return */ default Wrapper notiferMerge(Object eventNotifier) { return StreamOperator.service().notiferMerge(this, eventNotifier); } /** * Attaches an event notification instance to the current stream node, * overriding the execution path of the current stream. Only when the * notifier updates will the child nodes of this stream node be on the * execution path. * * @param eventNotifier external event notifier * @return */ default Wrapper notifierOverride(Object eventNotifier) { return StreamOperator.service().notifierOverride(this, eventNotifier); } /** * Publishes the current value to all child dependencies and then resets. After all children have processed the trigger a reset is * invoked on the wrapped instance. The publish and reset is triggered when the supplied notifier triggers in the * execution graph. * * @param notifier trigger for publish and reset * @return */ default Wrapper publishAndReset(Object notifier) { return this; } /** * Resets the current value without notifying children of a change. The reset is triggered when the supplied notifier triggers in the * execution graph. * * @param notifier trigger for reset * @return */ default Wrapper resetNoPublish(Object notifier){ return this; } /** * Resets the stateful node and publishes the current value by notifying child nodes. The reset is * before the notification is broadcast. The reset and publish is triggered when the supplied notifier triggers in the * execution graph. * * @param notifier trigger for reset and publish * @return */ default Wrapper resetAndPublish(Object notifier) { return this; } /** * Controls the notification policy of event notification to child nodes for * this stream node. The default policy is to invoke child nodes when the * return of the parent event method is true. NotifyOnChange notifies the * child only when the parent node return of the previous cycle is false and * this one is true. *

* * This can be useful if a single notification of a breach is required and * subsequent continued breaches are swallowed, for example this can prevent * logging spamming when combined with filters. * * @param notifyOnChange false = notify always. true = notify on change only * @return The current node */ default Wrapper notifyOnChange(boolean notifyOnChange) { return this; } /** * Set this property to signal the wrapper has a valid value and child nodes do not have to wait for a trigger * notification before using the data from this instance. * * @param validOnStart * @return */ default Wrapper validOnStart(boolean validOnStart) { return this; } default boolean isValidOnStart() { return false; } /** * Set the node id for this node within the generated SEP. This is the * variable name of the node in a Java SEP. The id must be unique for the * SEP. * * @param id the unique id of the node in the SEP * @return The current node */ default Wrapper id(String id) { return StreamOperator.service().nodeId(this, id); } }