Introduction
In this article, I will introduce you to Boomerang Framework and show how it can help you build notification/communication solutions.
Boomerang is a notification framework for professional developers and integrators providing rock solid service oriented infrastructure and rapid development interface.
Background
In corporate environments, there is an eternal need to automate and improve business processes and information management. IT shops everywhere are asked to do more, faster, with less or unchanged amount of resources.
Just about every development project that we have come across demanded notification, communication or distribution of information, ranging from a simple printout in a shipping application to complex email thread handling in a tech support center.
With these insights, we set out to build a notification/communication framework that is flexible, fast and dependable and that takes the complexity out of the equation. We also wanted to provide a service oriented structure for easy management of all notifications/communications solutions once deployed.
About Boomerang
Boomerang is a software framework providing communication services for distribution through e-mail, printers, fax devices and file channels. Boomerang alleviates integration by offering a simple SQL database interface to developers and system integrators. Boomerang blends easily with Microsoft SQL Reporting Services. It was designed and developed by IT professionals for IT professionals. As simple as it gets, all you need is to insert records into ubiquitous SQL tables in order to make Boomerang "talk".
The heart of Boomerang comprises a set of heavy-duty background Windows services which can quickly and efficiently process thousands of output tasks on the daily basis. Each service is multi-threaded and caters specific output kind. There is one service for print, one for e-mail, one for fax, and one for file tasks. Services work independently from each other, although one Boomerang task may comprise several kinds of output. The following picture depicts architecture of Boomerang services.
Boomerang services implement pull technique, i.e. database tables are polled on specific time interval set independently for each delivery service.
Working with Boomerang
Interaction from your application with Boomerang services is done via database interface. This implies that any programming language can be used as long as it provides support to Microsoft SQL Server. You communicate with Boomerang in exactly the same way, be it either ASP.NET application, or bar-code device running a Mobile OS, or TomCat application connecting over Ruby on Rails, such as Confluence.
Boomerang Objects
The unit of work implemented by Boomerang is called event. You can think of event as an application task. An event is represented by a single record in the EVENT_MASTER
table. These event records do not carry delivery data, however they may carry application specific keys used to tie events to sources which generated them. Examples of such keys may include a helpdesk id, an application source id, a customer order number, a client lead unique identifier, etc.
Each event comprises one or more jobs. A job represents the actual unit of delivery, such as e-mail, or print. Each job declares delivery data of its own kind. For example, a print job will define at the minimum an applicable printer path. Although several jobs make up a single event, no specific order is guaranteed in which the jobs will fire. Because of multi-threaded nature of Boomerang services, chances are they will fire all at once as soon as the corresponding event record is marked "ready".
Some jobs may extend data to one or more auxiliary tables. For example, e-mail jobs list target recipients in a separate table called OUT_EMAIL_RECEPIENT
.
Many jobs will have content or attachments for which a common storage table is designed and called EVENT_CONTENT
. For example, a fax job may be set to deliver a Microsoft SQL Reporting Services report by means of facsimile transmission, in which case the event content table would feature corresponding URL path, where a RDL report has been deployed.
Each job maintains its own status and repetition schedule in a table called EVENT_STATUS
. Such schedule defines whether or not a job should fire immediately or wait for a certain time delay. Also it defines whether or not the job should be retried or not in case of failure, and, if so, then also a number of times and interval.
As jobs are processed, an event log is being generated regardless of completion outcome. Some jobs establish a feedback mechanism with target device. For instance, the fax service will alternate job status based on notifications it receives from Microsoft Fax Server. The e-mail service will listen to delivery reports from SMTP relay agent and will log them associated with original e-mail job.
The illustration below depicts how various Boomerang objects (with tables they are hosted by) fit together.
You may find a full description of Boomerang database at Fuel9 web site, which is provided at the bottom of this article.
Basic Process
The process below demonstrates how to create a Boomerang distribution in 4 simple steps. Just follow me, here we go.
Create Event | Step 1
In the first step, you create a new task record. Simply insert a new row in table EVENT_MASTER
. The only required field in EVENT_MASTER
is the gKey (uniqueidentifier). This record will tie output jobs together as we'll see in further steps. There are several columns in EVENT_MASTER
that you may use to help you organize and manage different tasks. In this example, we will use Created_By and Str1.
E.g.:
declare @gKey uniqueidentifier; set @gKey = newid();
Insert EVENT_MASTER (gKey, Created_By, Str1)
values (@gKey, 'domain\username', 'Weekly Sales Report')
Another useful field could be Source. If you maintain a list of applications in your environment with unique integer id for each, the Source column is an ideal candidate to reference your applications.
In the above example, we declared a local T-SQL variable @gKey of certain type and assigned it a value by means of the built-in T-SQL newid() function. We will need this variable in the steps below. If you are a beginner with T-SQL, you may find a lot of useful articles explaining T-SQL variables by searching this web site.
Create Job | Step 2
In the second step, you select destination, i.e. e-mail, or printing, or faxing, etc. As discussed above, this will be referred to as job. Depending on the job destination, you insert the new job into an appropriate table. The following are your options: OUT_EMAIL
, OUT_FAX
, OUT_FILE
or OUT_PRINT
. While fields vary slightly depending on the destination nature, the job key jKey and the event key gKey are common. In this example, we have chosen to send an e-mail.
E.g.:
declare @jKey uniqueidentifier; set @jKey = newid();
insert OUT_EMAIL (gKey, jKey, [ReplyTo], [From], Subject, Body)
values (@gKey, @jKey, 'Boomerang_account@domain.com',
'"e-mail display name" <Boomerang_account@domain.com>',
'Weekly Sales Report', 'Message body test test test' )
Since this is an e-mail job, we also need to add recipients to it. You do this by adding one or more rows to OUT_EMAIL_RECEPIENT
. An optional Type column designates recipient as either To (default), Cc, or Bcc. E-mails can be represented either by simple SMTP address or full SMTP notation, i.e. "name" <email@domain.com>. Don't forget to pass along the job reference key jKey.
E.g.:
insert OUT_EMAIL_RECEPIENT (jKey, [Email])
values (@jKey, 'e-mail_address@domain.com')
Add Content | Step 3
Albeit optional, a SQL Reporting Services report can be easily attached to our e-mail. You do this by adding one or more rows to EVENT_CONTENT
. Multiple attachments may be added. Akin jobs and events, attachments are too identified by key aKey. Should you add multiple attachments, consider passing along the same gKey and jKey you've used in the above steps. EVENT_CONTENT
is designed to accommodate different kinds of jobs, i.e. e-mail, fax, print and file out.
E.g.:
declare @aKey uniqueidentifier; set @aKey = newid();
insert EVENT_CONTENT (gKey, jKey, aKey, Src_Type, Path, [Format])
values (@gKey, @jKey, @aKey, 2, 'SALES/Weekly Sales Report', 'PDF' )
By default, the report will attach itself as a file to your e-mail. To render report in-line with HTML body, pass 0 (zero) to an optional IsAttachment column of EVENT_CONTENT
table.
Should the report require input parameters to control its content, add these into CONTENT_PARAMETER
.
E.g.:
insert CONTENT_PARAMETER (aKey, [Name], [Value]) values (@aKey, 'Week', '12')
Release Task | Step 4
The last step is to release our task for processing. This is done simply by updating flag in EVENT_MASTER
. When record was inserted in step 1, the Status column defaulted to -1 (negative one). This indicated to Boomerang services that our event is a work in progress and hence should be ignored for the time being. It is now time to set Status value to 0 (zero).
E.g.:
update EVENT_MASTER set Status=0 where gKey=@gKey
Entire Process
The whole thing put together would look something like this:
declare @gKey uniqueidentifier; set @gKey = newid();
declare @jKey uniqueidentifier; set @jKey = newid();
declare @aKey uniqueidentifier; set @aKey = newid();
Insert EVENT_MASTER (gKey, Created_By, Str1)
values (@gKey, 'domain\username', 'Weekly Sales Report');
insert OUT_EMAIL (gKey, jKey, [ReplyTo], [From], Subject, Body)
values(@gKey, @jKey, 'Boomerang_account@servername.domain.com',
'"e-mail display name" <Boomerang_account@domain.com>',
'Weekly Sales Report', 'Message body test test test');
insert OUT_EMAIL_RECEPIENT (jKey, Email)
values (@jKey, 'e-mail_address@domain.com');
insert EVENT_CONTENT (gKey, jKey, aKey, Src_Type, Path, [Format])
values (@gKey, @jKey, @aKey, 2, 'SALES/Weekly Sales Report', 'PDF');
insert CONTENT_PARAMETER (aKey, [Name], [Value])
values (@aKey, 'Week', '12');
update EVENT_MASTER set Status=0 where gKey=@gKey;
The attachment to this article contains a more comprehensive list of examples with explanation for various options.
Stored Procedures
Although not required by Boomerang, stored procedures are known as a convenient way to encapsulate business logic. They may reside in Boomerang database or other databases of choice, and can either be invoked by database triggers, or run on SQL Agent schedule, or be called directly from your application. Please refer to Microsoft SQL Server documentation, or article on this site on how to manage stored procedures.
Event Scheduling
Boomerang jobs may be set to delay their processing in time or to retry upon unsuccessful attempt. This behavior defaults to service settings, however may be individually tuned for each job via EVENT_STATUS
table.
Alternatively, you may use any available scheduling tool, such as Microsoft SQL Server Agent. For more information on Microsoft SQL Agent, please refer to Microsoft SQL Server documentation.
Boomerang Configuration
Boomerang services ship with Microsoft Management Console snap-in. You can use snap-in to configure important service parameters, as well as Boomerang database. You may also manage Boomerang printers and attached fax servers. Boomerang MMC snap-in is provided for your convenience, although it is not required to configure Boomerang services.
Boomerang configuration component is implemented as a DCOM Windows service. You can perform virtually any Boomerang configuration task in XML format by means of a scripting language which supports Automation. Please stay tuned for another article on how to configure Boomerang Services from scripting languages.
Many Boomerang Service parameters can also be configured directly by manipulating SYSTEM_VARS
table, which in some cases may require restart of corresponding Boomerang services.
Monitoring Events
You can monitor progress of your tasks by checking either with EVENT_STATUS
, which holds last job state, or by looking into the EVENT_LOG
table. There are 4 key fields which help you identify the state of your task.
Table | Column | Value | Comments |
---|
EVENT_STATUS | Status | 0 | job is ready and is pending processing |
1 | job completed successfully |
2 | job completed with errors |
3 | job is in progress |
EVENT_STATUS | Closed | 0 | job is still open and may either be pending or in progress |
1 | no further processing will be done with the job |
EVENT_LOG | Type | 0 | indicates success |
1 | indicates logical error, such as missing recipient, or printer path |
2 | indicates system error, for example interruption during SMTP transmission, or lost connection to Boomerang database |
EVENT_LOG | Message | (text) | description of error, or successful completion |
Contrary to system errors (Type=2), jobs resulted in logical error (Type=1) will not be retried no matter what and any arbitrary settings in EVENT_STATUS
will be ignored.
The following T-SQL example demonstrates how you can obtain a summary for each event:
begin
declare @d datetime, @nxt datetime, @st int, @r int, @files int, _
@emails int, @prints int, @faxes int, @info varchar(4000);
set @info = '';
select @d = max(isnull(s.Processed_On,'')),
@st = max(isnull(s.Status,0)),
@r = max(isnull(s.Tried_Times,0)),
@nxt = max(isnull(s.Run_When,'')),
@files = sum(isnull(fl,0)),
@emails = sum(isnull(e,0)),
@prints = sum(isnull(p,0)),
@faxes = sum(isnull(fx,0))
from EVENT_MASTER m
left join EVENT_STATUS s on s.gKey=m.gKey
left join
(
select jKey,1 fl,0 e,0 p,0 fx from OUT_FILE union all
select jKey,0 fl,1 e,0 p,0 fx from OUT_EMAIL union all
select jKey,0 fl,0 e,1 p,0 fx from OUT_PRINT union all
select jKey,0 fl,0 e,0 p,1 fx from OUT_FAX
) t on t.jKey=s.jKey
where m.gKey=@gKey
group by m.gKey;
if( @files>0 ) set @info = @info + convert(varchar(10),@files) + ' files, ';
if( @emails>0 ) set @info = @info + convert(varchar(10),@emails) + ' e-mails, ';
if( @prints>0 ) set @info = @info + convert(varchar(10),@prints) + ' prints, ';
if( @faxes>0 ) set @info = @info + convert(varchar(10),@faxes) + ' faxes, ';
set @info = @info + case
when (@d is null) then '-'
when @st in (1) then 'last on ' + convert(varchar(50),@d,0)
when @st in (2) then 'last on ' + convert(varchar(50),@d,0) + ', _
tried ' + convert(varchar(10),isnull(@r,0)) + ' times'
when @st in (0,3) then 'last on ' + convert(varchar(50),@d,0) + ', _
tried ' + convert(varchar(10),isnull(@r,0)) + ' times' + ', _
next retry ' + convert(varchar(50),@nxt,0)
else '-' end;
select @info
end
References
History
- 27th September, 2010: Initial post