Central

Amplify Central Agent Status Change Notifier

Amplify Central Agent Status Change Notifier

Amplify Central agents provide a powerful and seamless means to synchronize APIs in your API Gateways, whether they be the Axway Amplify API Gateway or those from Azure, AWS or Istio, into your Amplify Central Environments, and ultimately the Amplify Unified Catalog. This helps reduce API Sprawl and accelerates innovation by making the discovery and usage of APIs easier on the API consumer.

In order for all of this to work well, the agents need to be running and operational. The Amplify Central user interface exposes the current state of the agents as shown below, where you can see running and stopped discovery and traceability agents:

Agent State – Stopped
Agent State – Running

There are other agent operational states, failed and unhealthy. The complete list is shown below:

  • running – Agent passed all health checks and is up and running
  • stopped – Agent is not running
  • failed – Failed health checks
  • unhealthy – Agent is running but with health check failure

However, in order to proactively respond to issues related to agent operation, it would be great to have a way to be notified automatically when an agent’s state changes.

Recall that in a prior blog post, we described how Amplify’s Integration Webhooks help expand the capabilities of the platform by providing a means of monitoring the platform for various events. Recently, Axway added agents as one of the resource types that can be monitored and generate webhooks.

In this blog post, we’ll look at how to set up an integration webhook that monitors agent status changes. We’ll leverage another Amplify Platform component, Integration Builder, that will respond to the webhook, analyze the payload and send a message to Microsoft Teams.

In doing so, we will have created a notification system that can alert an operations team of potential issues or outages so that remediation can be applied proactively, instead of reactively based on customer feedback.

A sample message that we will create is shown below:

Sample MS Teams Agent Status Change Notification Message

While we used integration builder and MS Teams in this example, we could process the webhook with any application that can process an incoming webhook and send the notification to any messaging platform (slack, sms, …).

The steps required to implement this agent status change notifier are:

  • Configure an Amplify Central Integration Webhook
  • Create an app to process the resulting webhook and process the payload
  • Create an MS Teams message and send it to MS Teams (via MS Teams incoming webhook connector)

Setup Amplify Central Integration Webhooks

As described in a prior blog post, the following YAML file, agentstatuschangesint.yaml, describes an Integration Webhook:

n
name: agentstatuschangesint
kind: Integration
apiVersion: v1alpha1
title: Agents Status Changes Integration
tags:
- Agents
spec:
  description: Agents Status Changes Integration
---
name: agentstatuschangesintwhs
kind: Secret
apiVersion: v1alpha1
title: Agents Status Changes Integration Webhook Secret
metadata:
  scope:
    kind: Integration
    name: agentstatuschangesint
spec:
  data:
    apikey: User IPJ...NW4=,Organization 79....05
---
name: agentstatuschangesintwh
kind: Webhook
apiVersion: v1alpha1
title: Agents Status Changes Integration Webhook
attributes:
release: 1.0.0
metadata:
  scope:
    kind: Integration
    name: agentstatuschangesint
spec:
  enabled: true
  url: https://staging.cloud-elements.com/elements/api-v2/formulas/instances/4...0/executions
  auth:
    secret:
      name: agentstatuschangesintwhs
      key: apikey
---
group: management
apiVersion: v1alpha1
kind: ResourceHook
name: agentstatuschangesintrh
title: Agents Status Changes Integration Resource Hook
metadata:
  scope:
    kind: Integration
    name: agentstatuschangesint
spec:
  triggers:
    - group: management
      kind: DiscoveryAgent
      name: "*"
      scope:
        kind: Environment
        name: "*"
      type:
      - updated
    - group: management
      kind: TraceabilityAgent
      name: "*"
      scope:
        kind: Environment
        name: "*"
      type:
      - updated
  webhooks:
    - agentstatuschangesintwh

