The Common Alerting Protocol (CAP) is a simple, standardized XML data format used by the United States Department of Homeland Security, the United States Geological Survey (USGS), the Government of Canada, and many other organizations to exchange information about a broad range of warnings and emergencies (see Resources for a list of companies and organizations using CAP).
The CAP standard defines a type of document called an alert, which is used to exchange information about geological, meteorological, public health and safety, rescue, law-enforcement, environmental, transportation, infrastructure, and terrorist warnings and events. Such alerts can be generated either manually by incident responders or automatically by monitoring and sensing equipment, and they can be distributed using a variety of means. Syndication formats such as Atom and RSS comprise one distribution channel for CAP alerts that's growing in popularity.
The Atom Publishing Protocol, sometimes known as the Atompub protocol, is a mechanism to publish and manage collections of resources using the basic HTTP GET, POST, PUT, and DELETE operations. While originally designed as a way to post new entries to weblog software, the Atompub protocol is well suited as a way to manage nearly any kind of Web-based content. In this article, I present an example Java™ Web application that uses the Atom Publishing Protocol to publish and distribute CAP alerts.
Introducing the Common Alerting Protocol
The structure of a CAP alert document consists of a single
<alert /> element, which contains one or
more <info /> elements that provide detail
about a situation. Within each <info />
element is a collection of simple metadata elements and a number of
<resource /> and <area />
elements that provide additional information, such as links to photographs
and documents or map coordinates of areas affected by the alert. It's not
unusual for a single incident to produce many alert documents tracking the
evolution of the emergency situation. Listing 1 shows an example CAP alert.
Listing 1. An example child-abduction alert from the CAP V1.1 specification
<?xml version = "1.0" encoding = "UTF-8"?>
<alert xmlns = "urn:oasis:names:tc:emergency:cap:1.1">
<identifier>KAR0-0306112239-SW</identifier>
<sender>KARO@CLETS.DOJ.CA.GOV</sender>
<sent>2003-06-11T22:39:00-07:00</sent>
<status>Actual</status>
<msgType>Alert</msgType>
<source>SW</source>
<scope>Public</scope>
<info>
<category>Rescue</category>
<event>Child Abduction</event>
<urgency>Immediate</urgency>
<severity>Severe</severity>
<certainty>Likely</certainty>
<eventCode>
<valueName>SAME</valueName>
<value>CAE</value>
</eventCode>
<senderName>LOS ANGELES POLICE DEPT - LAPD</senderName>
<headline>AMBER ALERT</headline>
<description>DATE/TIME: 06/11/03, 1915 HRS. VICTIM(S): KHAYRI DOE JR.
M/B BLK/BRO 3'0", 40 LBS. LIGHT COMPLEXION. DOB 06/24/01. WEARING RED
SHORTS, WHITE T-SHIRT, W/BLUE COLLAR. LOCATION: 5721 DOE ST.,
LOS ANGELES, CA. SUSPECT(S): KHAYRI DOE SR. DOB 04/18/71 M/B, BLK HAIR,
BRO EYE. VEHICLE: 81' BUICK 2-DR, BLUE (4XXX000).</description>
<contact>DET. SMITH, 77TH DIV, LOS ANGELES POLICE
DEPT-LAPD AT 213 485-2389</contact>
<area>
<areaDesc>Los Angeles County</areaDesc>
<geocode>
<valueName>SAME</valueName>
<value>006037</value>
</geocode>
</area>
</info>
</alert> |
In this example, you can see most of the primary components of a typical CAP alert. The following is a list of the typical alert elements:
- Unique
<identifier />and<sender />: Together, these elements make it possible to uniquely identify every alert. The current CAP standard is somewhat ambiguous on whether<identifier>must be globally unique or just unique within the context of a specific<sender />. However, it's very clear that the value of<sender />must be globally unique. - Sent timestamp: This IS0 8601-formatted date and time specifies when the alert document was transmitted.
- Disposition: The
<status />,<msgType />, and<scope />elements describe the specific nature of the alert document:- Status: An alert document can describe an actual event, an exercise, a system-to-system communication, a test, or a draft.
- Message Type: An alert document can be an initial notification, an update, a cancellation of a previous alert, an acknowledgment that a previous alert was received, or an error notification describing why a previously received alert has been rejected.
- Scope: An alert document can be intended for distribution to the general public, to restricted audiences on a need-to-know basis, or to a limited and specific private group.
The following is a list of typical info elements:
- Category: Every alert falls into one of several general categories, including geological, meteorological, public health or safety, rescue, law enforcement, and so on.
- Description: The info element contains textual information describing the event, the recommended response, instructions, contact information, links to more information, and so on.
- Disposition: The
<urgency />,<severity />, and<certainty />elements provide information on the importance and impact of the situation:- Urgency: The urgency of a situation can be immediate, expected, past, in the future, or unknown.
- Severity: The severity of a situation can be extreme, severe, moderate, minor, or unknown.
- Certainty: The certainty of a situation can be observed, likely, possible, unlikely, or unknown.
- Timestamps: Situations described by an alert can have timestamps indicating the onset of the situation, the date and time when the information becomes effective, and the date and time when the information expires.
Resource elements describe resources such as photographs, documents, and measurements that accompany the situation report. For instance, a law-enforcement alert might include photographs of the suspect or victim, photographs of the suspect's vehicle, and so on. A resource can either be linked through a URL or included directly within the alert as Base64-encoded text.
Area elements describe the geographical areas affected by the alert. These elements can include detailed geological coordinates described either as circles or polygons with precise map coordinates, or they can be simple and generalized text descriptions.
For added security, CAP alerts can include XML digital signatures and can be encrypted using XML Encryption.
Creating and consuming CAP alerts
The first step to implementing a CAP-based application is to provide a means to produce and parse the alert documents. You can use any XML library, and several Java libraries currently exist for working with CAP alerts. In the example presented here, I use the Apache Abdera project to take advantage of Abdera's built-in support for digitally signed and encrypted documents. Abdera makes it easier to implement the Atom Publishing Protocol endpoint. Later, I'll show you how to use that endpoint to publish and manage alerts. You can learn more about Abdera by visiting its Web site (see Resources).
The example provides a set of interfaces and classes that provide complete access to the content of an alert document. The full source of the CAP implementation is included in the downloadable .zip file included with this article. To download the source code, see Download later in this article.
Listing 2 demonstrates how to create an alert document with a single <info /> element.
Listing 2. Creating CAP alerts with Apache Abdera
Abdera abdera = new Abdera();
Factory factory = abdera.getFactory();
Alert alert = (Alert) factory.newElement(CAP_ALERT);
alert.setIdentifier("ABC123DEF456");
alert.setSender("jasnell@example.org");
alert.setSent(new Date());
alert.setStatus(Alert.Status.Actual);
//...
Info info = alert.addInfo();
info.setCategories(Info.Category.Geo);
info.setEvent("Something happened");
info.setUrgency(Info.Urgency.Past);
info.setSeverity(Info.Severity.Extreme);
//... |
Listing 3 demonstrates how to parse a CAP alert document and access the information it contains.
Listing 3. Parsing CAP alerts with Apache Abdera
Abdera abdera = new Abdera();
Parser parser = abdera.getParser();
InputStream in = ... // get the input stream
Document<Alert> doc = parser.parse(in);
Alert alert = doc.getRoot();
System.out.println(alert.getIdentifier());
System.out.println(alert.getSender());
System.out.println(alert.getSent());
System.out.println(alert.getStatus());
//...
for (Info info : alert.getInfo()) {
System.out.println(info.getEvent());
//...
} |
Because the CAP implementation is based on Abdera, it inherits many useful
features, such as the ability to serialize to XML directly using the toString()
and writeTo(...) methods, and more importantly, the ability to support XML
digital signatures to sign alert documents.
A digitally signed CAP alert allows recipients to verify the authenticity of that alert. When dealing with situations of public safety, such safeguards are critical to ensure that the alert-distribution system is not abused.
To sign an alert using the example implementation requires the optional
Abdera security module, a private key suitable for producing digital
signatures, and an X.509 certificate containing the public key used to verify
the signature. Listing 4 illustrates the process. The call
to getSignatureOptions(...) prepares the private
key and X.509 certificate for the signing process.
Listing 4. Digitally signing a CAP alert
Abdera abdera = new Abdera(); //... create the Alert document AbderaSecurity absec = new AbderaSecurity(abdera); Signature sig = absec.getSignature(); SignatureOptions sigoptions = getSignatureOptions(sig); doc = sig.sign(doc.getRoot(), sigoptions).getDocument(); |
After signing, the alert document includes an enveloped signature that contains the X.509 certificate, as you can see in Listing 5.
Listing 5. The digitally signed CAP alert
<alert xmlns="urn:oasis:names:tc:emergency:cap:1.1">
<identifier>ABC123DEF456</identifier>
<sender>jasnell@example.org</sender>
<sent>2007-06-30T19:15:32.468Z</sent>
<status>Actual</status>
<info>...</info>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />
<ds:Reference URI="">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
...
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</alert> |
The digital signature ensures that if any part of the alert is modified after the signature is generated, the signature will become invalid. If the signature is valid, and if the X.509 certificate included in the signature is trusted, recipients can generally assume that the alert is authentic, or at the very least has not been modified by a third party.
A signed alert that includes an X.509 certificate contains all of the information necessary to validate the signature, as illustrated in Listing 6.
Listing 6. Verifying a digitally signed CAP alert
Abdera abdera = new Abdera(); //... parse the Alert document AbderaSecurity absec = new AbderaSecurity(abdera); Signature sig = absec.getSignature(); boolean isValid = sig.verify(doc.getRoot(),null); |
The example application requires that all CAP alerts published through the Atom Publishing Protocol include a valid digital signature. Further, it redistributes those alerts in such a way that the signature continues to be valid after publishing.
Alerts often contain confidential information that only certain individuals with proper authorization should access. While you can ensure the confidentiality of an alert in many ways, the CAP specification explicitly calls out support for XML Encryption. The sample application presented here doesn't make use of encrypted documents, but the Abdera-based implementation can handle such encryption easily, as illustrated in Listing 7.
Listing 7. Encrypting a CAP alert
Alert alert = //... create the CAP Alert
String jceAlgorithmName = "AES";
KeyGenerator keyGenerator =
KeyGenerator.getInstance(jceAlgorithmName);
keyGenerator.init(128);
SecretKey key = keyGenerator.generateKey();
AbderaSecurity absec = new AbderaSecurity(abdera);
Encryption enc = absec.getEncryption();
EncryptionOptions options = enc.getDefaultEncryptionOptions();
options.setDataEncryptionKey(key);
// Encrypt the document using the generated key
Document enc_doc = enc.encrypt(alert.getDocument(), options); |
In this example, the alert document is encrypted using a symmetric key that the receiving party must know to decrypt the document. This is done here only to simplify the example. Asymmetric key encryption using public/private key pairs or key-exchange methods such as Diffie-Hellman are also possible and in some cases are recommended. The result of the code in Listing 7 is an encrypted XML document as shown (in an abbreviated form) in Listing 8.
Listing 8. An encrypted CAP alert
<?xml version='1.0' encoding='utf-8'?>
<xenc:EncryptedData
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
Type="http://www.w3.org/2001/04/xmlenc#Element">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<xenc:CipherData>
<xenc:CipherValue>...</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData> |
It is strongly recommended that you digitally sign alert documents before you encrypt them to avoid a number of potential attacks in which encrypted data can be modified without requiring the attacker to break the cipher.
Now that you have a way to create and parse alert documents, you need a means to publish and manage them. For this, you can turn to the Atom Publishing Protocol.
Atompub is based around collections of individual resources. For the CAP service, there is a single collection to which you can add CAP alert documents. To retrieve the collection of alerts represented by an Atom Feed, you can issue an HTTP GET request on the URI of the collection. Each alert is represented by both an Atom Entry and a CAP alert document.
Table 1 provides a listing and description of each of the URIs and methods that the CAP publishing service supports.
Table 1. The URIs and operations supported by the CAP service TEST FOR PRINT
| URI and Type | Method | Operation | Description |
|---|---|---|---|
URI: Type: | GET | retrieve | Gets the Atom Service document |
URI: Type: | GET | listing | Gets the Atom Feed for this collection |
URI: Type: | POST | create | Adds a CAP alert to the Atom collection |
URI: Type: | GET | retrieve | Gets an Atom Entry representing the CAP alert |
URI: Type: n/a | DELETE | delete | Deletes the CAP alert |
URI: Type: | GET | retrieve | Gets the published CAP alert |
URI: Type: | PUT | update | Updates the published CAP alert |
URI: Type: n/a | DELETE | delete | Deletes the CAP alert |
The downloadable .zip file associated with this article provides the complete implementation of the CAP service (see Download for more information). To run the example, you'll need a Java Web application server such as Apache Tomcat or IBM WebSphere® Application Server. The archive includes full instructions.
As a quick side note, the CAP standard doesn't define a MIME media type
for alert documents. While you can use the application/xml media type, it
isn't ideal to use such a generic media type for a document format as specific
as an alert. For the sake of the example application, I use a made-up
application/alert+xml media type to identify alert documents.
To publish an alert document to the collection requires only a couple of steps, as illustrated in Listing 9. First, you create and sign the alert document as shown in Listing 2 and Listing 4. Then you create an Abdera client and specify the appropriate media type for the alert. Lastly, you send the alert to the collection using HTTP POST.
Listing 9. Posting an alert to the collection
Alert alert = // create and sign the alert
RequestOptions options = client.getDefaultRequestOptions();
options.setContentType("application/alert+xml");
resp = client.post(
"http://localhost:9080/capserver/alerts",
alert.getDocument(), options);
switch(resp.getType()) {
case SUCCESS:
// posting succeeded
default:
// something else happened
System.out.println(resp.getStatus());
System.out.println(resp.getStatusText());
} |
If the POST operation succeeds, the HTTP response will include a Location
header specifying the location of an Atom Entry Document representing the alert
that was published. That entry will include a link to the CAP alert document
sent to the collection. The server will digitally sign the Entry Document.
Listing 10 shows the Entry Document produced by the server.
Listing 10. The Atom Entry Document representing the posted CAP alert
<?xml version="1.0" encoding="utf-8"?>
<entry>
<id>http://localhost:9080/capserver/alerts/KAR0-0306112239-SW</id>
<updated>2003-06-12T05:39:00.000Z</updated>
<published>2003-06-12T05:39:00.000Z</published>
<app:edited xmlns:app=
"http://www.w3.org/2007/app">2007-06-27T05:12:05.448Z</app:edited>
<title type="text">AMBER ALERT</title>
<author><name>LOS ANGELES POLICE DEPT - LAPD</name></author>
<summary type="text">...</summary>
<link href="http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.cap" />
<link href="http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.cap"
rel="edit-media" />
<link href="http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.cap"
rel="enclosure" />
<link href="http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.atom"
rel="self" />
<content type="application/alert+xml"
src="http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.cap" />
<category scheme="urn:oasis:names:tc:emergency:cap:1.1:status" term="Actual" />
<category scheme="urn:oasis:names:tc:emergency:cap:1.1:msgtype" term="Alert" />
<category scheme="urn:oasis:names:tc:emergency:cap:1.1" term="Rescue" />
<category scheme="urn:oasis:names:tc:emergency:cap:1.1:urgency" term="Immediate" />
<category scheme="urn:oasis:names:tc:emergency:cap:1.1:severity" term="Severe" />
<category scheme="urn:oasis:names:tc:emergency:cap:1.1:certainty" term="Likely" />
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...
</ds:Signature>
</entry> |
In this example, several of the data elements contained in the CAP alert
are converted into atom:category elements in the
Entry Document. Doing so allows Atom client implementations to present
additional information about the alert without needing to have any prior
knowledge of the CAP specification. With no standard way to express
alert metadata within an Atom Entry, it's likely that different
implementations will present this information in a variety of ways.
Client applications can access either the Entry Document or the CAP alert
document using URLs provided in the various atom:link elements in the entry.
You can retrieve the CAP alert document, shown in Listing 11,
at http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.cap.
Listing 11. Retrieving the CAP alert
Entry entry = // get the entry
ClientResponse resp = client.get(
"http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.cap");
Document<Alert> doc = resp.getDocument();
Alert alert = doc.getRoot(); |
You can retrieve the Entry Document, shown in Listing 12,
at http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.atom.
Listing 12. Retrieving the Atom Entry for the alert
ClientResponse resp = client.get( "http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.atom"); Document<Entry> doc = resp.getDocument(); Entry entry = doc.getRoot(); |
Posted alerts are listed in the Atom Feed Document provided by the collection, with the most recently created or modified alert listed first. As shown in Listing 13, each entry represents exactly one alert document and provides the links necessary to retrieve or modify the alert.
Listing 13. The catalog Atom collection
<?xml version="1.0" encoding="utf-8"?>
<feed xml:base="http://localhost:9080/capserver/alerts"
xml:lang="en-US"
xmlns="http://www.w3.org/2005/Atom">
<id>http://localhost:9080/capserver/alerts</id>
<title type="text">CAP Catalog</title>
<updated>2007-06-27T07:51:29.676Z</updated>
<author><name>CAP Catalog</name></author>
<link href="http://localhost:9080/capserver/alerts" rel="self" />
<link href="http://localhost:9080/capserver/alerts?page=2"
rel="next" type="application/atom+xml" />
<entry>
<id>http://localhost:9080/capserver/alerts/KAR0-0306112239-SW</id>
...
</entry>
...
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...
</ds:Signature>
</feed> |
Modifying an alert is a generally straightforward process. First, to retrieve the current editable representation of the alert document, the editing client sends an HTTP GET request to the CAP document. This returns the alert along with a last-modified timestamp or entity tag. The client can then make any modifications it wishes, removing the old digital signature from the alert and re-signing the modified document. Once that is complete, the client sends a PUT request containing the modified alert back to the same URL used to retrieve the original document, as shown in Listing 14.
Listing 14. Updating the CAP alert
Alert alert = // get and modify the alert
RequestOptions options = client.getDefaultRequestOptions();
options.setIfMatch(etag);
options.setContentType("application/alert+xml");
resp = client.put(
"http://localhost:9080/capserver/alerts/KAR0-0306112239-SW.cap",
alert.getDocument(), options);
switch(resp.getType()) {
case SUCCESS:
// update succeeded
default:
// something else happened
System.out.println(resp.getStatus());
System.out.println(resp.getStatusText());
} |
Note that in a typical Atom Publishing Protocol implementation, the Atom Entry Documents are editable. However, in the CAP server example, Entry Documents are generated automatically based on information contained in the alert document, and a client cannot edit them directly. To edit the Entry Document, a client must edit the CAP alert.
To delete an alert, you send an HTTP DELETE request to the URL used to retrieve the alert document, as shown in Listing 15.
Listing 15. Deleting the CAP alert
RequestOptions.options = client.delete( "http://localhost:9080/capserver/alerts/KAR0- 0306112239-SW.cap"); |
While the example application doesn't implement any access-control mechanisms, a real-world implementation would ensure that only individuals with the proper authorization are permitted to post, modify, and delete alert documents.
One key goal that drives the development of the Common Alerting Protocol is the need for a comprehensive and standardized means to distribute critical information about life-threatening events of any kind. Use of the Atom Publishing Protocol to publish and manage collections of CAP alerts helps to advance that goal.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample Java Web Application for this article | atomcap.zip | 18455KB | HTTP |
Information about download methods
Learn
- The Getting
to know the Atom Publishing Protocol series (James Snell, developerWorks, October 2006): Get an introduction to the basic operations of the protocol.
- An overview of the Atom
1.0 Syndication Format (James Snell, developerWorks, August 2005): Find details about the popular Web content syndication format.
- The CAP
Cookbook: Learn more about the Common Alerting Protocol.
- The CAP
V1.1 specification: Read about this simple but general format for exchanging all-hazard emergency alerts and public warnings over all kinds of network.
- California Emergency
Digital Information Service: Discover how the statewide EDIS network combines CAP and Atom to publish alert notifications.
- Atom Publishing Protocol specification: Read the details of this standard for content publishing and management..
- Atom Syndication Format specification: Get the details on this XML-based document format that describes feeds that syndicate Web content such as weblogs and news headlines to Web sites and directly to user agents.
- Apache Abdera project: Visit the project's Web site to learn more about this
effort to build a functionally-complete, high-performance implementation of the Atom Syndication Format and Atom Publishing Protocol specifications.
- Who Is Using
CAP?: Read a list of companies, agencies, and organizations who've announced support for CAP for applications and services.
- IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
- XML technical library: See the developerWorks XML zone for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks.
- developerWorks technical events and webcasts: Stay current with technology in these sessions.
- The
technology bookstore: Browse for books related to XML, JavaScript, and other Web technologies.
Get products and technologies
- IBM trial software: Build your next development project with trial software available for download directly from developerWorks.
- Apache Tomcat: Download and install this Java-based
Web server.
- WebSphere
Application Server Express V6.1: Download a trial version of this ready-to-go solution
with a J2EE application server, sample apps, development tools, and wizards. Or try WebSphere Application Server
Community Edition V1.1.0.2, a fully licensed, no-charge version.
Discuss
- Participate in the discussion forum.
- Atom and RSS forum: Find tips, tricks, and answers about Atom, RSS, or other syndication topics in this forum.
- XML zone discussion forums: Participate in any of several XML-centered forums.
- developerWorks XML zone: Share your thoughts: After you read this article, post your comments and thoughts in this forum. The XML zone editors moderate the forum and welcome your input.
- developerWorks blogs: Get involved in the
developerWorks community.

James M. Snell is a software engineer in IBM's WebAhead group focusing on the development and practical application of key emerging technologies for IBM's own use. James has participated in the effort to define the Atom Syndication Format and Atom Publishing Protocol standards and has implemented no less than nine different Atom Publishing Protocol server implementations.
Comments (Undergoing maintenance)





