← Integration Academy

Production Pulse · 7 / 8

Share one signal-sending library

Consolidate scheduled, event-driven and manual signals behind one supplied Lua library.

YOUR TASK

Make this happen

3 steps
  1. Connect integration_actor_library.monitor to libraries in actor.cococo.

  2. Keep each supplied entry-point script: heartbeat, job.updated and manual.

  3. Update the Action output to a required boolean accepted field.

This lesson starts with the previous working solution. Build and connect the next capability. Your earlier drafts are kept separately.

Read the starter files

main.cococo

integration_document "monitor" {
  integrationId = "com.academy.monitor"
  sdkVersion = "2.0"
  version = "1.0.0"
  description = "A small heartbeat integration"
  resources = [integration_resource_requirement.monitor_service]
  policy = integration_policy.monitor
  apiClients = [integration_api_client.monitor]
  actor = integration_actor.monitor
}

actor.cococo

integration_actor "monitor" {
  subscriptions = [integration_actor_subscription.job_updates]
  actions = [integration_actor_action.status]
  timers = [integration_actor_timer.heartbeat, integration_actor_timer.daily_review]
}

timer.cococo

integration_actor_timer "heartbeat" {
  name = "heartbeat"
  schedule = { every = "5m" }
  jitter = "15s"
  source = "return { alive = true }"
}

events.cococo

integration_actor_subscription "job_updates" {
  topic = "job.updated"
  source = file("scripts/job-updated.lua")
}

actions.cococo

integration_actor_action "status" {
  name = "status"
  label = "Check production pulse"
  inputSchema = { type = "object", properties = {} }
  outputSchema = {
    type = "object"
    properties = { alive = { type = "boolean" } }
    required = ["alive"]
  }
  source = file("scripts/status.lua")
}

resources.cococo

integration_resource_requirement "monitor_service" {
  id = "monitor_service"
  type = "protocol/http"
  optional = false
  description = "HTTP device for the monitoring service"
}

policy.cococo

integration_policy_statement "devices" {
  effect = "ALLOW"
  actions = ["device:*"]
  resources = [integration_resource_requirement.monitor_service.id]
}

integration_policy "monitor" {
  statements = [integration_policy_statement.devices]
}

client.cococo

integration_api_client "monitor" {
  name = "monitor"
  schema = file("contracts/monitor.openapi.json")
  definition = file("contracts/monitor.api.xml")
}

daily.cococo

integration_actor_timer "daily_review" {
  name = "daily_review"
  schedule = { cron = "0 6 * * *" }
  source = "return { review = true }"
}

library.cococo

integration_actor_library "monitor" {
  name = "monitor"
  # TODO: add source — see the task above.
}
Supplied scripts and pinned contracts (read-only)

These fixtures explain the runtime behaviour being composed. They are included in validation but are not executed. The generated API definition is supplied, not an XML authoring task.

scripts/heartbeat.lua

local monitor = ctx.script.load("monitor")
return monitor.send("heartbeat")

scripts/job-updated.lua

local event, config = ...
local monitor = ctx.script.load("monitor")
return monitor.send("job.updated")

scripts/status.lua

local input, actionConfig = ...
local monitor = ctx.script.load("monitor")
return monitor.send("manual")

contracts/monitor.openapi.json

{
  "openapi": "3.0.3",
  "info": {
    "title": "Production Pulse",
    "version": "1.0.0"
  },
  "paths": {
    "/signals": {
      "post": {
        "operationId": "sendSignal",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "reason"
                ],
                "properties": {
                  "reason": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signal accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "accepted"
                  ],
                  "properties": {
                    "accepted": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

contracts/monitor.api.xml

<api-client name="monitor" schema-sha256="ff335ef17f27b04682e45ed20fc932d10c89dc2b37572defa7addf51129fa220"><operation id="sendSignal"/></api-client>

scripts/monitor.lua

local monitor = {}

monitor.send = function(reason: string)
  local client = ctx.api.get("monitor"):init(ctx.device.get("monitor_service"))
  local ok, response = client:sendSignal({ body = { reason = reason } })
  if not ok then
    error(response)
  end
  return { accepted = response.body.accepted }
end

return monitor