Here are some properties of the Integration Webhook described in the above YAML file starting from the bottom and working our way up:

  • It defines a resource hook, agentstatuschangesintrh, that is triggered on the following:
    • Any update (type = updated) to any discovery agent (name = *) and any traceability agent (name = *) in any environment (name = *)
  • When the resource hook is triggered, it will cause a webhook called agentstatuschangesintwh to be called
  • The webhook, agentstatuschangesintwh will POST its data to the url https://staging.cloud-elements.com/elements/api-v2/formulas/instances/4…0/executions which is an Integration Builder manual triggered flow instance
  • The webhook will include an authorization header (secret) called agentstatuschangesintwhs
  • The authorization header (secret), called agentstatuschangesintwhs defines the Integration Builder authorization header User IPJ…NW4=,Organization 79….05
  • The name of the Integration Webhook is agentstatuschangesint

To create this Integration Webhook using the above YAML file, we can use the Axway CLI as follows:

axway central create -f agentstatuschangesint.yaml

with the following response:

axway central create -f agentstatuschangesint.yaml
✔ "Integration/agentstatuschangesint" has successfully been created.
✔ "Secret/agentstatuschangesintwhs" in the scope "Integration/agentstatuschangesint" has successfully been created.
✔ "Webhook/agentstatuschangesintwh" in the scope "Integration/agentstatuschangesint" has successfully been created.
✔ "ResourceHook/agentstatuschangesintrh" in the scope "Integration/agentstatuschangesint" has successfully been created.

A sample webhook payload for when a traceability agent changes from unhealthy to running is shown below:

{
  "metadata": {
    "subresource": "status"
  },
  "product": "AmplifyCentral",
  "type": "SubResourceUpdated",
  "version": "v1",
  "payload": {
    "finalizers": [],
    "metadata": {
      "references": [],
      "audit": {
        "modifyUserId": "DOSA_50e7481fc643403cbc031315cfa013ab",
        "createUserId": "DOSA_50e7481fc643403cbc031315cfa013ab",
        "createTimestamp": "2021-02-24T17:53:43.231+0000",
        "modifyTimestamp": "2021-02-24T17:53:43.231+0000"
      },
      "resourceVersion": "94771",
      "scope": {
        "name": "aws",
        "id": "8a2e862d779860e20177a6888d450233",
        "kind": "Environment",
        "selfLink": "/management/v1alpha1/environments/aws"
      },
      "id": "8a2e942477a98b570177d52cdd3f26be",
      "selfLink": "/management/v1alpha1/environments/aws/traceabilityagents/cli-1613407416594"
    },
    "kind": "TraceabilityAgent",
    "title": "cli-1613407416594",
    "spec": {
      "logging": {},
      "config": {},
      "dataplaneType": "AWS"
    },
    "tags": [],
    "apiVersion": "v1alpha1",
    "name": "cli-1613407416594",
    "attributes": {},
    "group": "management",
    "status": {
      "latestAvailableVersion": "1.1.5",
      "sdkVersion": "1.1.8",
      "state": "running",
      "lastActivityTime": "2021-11-05T00:38:30.009+0000",
      "version": "1.1.5-e6d57638",
      "previousState": "unhealthy"
    }
  },
  "organization": {
    "id": "100000142"
  },
  "correlationId": "dc3b241c-4901-4519-a3c1-9d1fa8ad26d4",
  "id": "6016b6db-501b-4ac1-b3d8-7e1af34c1c94",
  "time": "2021-11-05T00:38:30.403+0000"
}

It’s worth noting that there will be other agent update webhooks generated as a result of the Integration Webhook. Not all will be relevant to status updates. The webhooks we want to process have the following properties:

  • type = “SubResourceUpdated”
  • metadata.subresource = “status”

It is also worth noting that payload.status.previousState can be used to determine if there is a state change but it’s not always present, particularly on startup when there is no previous state so we may need to check to see if this property exists before checking its value. More on this in the next section.

Integration Builder Flow

Our manual trigger Integration Builder flow is shown below:

