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

Ability to add timezone and extra user payload to calendar gateway #164

Merged
merged 1 commit into from
Feb 6, 2019

Conversation

VaibhavPage
Copy link
Contributor

No description provided.

@VaibhavPage VaibhavPage added the enhancement New feature or request label Feb 4, 2019
@VaibhavPage VaibhavPage added this to the v0.8 milestone Feb 4, 2019
@VaibhavPage VaibhavPage requested a review from magaldima February 4, 2019 20:49
Copy link
Contributor

@magaldima magaldima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other than one comment, lookds good


// UserPayload will be sent to sensor as extra data once the event is triggered
// +optional
UserPayload string `json:"userPayload,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason this is a string and not []byte ?

Copy link
Contributor Author

@VaibhavPage VaibhavPage Feb 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most probably user will put JSON string as UserPayload because it is the easiest way to parse it in workflow

@magaldima magaldima merged commit 74272fb into master Feb 6, 2019
@VaibhavPage VaibhavPage deleted the timezone-and-extra-payload-for-calendar-gateway branch February 18, 2019 12:58
@inteledyne
Copy link

i can't find any examples of how to pass this userpayload to the workflow that is triggered by the sensor.

@VaibhavPage
Copy link
Contributor Author

the example would be -


apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
  name: calendar-sensor
  labels:
    sensors.argoproj.io/sensor-controller-instanceid: argo-events
spec:
  template:
    spec:
      containers:
        - name: "sensor"
          image: "argoproj/sensor"
          imagePullPolicy: Always
      serviceAccountName: argo-events-sa
  dependencies:
    - name: "calendar-gateway:interval"
  eventProtocol:
    type: "HTTP"
    http:
      port: "9300"
  triggers:
    - template:
        name: calendar-workflow-trigger
        group: argoproj.io
        version: v1alpha1
        kind: Workflow
        source:
          inline: |
            apiVersion: argoproj.io/v1alpha1
            kind: Workflow
            metadata:
              generateName: calendar-workflow-
            spec:
              entrypoint: whalesay
              arguments:
                parameters:
                - name: message
                  # this is the value that should be overridden
                  value: hello world
              templates:
              - name: whalesay
                inputs:
                  parameters:
                  - name: message
                container:
                  image: docker/whalesay:latest
                  command: [cowsay]
                  args: ["{{inputs.parameters.message}}"]
      resourceParameters:
        - src:
            event: "calendar-gateway:interval"
            path: userPayload
          dest: spec.arguments.parameters.0.value

@inteledyne
Copy link

Love it, and is that userPayload set in the gateway? I'm testing a simple POC that involves passing static values to the same workflow for different cron schedules/sensors. Following is what I'm trying to do -

resourceParameters: - src: event: "calendar-gateway:interval" key: "sql_script" value: "[{ 'sqlfile': 'test_1.sql', 'schedulekey': 'recent_records' }]" dest: spec.arguments.parameters.0.value

@VaibhavPage
Copy link
Contributor Author

VaibhavPage commented Apr 4, 2019

That would be in gateway-configmap. e.g calendar gateway configmap would look like -


apiVersion: v1
kind: ConfigMap
metadata:
  name: calendar-gateway-configmap
data:
  interval: |-
    interval: 10s
    userPayload: "{\"hello\": \"world\"}"
  schedule: |-
    schedule: "30 * * * *"
    userPayload: {\"hey\": \"there\"}

To pass json as userPayload, you need to escape that json to get the string.

@inteledyne
Copy link

That works perfectly thank you.

@inteledyne
Copy link

If I want to have a 1-1 mapping between cron schedule and sensor, what is the best method? Maybe something like this?

apiVersion: v1 kind: ConfigMap metadata: name: calendar-gateway-configmap data: interval-recent-records: |- interval: 60s userPayload: "[{ \"sqlfile\": \"test_1.sql\", \"schedulekey\": \"recent_records\" }]" interval-next-unit-test: interval: 300s userPayload: "[{ \"sqlfile\": \"test_2.sql\", \"schedulekey\": \"recent_records\" }]" schedule: |- schedule: "10 * * * *"

Then in my sensor I have this?

resourceParameters: - src: event: "calendar-gateway:interval-recent-records" path: userPayload dest: spec.arguments.parameters.0.value

@inteledyne
Copy link

Is a completely separate configmap required for each unique interval associated with the calendar gateway?

@VaibhavPage
Copy link
Contributor Author

Gateway always has a single configmap that contains all the configurations.
Do you want to trigger the same workflow for different intervals/schedules or different workflows?

@inteledyne
Copy link

Different workflows, different intervals and schedules.

@inteledyne
Copy link

ScheduleA - 6pm
ScheduleA - Every 5 minutes
ScheduleB - 9am
Schedule C - 9am, weekdays only

@VaibhavPage
Copy link
Contributor Author

VaibhavPage commented Apr 4, 2019

Cool. Check these example out,

https://github.com/argoproj/argo-events/blob/master/examples/sensors/webhook-http-boolean.yaml
https://github.com/argoproj/argo-events/blob/master/examples/sensors/webhook-http-dependency-groups.yaml

Basically in your case, sensor will have four dependencies ScheduleA, B, C, D. Each dependency will belong to separate group and you would just OR these groups.

Why group dependencies? Because sensor acts as barrier waiting for receive events from one or more gateways. And historically it only supported ANDing the dependencies, so, basically waiting for all events to happen. In your case, you want to trigger workflows, if Schedule A or B or C or D happens, hence you group them and apply OR.

@inteledyne
Copy link

I got it working - here's my test -

image

@VaibhavPage
Copy link
Contributor Author

VaibhavPage commented Apr 4, 2019

So the sensor would look like ,


apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
  name: your-sensor
  labels:
    sensors.argoproj.io/sensor-controller-instanceid: argo-events
spec:
  template:
    spec:
      containers:
        - name: "sensor"
          image: "argoproj/sensor"
          imagePullPolicy: Always
      serviceAccountName: argo-events-sa
  # defines list of all events sensor will accept
  dependencies:
    - name: "calendar-gateway:interval_recent_records"
    - name: "calendar-gateway:interval_max_volume"
    - name: "calendar-gateway:schedule"
  # divides event dependencies into groups
  dependencyGroups:
    - name: "group_1"
      dependencies:
        -  "calendar-gateway:interval_recent_records"
    - name: "group_2"
      dependencies:
        - "calendar-gateway:interval_max_volume"
    - name: "group_3"
      dependencies:
        - "calendar-gateway:schedule"
  # either  "calendar-gateway:interval_recent_records" or "calendar-gateway:interval_max_volume" or  "calendar-gateway:schedule" happens
  circuit: "group_1 || group_2 || group3"
  eventProtocol:
    type: "HTTP"
    http:
      port: "9300"
  triggers:
    - template:
        when:
          all:
            - "group_1"
        name: trigger-1
        group: argoproj.io
        version: v1alpha1
        kind: Workflow
        source:
          inline: |
            apiVersion: argoproj.io/v1alpha1
            kind: Workflow
            metadata:
              generateName: hello-world-
            spec:
              entrypoint: whalesay
              templates:
                - name: whalesay
                  container:
                    args:
                      - "hello world"
                    command:
                      - cowsay
                    image: "docker/whalesay:latest"
      resourceParameters:
        - src:
            event: "calendar-gateway:interval_recent_records"
            path: userPayload
          dest: spec.arguments.parameters.0.value
    - template:
        when:
          all:
            - "group_2"
        name: trigger-2
        group: argoproj.io
        version: v1alpha1
        kind: Workflow
        source:
          inline: |
            apiVersion: argoproj.io/v1alpha1
            kind: Workflow
            metadata:
              generateName: hello-world-2-
            spec:
              entrypoint: whalesay
              templates:
                - name: whalesay
                  container:
                    args:
                      - "hello world"
                    command:
                      - cowsay
                    image: "docker/whalesay:latest"
      resourceParameters:
        - src:
            event:  "calendar-gateway:interval_max_volume"
            path: userPayload
          dest: spec.arguments.parameters.0.value
    - template:
        when:
          all:
            - "group_3"
        name: trigger-3
        group: argoproj.io
        version: v1alpha1
        kind: Workflow
        source:
          inline: |
            apiVersion: argoproj.io/v1alpha1
            kind: Workflow
            metadata:
              generateName: hello-world-2-
            spec:
              entrypoint: whalesay
              templates:
                - name: whalesay
                  container:
                    args:
                      - "hello world"
                    command:
                      - cowsay
                    image: "docker/whalesay:latest"

@VaibhavPage
Copy link
Contributor Author

VaibhavPage commented Apr 4, 2019

The sensor spec looks long because all workflows are inlined. You can actually store workflow definitions on git, s3, file, configmap etc and refer them. https://github.com/argoproj/argo-events/blob/master/docs/trigger-guide.md#how-to-define-a-trigger

@inteledyne
Copy link

Interesting, so this is essentially how you would define multiple sensor triggers in the same sensor reacting on multiple events coming from the gateway, firing different workflows.

As an alternative, you could also specify a separate sensor per trigger, each sensor pointing to a separate workflow, correct? I think this approach might make it easier to build out a dynamic workflow generation and deployment wrapper on top of it.

@inteledyne
Copy link

Also, I recognize there is probably not the right place to ask this question, but is there a way to run specific steps in a workflow, say in a triage situation for a data pipeline where the pipeline is partially processed?

@VaibhavPage
Copy link
Contributor Author

VaibhavPage commented Apr 5, 2019

yes, you can have a separate sensor that handles a single trigger.

About the workflow question, I would raise that in argo workflow project / slack channel

@janmasarik
Copy link

janmasarik commented Apr 20, 2019

Hey @VaibhavPage , 👋

What is the recommended way how to parse userPayload json in the workflow?

I would like to pass:

apiVersion: v1
kind: ConfigMap
metadata:
  name: calendar-gateway-configmap
data:
  interval-json: |-
    interval: 10s
    userPayload: "{\"domian\": \"argo.io\", \"another-param\": \"bar\"}"

and then, in workflow insert the domain and another-param to 2 different paramters, like this:

apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
  name: calendar-sensor
  labels:
    sensors.argoproj.io/sensor-controller-instanceid: argo-events
spec:
  template:
    spec:
      containers:
        - name: "sensor"
          image: "argoproj/sensor"
          imagePullPolicy: Always
      serviceAccountName: argo-events-sa
  dependencies:
    - name: "calendar-gateway:interval"
  eventProtocol:
    type: "HTTP"
    http:
      port: "9300"
  triggers:
    - template:
        name: calendar-workflow-trigger
        group: argoproj.io
        version: v1alpha1
        kind: Workflow
        source:
          inline: |
            apiVersion: argoproj.io/v1alpha1
            kind: Workflow
            metadata:
              generateName: calendar-workflow-
            spec:
              entrypoint: whalesay
              arguments:
                parameters:
                - name: message
                  # this is the value that should be overridden
                  value: hello world
                - name: another-message
                  value: plz-work
              templates:
              - name: whalesay
                inputs:
                  parameters:
                  - name: message
                  - name: another-message
                container:
                  image: docker/whalesay:latest
                  command: [cowsay]
                  args: ["{{inputs.parameters.message}}", "{{inputs.parameters.another-message}}"]
      resourceParameters:
        - src:
            event: "calendar-gateway:interval"
            path: userPayload.domian
          dest: spec.arguments.parameters.0.value
        - src:
            event: "calendar-gateway:interval"
            path: userPayload.another-param
          dest: spec.arguments.parameters.1.value

Btw, thanks a lot for your awesome work. I really enjoy learning argo-events and seeing how it grows every week! :-)

@VaibhavPage
Copy link
Contributor Author

VaibhavPage commented Apr 21, 2019

As userPayload is a string and not a JSON, you won't be able to access any particular substring using resourceParameters.

I would suggest that you pass the userPayload as the first argument to container command and then convert string to JSON in your process baked into the image.

The source would like following,


        source:
          inline: |
            apiVersion: argoproj.io/v1alpha1
            kind: Workflow
            metadata:
              generateName: calendar-workflow-
            spec:
              entrypoint: whalesay
              arguments:
                parameters:
                - name: message
                  # this is the value that should be overridden
                  value: hello world
              templates:
              - name: whalesay
                inputs:
                  parameters:
                  - name: message
                container:
                  image: <your image>  # It will convert userPayload string to JSON
                  command: [<your command>]
                  args: ["{{inputs.parameters.message}}"]
      resourceParameters:
        - src:
            event: "calendar-gateway:interval"
            path: userPayload
          dest: spec.arguments.parameters.0.value


@janmasarik
Copy link

Understood, that's actually what I expected, but still had a small hope that there is some nicer solution for this :-)

Thanks for the answer and your amazing work here!

juliev0 pushed a commit to juliev0/argo-events that referenced this pull request Mar 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants