Push Notifications

General

Certain system events generate events. When configured, notification of events is published to all involved endpoints.

The notification consists of a URL pointing to the resource that was updated. The expectation is that consumers of these notifications will then use that URL to discover the data that changed and associate it back to their local resources as appropriate.

Mapping/configuration

The mapping between system events and the authenticated endpoints to which they are sent is configured in the admin section of the application. Some functions of which may be limited to Decisiv professional services.

Authentication

All requests must be transmitted over HTTPS.

Supported schemes

  • HTTP Basic Authentication

Future schemes

  • URI encoded authentication token
  • OAuth
    • token may not expire

Delivery failure

Configurable options for failure handing include: - timeout (default: 5 seconds)

At the point that the retry limit(5 attempts) is hit, an email indicating the failure and including the message will be sent to the profile user’s email address.

Implications

Read consensus problem

Multiple consuming processes (A)

Notifications may be issued in order in our system and may be processed in a different order in consuming systems. This is most likely due to multiple processes consuming the notifications.

  • Example 1: A case is created from the Decisiv Case UI, generating a case create and note create notification (textual complaints are turned into notes). They are issued in order, but because of network delays the note creation notification is processed before the case creation notification is processed.
  • Example 2: A case might be created such that a case creation notification is issued within ms of (1 or more) case update notifications. Even if issued in order, the update may be in-process before the creation.

Delivery failures (B)

Notifications may be issued out of order in some scenarios due to timed-out notifications being retried.

  • Example 1: a case creation notification is issued and times out. During the retry interval a note creation notification is issued for a case the consuming system doesn’t know about.
  • Example 2: a case creation notification is issued and times out. During the retry interval a case update notification is issued for a case the consuming system doesn’t know about.

Mitigation

What doesn’t work
  1. A consuming system might use a single process (and thread) to consume notifications. This wouldn’t prevent delivery failures from causing out of order messages.
  2. A consuming system might disable retries (by asking Decisiv CSO to change the setting). This would mean either processing failure emails to retrieve missed updates or accept data loss. The latter case is clearly unacceptable. The former case would still require the consuming system to decide when to read the data from the Decisiv API.
  3. A combination of the above still lacks consensus.
Potential solutions

These require the consensus algorithm to (1) have a way to share a resource lock across processes and (2) have enough knowledge of the Decisiv API structure.

Consider A1 from above: heterogenous concurrent notifications.

When a process (P1) in the consuming system retrieves the note message it might realize that it doesn’t have the case. It then might attempt to lock on the case resource (identifier or URL). If it succeeds it can pull the case into the system and create the note for the create note notification. If the lock is already held it might be due to another process (P2) pulling the case into the system. When P2 releases the lock, then P1 can check the existence of the case and either proceed with case creation or skip to creating the note.

To make the API navigtion easier, we might consider adding the parentResourceURL to notifications that have them.

Consider A2 from above: homogenous concurrent notifications.

Assume the update is being processed ahead of the case create.

A similar locking strategy to what was just described could be used, but treating an update for an unknown case as a create. This along with tracking “last retrieved” metadata could allow the subsequent case creation message to be safely ignored.

Notification format

All notifications send a variation of the same message.

Example Responses

Attachment updated

<?xml version="1.0" encoding="UTF-8"?>
<pushNotification xmlns="http://www.decisiv.net/platform_api/0.0.7/Case/PushNotification"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.decisiv.net/platform_api/0.0.7/Case/PushNotification">
    <resourceURL>http://api.decisiv.net/cases/1234/attachments/456</resourceURL>
    <resourceIdentifier>456</resourceIdentifier>
    <resourceType>Attachment</resourceType>
    <eventType>Update</eventType>
    <generatedAt>2006-05-04T18:13:51.0</generatedAt>
</pushNotification>

Case created

<?xml version="1.0" encoding="UTF-8"?>
<pushNotification xmlns="http://www.decisiv.net/platform_api/0.0.7/Case/PushNotification"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.decisiv.net/platform_api/0.0.7/Case/PushNotification">
    <resourceURL>http://api.decisiv.net/cases/1234</resourceURL>
    <resourceIdentifier>1234</resourceIdentifier>
    <resourceType>Case</resourceType>
    <eventType>Create</eventType>
    <generatedAt>2006-05-04T18:13:51.0</generatedAt>
</pushNotification>

Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
           xmlns:pn="http://www.decisiv.net/platform_api/0.0.7/Case/PushNotification"
           targetNamespace="http://www.decisiv.net/platform_api/0.0.7/Case/PushNotification">
    <xs:element name="pushNotification" type="pn:PushNotification"/>
    <xs:complexType name="PushNotification">
        <xs:all>
          <xs:element name="resourceURL" type="xs:string"/>
          <xs:element name="resourceIdentifier" type="xs:string"/>
          <xs:element name="resourceType" type="pn:ResourceTypes"/>
          <xs:element name="eventType" type="xs:string" minOccurs="0"/>
          <xs:element name="generatedAt" type="xs:dateTime"/>
        </xs:all>
    </xs:complexType>
    <xs:simpleType name="ResourceTypes">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Case"/>
            <xs:enumeration value="Attachment"/>
            <xs:enumeration value="CaseNote"/>
            <xs:enumeration value="Customer"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

Available Events

Notes

  • Created

Created and updated are one and the same for notes in our system, as they are immutable once created.

Case

  • Updated
  • Created

There might be other events that are useful for cases. We are open to adding more as their worth is demonstrated.

Attachments

  • Created

Future Events

Customer

  • Updated
  • Created