Giter Site home page Giter Site logo

deepakpathania-zz / noah Goto Github PK

View Code? Open in Web Editor NEW
7.0 2.0 2.0 782 KB

Scheduling as a service platform to make outbound requests recurringly.

License: MIT License

JavaScript 100.00%
scheduler scheduled-tasks scheduler-service scheduled-jobs rest-api nodejs sailsjs

noah's Introduction

Noah

Build Status Coverage Status License: MIT

Noah is a scheduling service that allows you to register tasks for making an outbound request after a recurring interval.

  • It allows you to configure the request to accept query params, headers and request body and accepts a human-readable interval to invoke the request.
  • It exposes a REST API for CRUD on schedules backed with a MySQL database for persistence. Refer to API section below for details.

Usage

Noah is supposed to be used as a self-hosted service for your scheduling needs. Here's how you can set it up.

  1. After cloning, install the dependencies.

    npm i
  2. Create a .env file in the root directory and add the following environment variables.

    MYSQL_HOST
    MYSQL_USER
    MYSQL_PASSWORD
    MYSQL_DB_NAME
    MYSQL_TEST_DB_NAME
    
  3. Create the databases you have specified in the .env file.

    CREATE DATABASE IF NOT EXISTS MYSQL_DB_NAME;

    You don't need to create the tables explicitly, sails does that for you based on the models when you lift the server.

  4. Lift the server.

    node app.js
  5. Test whether the server was lifted properly by making a call to the health check endpoint : {{url}}/knockknock

API

Noah exposes the following APIs to interact with the system.

  1. Create Schedule - Allows you to register a schedule with the system.

    • Endpoint - /v1/schedules
    • Method - POST
    • Request Body:
      {
        "request": {
          "url": "{{targetUrl}}",
          "method": "{{method}}",
          "data": {
            "params": {
                "key": "value"
            },
            "headers": {},
            "body": {}
          }
        },
        "period": {
          "every": 2,
          "interval": "{{interval}}"
        },
        "start": true,
        "storeResponseBody": true
      }
      • request is a required field. It includes the following required fields:

        • url (string)- specifies the target URL to be called.
        • method (string)- specifies the request method for calling the URL, eg. GET. Accepts one of the following values ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE']
        • data (object) - specifies the request data to be sent with the request. Send {} in case of no data. Each data item is an object that accepts key-value pairs.

        Note - body accepts only raw format for now with json data, application/json header is added implicitly.

      • period is a required field. It includes the following required fields:

        • every (integer) - represents the frequency of invocation, for eg. every 2 hours.
        • interval (string) - represents the time interval between invocations. Accepts one of the following values ['hours', 'days', 'weeks', 'months']
      • start is an optional boolean field, false by default. Represents whether or not a request should be made at the time of registering the schedule.

      • storeResponseBody is an optional boolean field, false by default. Represents whether or not the response body should be stored while making request.

    • Returns - unique identfier for the created schedule.
      {
        "data": {
          "id": "88b6ba474b76df6ab866111fc3284ab0"
        },
        "meta": {}
      }
  2. Update Schedule - Allows updating the existing schedules based on their unique identifiers.

  • Endpoint - /v1/schedules/{{identifier}}
  • Method - PUT
  • Request body is similar to create schedule with the following exceptions:
    • start is not accepted.
    • In case you want to edit a request, storeResponseBody or period field, entire object needs to be sent. For example, for updating period from every 2 hours, to every 3 hours, request body would be:
      {
        "period": {
          "every": 3,
          "interval": "hours"
        }
      }
      Note Period changes would start reflecting from next cycle onwards.
  1. Get all schedules - Fetches all active schedules.
  • Endpoint - /v1/schedules
  • Method - GET
  • Returns - An array of all active schedules.
    {
      "data": [
        {
          "identifier": "64a623fd6b35f435dfb5fde03df2d4ed",
          "nextRunningTime": 1570435680068,
          "request": {
            "url": "http://localhost:3000/v1/blogs/29",
            "method": "GET",
            "data": {
              "params": {},
              "headers": {},
              "body": {}
            }
          },
          "period": {
            "every": 2,
            "interval": "hours"
          },
          "storeResponseBody": true
        }
      ],
      "meta": {
        "filter": "active"
      }
    }
  1. Get run history of schedule - Fetches all the run histories for the specified schedule.
  • Endpoint - /v1/schedules/{{identifier}}
  • Method - GET
  • Returns - An array of run history for the schedule.
    {
      "data": [
        {
          "id": 1,
          "runTime": 1570428480068,
          "responseStatusCode": 200,
          "responseBody": "hello i am a response body."
        }
      ],
      "meta": {}
    }
  1. Delete a schedule - Marks a schedule as inactive.
  • Endpoint - /v1/schedules/{{identifier}}
  • Method - DELETE

Contributing

Please refer to the issue tracker in case you'd like to contribute. Also, feel free to open feature requests/bug reports in case you face any.

noah's People

Contributors

deepakpathania avatar sagarchoudhary96 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

noah's Issues

Add functionality to pause/resume schedules

Since schedules are picked up based on nextRunningTime, a schedule can be considered paused for a cycle by simply updating their nextRunningTime to their next cycle's time.

For example, if a schedule was supposed to run every hour and the next invocation time is 1PM, if we update it to 2PM, it will not be picked up in the 1PM cycle and can be considered pasued for that duration.

Expose an endpoint that pauses the schedule based on this method for a given number of cycles.

Structure

  • POST /v1/schedules/{{identifier}}/pause
{
  "cycles": <int>
}

Similarly, expose an endpoint to resume a paused schedule. Resuming in this context would mean, simply calculating the nextRunningTime based on their original period and setting that as the new nextRunningTime for the schedule.

Structure

  • POST /v1/schedules/{{identifier}}/resume

Optionally allow storing response body in run history

Accept an optional parameter in the create schedule API to decide whether or not to store response bodies in run history (false by default.)

Add a column to the RunHistory model and start storing the response body in case the option was sent as true.

Add tests to verify request data fields resolve correctly

Add a bunch of unit tests to UtilService.test.js to ensure that different params when sent in the requestObject resolves to proper outbound requests.

One test per different field should be added:

  • query params.
  • headers
  • body

nock should be used to ensure the outbound call matches the expectation.

Add functionality to run a scheduled task now

There should be a separate endpoint that runs a scheduled task immediately, which means, it makes the outbound request on-demand.

This should also accept an optional parameter to decide whether or not nextRunningTime should be updated for this schedule based on this run, should be treated as false by default.

Structure

  • POST /v1/schedules/{{identifier}}/run
{
  updateNextRunningTime: true
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.