Integration Builder Agent Status Change Notifier Flow

It is quite simple and the main part is the check to see if there is a state change before sending a message to MS Teams. This is the shouldProcess JS Filter (true/false) Step and is shown below:

const subresourceIsStatus = trigger.args.metadata.subresource === "status";
const typeIsSubResourceUpdated = trigger.args.type === "SubResourceUpdated";

// The isAgent check is superfluous and included in case the Integration Resource hook is not configured properly
const isAgent = trigger.args.payload.kind === "TraceabilityAgent" || trigger.args.payload.kind === "DiscoveryAgent";

const previousStateExists = trigger.args.payload.status.hasOwnProperty('previousState');

var isStateChanged = true;
if(previousStateExists) {
 isStateChanged = trigger.args.payload.status.state != trigger.args.payload.status.previousState;
}

done(subresourceIsStatus && typeIsSubResourceUpdated && isAgent && isStateChanged);

This step performs the following checks:

  • Is metadata.subresource = “status”?
  • Is type = “SubResourceUpdated”?
  • Is the webhook related to either the Discovery agent or Traceability agent?
  • Does the webhook relate to a state change?
    • There are two possibilities for this to be true:
      • If there is no previousState property
      • If there is a previousState property and it differs from the state property (e.g. state changed from unhealthy to running)

If all these are true, then a message is constructed and sent to MS Teams.

The other main step is the prepareSendToTeams JS Script Step that creates the MS Teams card body:

const url = config.msTeamsWebhookURL;

let apicentralUrl = config.apiCentralUrl ? config.apiCentralUrl : 'https://apicentral.axway.com';

let envURL = apicentralUrl+'/topology/environments/'+trigger.args.payload.metadata.scope.name;

let agentPrefix;

trigger.args.payload.kind === "TraceabilityAgent" ? agentPrefix = "Traceability" : agentPrefix = "Discovery"

const message = agentPrefix+" agent **"+trigger.args.payload.name+"** from Environment **"+trigger.args.payload.metadata.scope.name+"** has changed it's status to **"+trigger.args.payload.status.state+"**";

var suffix;
switch (trigger.args.payload.status.state) {
  case 'stopped':
    suffix = 'WARNING';
    break;
  case 'unhealthy':
    suffix = 'WARNING';
    break;
  case 'failed':
    suffix = 'ERROR';
    break;
  default:
    suffix = 'UPDATE';
}

let body = {
    "@type": "MessageCard",
    "@context": "http://schema.org/extensions",
    "themeColor": "0076D7",
    "summary": "Amplify Central Agent "+suffix,
    "sections": [{
        "activityTitle": "[**Amplify Central Agent**](https://docs.axway.com/bundle/amplify-central/page/docs/connect_manage_environ/index.html) "+suffix,
        "facts": [{
            "name": "Agent Name:",
            "value": trigger.args.payload.name
        },
        {
            "name": "Agent Type:",
            "value": agentPrefix
        },
        {
            "name": "Environment:",
            "value": '[**'+trigger.args.payload.metadata.scope.name+'**]('+envURL+')'
        }],
        "text": message,
        "markdown": true
    }]
};

done({body, url});

The output of this step is used in the sendToTeams HTTP Request Step:

sendToTeams HTTP Request Step

This step POSTS the body constructed in the prepareSendToTeams step to a URL for an MS Teams channel that has an incoming webhook connector configured.

The flow can be downloaded from here.

Some sample cards are shown below:

Sample MS Teams Notification
Sample MS Teams Notification
Sample MS Teams Notification

You can see that the MS Team message provides useful information about the status change of the agents. A link to the environment is included in the message so that you can click on it and log into the Axway Platform.

Summary

In this blog post, we saw how the openness and extensibility of the Axway Platform, namely Integration Webhooks, can be leveraged to create a notification service. This notification service can proactively alert your operations team to the potential issues related to your APIs.

Learn how to add headers to an integration webhook.