Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc Update #11

Merged
merged 3 commits into from
Jan 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 112 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,119 @@
[![Java CI with Maven](https://github.com/flipkart-incubator/tef/actions/workflows/maven.yml/badge.svg)](https://github.com/flipkart-incubator/tef/actions/workflows/maven.yml)
[![Maven Package](https://github.com/flipkart-incubator/tef/actions/workflows/maven-publish.yml/badge.svg)](https://github.com/flipkart-incubator/tef/actions/workflows/maven-publish.yml)

A low-footprint Workflow Execution Framework to build and execute configured DAGs.
## Philosophy

The highlights of this framework is its ability to configure within code, with the support for Data and Control Dependencies along with packaging logical blocks as Capabilities.
A low-footprint Workflow Execution Framework to build and execute configured DAGs.

The highlights of this framework is its ability to configure within code, with the support for Data and Control
Dependencies along with packaging logical blocks as Capabilities.

## Terminology

### Bizlogic

An arbitrary piece of logic wrapped in the `execute` method. There are different flavours of bizlogics to cater to
custom needs - like Data Adapters, Enrichers and Validators.

##### Data Adapter

A bizlogic that lets the `execute` method return an immutable value object.

##### Validator

A bizlogic that can be used to validate arbitrary items and set a status on them.

##### Enricher

A bizlogic that lets the `execute` method return a mutable object, whose value can be `enriched` over the course of the
flow.

### Capability

A capability is a collection of bizlogics. It defines a logical feature in any large arbitrary system. Such a system is
made up of 1 more `pluggable`
capabilities.

### Flow

A Flow represents a set of bizlogic to be executed in a strict pre-defined order
(topologically sorted) to adhere to the defined dependencies.

### Flow Builder

Tef has a `FluentCapabilityBuilder` which exposes a fluent api to build a flow. It supports apis to

1. Add bizlogics and its various flavors to the flow.
2. Define control dependencies between bizlogics.
3. Add capabilities to a flow.
4. Exclude arbitrary bizlogics from a flow.
5. Add implicit bindings (more on this later in the doc)

The `FlowBuilder` takes all the input from `FluentCapabilityBuilder` and topologically sorts the bizlogics, returning a
flat list of bizlogics to be executed. Flow Builder ensures the generated flow is a DAG. If cycles are found in the
definition, flow build fails at runtime.

## Dependency

Tef supports 2 types of dependency - Control Dependency and Data Dependency

### Control Dependency

Here a `Bizlogic A` is said to depend upon another `Bizlogic B`, in which case Tef ensures `B` will get executed
before `A`.

### Data Dependency

Here a `Bizlogic A` is said to depend upon `Data B`.
`Bizlogic A` does not know how the `Data B's` value is computed. Tef ensures that the data adapter responsible for
emitting `Data B` is executed before `Bizlogic A`.

### Implicit Binding

A data dependency can either be satisfied by another Data Adapter, or if the data is provided upfront at the start of
the flow execution. This is known as an Implicit Binding.

## Flow Builder

Tef has a `FluentFlowBuilder`

## Advanced Features

### [Data Injection](https://github.com/flipkart-incubator/tef/blob/main/tef-core/src/main/java/flipkart/tef/annotations/InjectData.java)

There are various flags that can be passed to a data injection viz. `mutable`, `nullable`, `name` and `optional` .

#### mutable

If a DataAdapter is injecting dependent data, and if that data can change, the injection can be marked as mutable. In
such cases, when the injected data changes, the injectee data adapter will get re-triggered.

#### nullable

This flag should be used on the bizlogics which are ok to receive a null value for this injection.

#### name

Name of the Injected data for specificity

#### optional

This parameter is indicative of the fact that the particular injection is optional. No checks will be performed if there
are no data adapters present for this injection. Such injections will only be served via the ImplicitBindings.

### Mutation Listener

`MutationListener` provides an ability to plug a callback when data returned a DataAdapter changes.

### Lifecycle Hooks

`FlowExecutionListener` provides an ability to listen to lifecycle hooks in during flow execution

Refer to [tests](https://github.com/flipkart-incubator/tef/tree/main/tef-impl/src/test/java/flipkart/tef) for detailed
use-cases.

## [Usage Instructions](UsageInstructions.md)

## Lead Developer

@bageshwar
114 changes: 114 additions & 0 deletions UsageInstructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
## How-To Guide

### Scenario 1

Here we will create a couple of vanilla bizlogics and demonstrate control dependencies between them by stitching a flow
and executing them.

```java
class BizlogicA implements IBizlogic {

@Override
public void execute(TefContext tefContext) {
System.out.println(this.getClass().getName());
}
}

// This class demonstrates the way to define control dependency
@DependsOn(BizlogicA.class)
class BizlogicB implements IBizlogic {

@Override
public void execute(TefContext tefContext) {
System.out.println(this.getClass().getName());
}
}
```

Building and executing the flow

```java
public class Demo {
public static void main(String args[]) {
FlowBuilder flowBuilder = new FlowBuilder();
flowBuilder.add(BizlogicA.class);
flowBuilder.add(BizlogicB.class);
// Please note that the order of adding bizlogics to the flow is inconsequential here.
// All the bizlogics in the flow are topologically sorted before at the time of `flowBuilder.build()`.

SimpleFlow simpleFlow = flowBuilder.build();

// Creating a FlowExecutor which takes flow and context as inputs.
FlowExecutor executor = new FlowExecutor(flow, new DataContext(), new TefContext());
// The execute method is a blocking call.
executor.execute();

// output
/*
BizlogicA
BizlogicB
* */
}
}

```

### Scenario 2

Defining Data Dependency

To define data dependency, create a data adapter to emit data

```java
// A sample data class (to be emitted by a DataAdapter)
public class SampleDataAdapter extends DataAdapterBizlogic<String> {

@Override
public String adapt(TefContext tefContext) {
System.out.println(this.getClass().getName());
return "Hello World";
}
}
```

Now this DataAdapter can be used in a bizlogic by injecting its data

```java
class BizlogicC implements IBizlogic {

@InjectData
private String dataFromSampleDataAdapter;

@Override
public void execute(TefContext tefContext) {
System.out.println(this.getClass().getName());
System.out.println(dataFromSampleDataAdapter);
}
}
```

Building and executing the flow

```java
public class Demo {
public static void main(String args[]) {
FlowBuilder flowBuilder = new FlowBuilder();
flowBuilder.add(BizlogicA.class);
flowBuilder.add(BizlogicB.class);
flowBuilder.add(BizlogicC.class);
flowBuilder.add(SampleDataAdapter.class);
SimpleFlow simpleFlow = flowBuilder.build();
FlowExecutor executor = new FlowExecutor(flow, new DataContext(), new TefContext());
executor.execute();

// output
/*
BizlogicA
BizlogicB
SampleDataAdapter
Hello World
* */
}
}

```
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import flipkart.tef.exception.TefExecutionException;

/**
* A specialized bizlogic that can be used to validate items in cart.
* A specialized bizlogic that can be used to validate items.
* <p>
* <p>
*
* Date: 19/06/20
* Time: 4:25 PM
*/
Expand All @@ -38,7 +38,7 @@ public final void execute(TefContext tefContext) throws TefExecutionException {

/**
* Implement this method to run the validation logic and return the validation status
* at an item level.
*
*
* @return Item Level Validation Status
*/
Expand Down