anubhavjana / DAGit-Serverless-Applications-as-a-Service

0 stars 1 forks source link

DAGit

Currently being developed by Anubhav Jana along with Prof Puru IITB

This serverless FaaS platform supports individual function registrations, DAG registrations, Trigger registrations associated with DAGs/functons. This platform also supports various DAG primitives which is provided in this document for reference.

Guide: Register a Function

This section will guide you how to register a function. The following pre-requites are to be fulfilled before you register a function

You must have the above 3 files before you register the function

Following is the sample code register_function.py to register a function. This will create a new function named "testaction" and register it onto our function store handled by us. The url endpoint is: /regster/function/function_name

register_function.py

import requests
import sys
import json

def server():

    url = "http://10.129.28.219:5001/register/function/testaction"
    files = [
    ('pythonfile', open(sys.argv[1],'rb')),
    ('dockerfile', open(sys.argv[2],'rb')),
    ('requirements.txt', open(sys.argv[3],'rb'))
   ]

   reply = requests.post(url = url,files = files,verify=False)
   print(reply.json())

def main():
    server()

if __name__=="__main__":
    main()

Guide: Register a DAG

This section will guide you how to register a DAG. The following pre-requites are to be fulfilled before you register a DAG

Following is the sample code dag_register.py to register a DAG. This will register a new DAG onto our DAG store handled by us. The url endpoint is: /regster/dag

dag_register.py

import requests
import sys
import json

def server():
    url = "http://10.129.28.219:5001/register/dag"
    input_json_file = open(sys.argv[1])
    params = json.load(input_json_file)
    reply = requests.post(url = url,json = params,verify=False)
    print(reply.json())

def main():
    server()

if __name__=="__main__":
    main()

Guide: Register a Trigger

This section will guide you how to register a trigger. The following pre-requites are to be fulfilled before you register a trigger

Accepted Trigger Format

DAG specification includes both control dependancy as well as the control dependancy

Trigger Fields

Example format of trigger.json

{
    "trigger_name": "mydagtrigger",
    "type":"dag",
    "dags": ["odd-even-test","dummy-dag"],
    "functions":""
}
{
    "trigger_name": "myfunctiontrigger",
    "type":"function",
    "dags":"",
    "functions": ["odd-even-action"]
}

Following is the sample code trigger_register.py to register a trigger. This will register a new trigger onto our Trigger store handled by us. The url endpoint is: /regster/trigger

trigger_register.py

import requests
import sys
import json

def server():
    url = "http://10.129.28.219:5001/register/trigger/"
    input_json_file = open(sys.argv[1])
    params = json.load(input_json_file)
    reply = requests.post(url = url,json = params,verify=False)
    print(reply.json())

def main():
    server()

if __name__=="__main__":
    main()

List of triggers

Supported DAG Primitive

dag_primitive

Accepted DAG Format

DAG specification includes both control dependancy as well as the control dependancy

DAG Fields

{

"name":<string>

"dag":[
    {
        "node_id": "<string>",
        "properties":
        {
            "node_id_label": "<string>"

            "primitive":"<condition | parallel | serial>",
            "condition":
            {
                "source":"<key obtained from node)id result json>",
                "operator":"<equals || greater_than || less_than || ..>",
                "target":"<string|integer>"

            },
            "next": "<next node_id to be executed : if primitive=parallel, "next" will take list of node_ids, if primitive: serial then specify a single node_id >",
            "branch_1": "<node_id if type==condition else keep "">",
            "branch_2": "<node_id if type==condition else keep "">",
            "arguments": {} ---> Keep it blank for all action. It will get updated when the DAG is run
            "outputs_from": "<list>"

        }
    },
    {

    },

    .
    .
    .

    {

    }

]

}

Sample Example Usage

odd-even-action

{

"name": "odd-even-test",

"dag": [

    {

        "node_id": "odd-even-action",
        "properties":
        {
            "label": "Odd Even Action",
            "primitive": "condition",
            "condition":
            {
                "source":"result",
                "operator":"equals",
                "target":"even"
            },

            "next": "",
            "branch_1": "even-print-action",
            "branch_2": "odd-print-action",
            "arguments": {},
            "outputs_from":[]

        }
    },
    {
        "node_id": "even-print-action",
        "properties":
        {

            "label": "Even Print Action",
            "primitive": "parallel",
            "condition": {},
            "next": ["increment-action","multiply-action"],
            "branch_1": "",
            "branch_2": "",
            "arguments":{},
            "outputs_from":["odd-even-action"]

        }

    },
    {
        "node_id": "increment-action",
        "properties":
        {

            "label": "INCREMENT ACTION",
            "primitive": "serial",
            "condition": {},
            "next": "",
            "branch_1": "",
            "branch_2": "",
            "arguments":{},
            "outputs_from":["even-print-action"]

        }

    },
    {
        "node_id": "multiply-action",
        "properties":
        {

            "label": "MULTIPLY ACTION",
            "primitive": "serial",
            "condition": {},
            "next": "",
            "branch_1": "",
            "branch_2": "",
            "arguments":{},
            "outputs_from":["even-print-action"]

        }

    },
    {
        "node_id": "odd-print-action",
        "properties":
        {
            "label": "Odd Print Action",
            "primitive": "serial",
            "condition":{},
            "next": "prime-check-action",
            "branch_1": "",
            "branch_2": "",
            "arguments":{},
            "outputs_from":["odd-even-action"]
        }

    },
    {
        "node_id": "prime-check-action",
        "properties":
        {
            "label": "Prime Check Action",
            "primitive": "serial",
            "condition":{},
            "next": "",
            "branch_1": "",
            "branch_2": "",
            "arguments":{},
            "outputs_from":["odd-print-action"]

        }

    }

]

}

Handle output from multiple actions

Suppose you want to merge outputs from two actions action_1 and action_2 in your action_3, then you must include the following lines in your action_3 to process incoming inputs from action_1 and action_2

. This is applicable for merging primitive as well as handling output from multiple actions. * "key_action_1" refers to a key from action_1 response which you want to use in action_3 * "key_action_2" refers to a key from action_2 response which you want to use in action_3 params = json.loads(sys.argv[1]) op_1 = params["__ow_body"][0]["key_action_1"] op_2 = params["__ow_body"][1]["key_action_2"] Use these op_1 and op_2 to process