posted Sep 20, 2011, 5:38 PM by Eric Patrick   [ updated Sep 17, 2014, 9:51 AM ]



The QBO3 notification infrastructure will support use cases like:
  • Notify an attorney via a web service call when they have been assigned a task
  • Notify a user via email when a task has become overdue
  • Notify a Loan's investor when a child process changes status
  • Notify a Servicer when non-information-only messages are added to a child process
  • Notify a Broker when corrections are required
To support a highly scale-able system, the following concepts will be used:
  • Each QBO3 install will need to pre-define what notification events can be subscribed to based on business requirements
  • A data listener will be created for each notification event
  • The data listener will query the database, and for each row returned, call {ClassName}/Notify 
    • the parameters passed to notify will be the columns returned by the data listener query
    • the data listener query must return enough information to correctly route the notification
  • The Notify operation will queue the notification data to an SQS queue that is being monitored by
  • The will pop a notification from the SQS queue, gather a list of applicable subscriptions, and invoke the notification endpoint appropriately
  • Notification data should be short and sweet
    • including a task due date is reasonble
    • including the body of an updated document is unreasonble
    • including the BodyHtml of a Message is unreasonable
  • Notifications should include a ResourceUrl so a receiving system can decide if it wants to get more detail
    • e.g. a 'Document added' notification should include a link to Attachment.ashx/Download?ID=X
    • e.g. an 'Import complete' notification should include a link to ImportFile.ashx/Summary?ID=Y
Note: We brain stormed for quite some time about several aspects of this, and discarded the following concepts:
  • Using an app tier method instead of a data listener: this method cannot handle use cases like 'Task Overdue'; nor is it aware of bulk updated
  • Enable notifications on every possible event out of the box: too many edge cases break
  • Include full Summary data for each notification, so you can decide what to filter on later: this is too resource-intensive to scale well


The QLS system will need to support the following notifications:
  • Attorney Task Assignment (near real time): SELECT FROM ImportForm WHERE StepType = 'Attorney' AND ActualCompletion IS NULL
  • Attorney Task Overdue (daily): SELECT FROM ImportForm WHERE StepType = 'Attorney' AND ActualCompletion IS NULL AND ProjectedCompletion < GETDATE()
Assume the following subscriptions are requested
  • Trott & Trott wants task assignment notifications to route through a NetDirector interface
  • Trott & Trott wants task overdue notifications to route through email
  • Barrett Burke wants to poll us for task assignment notifications
  • Barrett Burke wants email notification of Foreclosure Sale tasks
For the Attorney Task Assignment event, the data submitted to the system must be robust enough to determine routing:
  • Task Name
  • Attorney Name
  • Due Date
  • Attorney Case Number
Thus, the data listener query supporting this notification event needs to look something like this:

  Organization.Organization AS Attorney,
  Process.Process AS CaseNumber,
  '{app:BaseUrl}Decision/ImportForm.ashx/Summary?ID={ImportFormID}' AS ResourceUrl
FROM ImportForm
  INNER JOIN Process
    ON Process.ProcessID = ImportForm.ObjectID
  INNER JOIN Organization
    ON Organization.OrganizationID = Process.AssignedOrganizationID
  Importform.UpdatedDate > @FromDate

From the QBO site's perspective, it will deliver EVERY new task to the site.  It will be up to to filter the results to the correct subscribers appropriately. For example:
  • Trott & Trott:
    • Filter: ImportForm LIKE '%'
    • DeliveryMethod: NotifyNetDirector (HttpNotification plugin)
  • Barrett Burke:
    • Filter: ImportForm LIKE '%'
    • DeliveryMethod: NotifyBarrettBurke (SQS plugin)
  • Barrett Burke:
    • Filter: ImportForm LIKE 'Foreclosure Sale Held'
    • DeliveryMethod: NotifyBarrettBurkeByEmail (Email Plugin)

Data Listeners

When configuring a data listener, care must be taken to ensure the data listener query does not cause data contention. The standard pattern will include:
  • The table being queried should contain a conditional index based on {Table}.UpdatedDate
    • This index should be rebuilt every week as part of weekend maintenance
  • The data listener should be tied to a schedule, so when it runs, the query can use the @FromDate parameter to filter with UpdatedDate > @FromDate