Creating and publishing events.

How to create and publish events

  1. Check to see if the event already exists.
  2. Design the event.
  3. Add the event to the EventHub dictionary.
  4. Document the event in the SOA Registry.
  5. Publish the event.

This section covers steps 2 and 5, designing and publishing events.

EventHub API

The EventHub API is intended to be small, lightweight and flexible to accommodate a wide variety of events created by the event publishers. EventHub uses RESTful web services to publish events so the event data is in XML or JSON format; the two most popular standards in use today. Here is an example of a simple event published in JSON format:

{
  "head": {
    "domain": "edu.byu.hr.payroll",
    "entity": "PeopleSoft HR",
    "type": "W2 Form Available",
    "version": "1.0"
  }
}

There is 1 required node (head) and 4 required fields (domain, entity, type, version). There are also 3 optional nodes (paramList, body, history) not shown in this example. The "body" node has no predetermined format, which allows the publisher a great deal of freedom to decide what the event body should look like as long as it conforms to XML or JSON standards. EventHub generates a time stamp and a globally unique identifier (guid) when the event is published, adds them to the "head" node of the event and forwards the event to all web service endpoints that have subscribed to the event.

Who decides what events can be published?

The event publisher is responsible for deciding what events are published and what the event should contain. There is no oversight committee to review or approve events. If you can log in to BYU you can publish events. Likewise, if you have a BYU login and an application that can receive RESTful web services, you can receive events. Event publishers are responsible to document the events they provide so subscribers know what to listen for. If there is poor documentation or no documentation, those events will likely have very few or no subscribers, which defeats the purpose of publishing events. Publishers can register the domain, entity and type of events in a dictionary in EventHub so subscribers can easily discover what events are available. Not registering them will make it difficult for subscribers to find those events. In addition, it is highly recommended that publishers document their events in the BYU Web Service Registry.

Publishers send events to the EventHub RESTful web service endpoint in XML or JSON format using HTTP POST. EventHub directs those events to the RESTful web service endpoints of subscribers in the same format using HTTP POST. If you don't have a RESTful web service endpoint that can receive events you won't be able to receive any. EventHub "users", "subscribers", or "receivers" are really just web service "endpoints" that events will get directed to. EventHub provides web services for publishers to publish events, for receivers (users) to subscribe to events, and for both to discover what kinds of events are being published or subscribed to. What follows is a description of the format that event publishers use for publishing events to EventHub, which is identical to what subscribers will receive at their web service endpoints.

Event Format

JSON

{
  "head": {
    "domain": "edu.byu.finance",
    "entity": "MyFinancialCenter",
    "type": "TuitionDue",
    "version": "1.0",
    "timeStamp": "2013-03-29T23:22:42.367-06:00",
    "guid": "20130329TuitionDue234802601"
  }
}

XML

<?xml version="1.0" encoding="UTF-8" ?>
  <head>
    <domain>edu.byu.finance</domain>
    <entity>MyFinancialCenter</entity>
    <type>TuitionDue</type>
    <version>1.0</version>
    <timeStamp>2013-03-29T23:22:42.367-06:00</timeStamp>
    <guid>20130329TuitionDue234802601</guid>
  </head>

Required node: head

Required fields:

  • domain - something like "edu.byu.finance" or "edu.byu.admissions" or "edu.byu.oit.core.identity"
  • entity - typically the name of the application generating the event, like "MyFinancialCenter" or "AIM" or "IdentityManagement"
  • type - the type of event, something like "TuitionDue" or "AddressChanged" or "ClassRegistrationOpen" or "ClassFull"
  • version - the version of the domain/entity/type combination, something like 1.0

What is entered in the domain, entity, type and version is up to the event publisher to decide, or to negotiate with people who are interested in receiving those events. It is recommended, however, that you use domain notation for the domain; e.g., edu.byu.hr.benefits.

Optional fields:

  • timeStamp - the publisher may provide a time stamp, for example to track when the event was created. EventHub will return its own generated time stamp when it receives the event which the publisher can use, for example, to monitor the performance of the system.
  • guid - the publisher may provide a globally unique identifier (guid) that is unique to its system. EventHub will return its own generated guid which can be used to track the event.

 

Additional optional nodes and fields. Examples will be shown below:

  • paramList - Additional parameters used in combination with the domain/entity/type to help event receivers search for and filter specific events to receive. For events that are specific to an individual, like an address change in PRO, an obvious parameter would be the individual's Person ID (or BYU ID or Net ID). These parameters are decided by the publisher and should be registered in EventHub so those who wish to receive these events know which parameters they can search or filter on.
    • params - Required node name when including paramList. What follows are name/value pairs decided by the publisher.
      • name - the name of the parameter, for example "personId"
      • value - the value of the parameter, for example "013024069"
  • body - The content of the body is determined by the publisher. It must conform to XML or JSON standards. It can be used to include additional, non-secure information pertinent to the event. If the event signals something that happens that involves sensitive information, rather than send the private information with the event, the body could contain a web service URL that an event receiver can contact (and authenticate to) to get the sensitive information.
  • history - For event receivers that will enhance an original event with additional information and generate a new event, this is a way to track the series of events that produced the final event. The content of the "head" of each prior event is appended here.
    • {head(1)}
    • {head(2)}
    • {head(...)}

Publish Events

When the event is published to EventHub, a timeStamp and guid are generated by EventHub and the full message body is returned along with the generated timeStamp and guid. If a timeStamp and guid were passed in by the publisher, those are stored in the "history" node.

For example, if this is sent:

 

{
  "head": {
    "domain": "edu.byu.finance",
    "entity": "MyFinancialCenter",
    "type": "TuitionDue",
    "version": "1.0"
  }
}

This is returned:

{
  "head": {
    "domain": "edu.byu.finance",
    "entity": "MyFinancialCenter",
    "type": "TuitionDue",
    "version": "1.0",
    "timeStamp": "2013-11-07T12:56:51.058-07:00",
    "guid": "0000020d-fca7-6feb-0000-014234237ff2"
  }
}

The publisher can use the timeStamp and guid to uniquely identify this event. If the publisher wants to track the time it created the event and its own guid, it can provide those. EventHub will return its own generated timeStamp and guid and keep the original timeStamp and guid from the publisher in the history node.

For example, if this is sent:

{
  "head": {
    "domain": "edu.byu.finance",
    "entity": "MyFinancialCenter",
    "type": "TuitionDue",
    "version": "1.0",
    "timeStamp": "2013-11-07T10:15:25.355-07:00",
    "guid": "20130329TuitionDue234802601"
  }
}

This is returned:

{
  "head": {
    "domain": "edu.byu.finance",
    "entity": "MyFinancialCenter",
    "type": "TuitionDue",
    "version": "1.0",
    "timeStamp": "2013-11-07T10:15:25.428-07:00",
    "guid": "0000020d-fca7-6feb-0000-0142342a8192"
  },
  "history": {
    [
      "domain": "edu.byu.finance",
      "entity": "MyFinancialCenter",
      "type": "TuitionDue",
      "version": "1.0",
      "timeStamp": "2013-11-07T10:15:25.355-07:00",
      "guid": "20130329TuitionDue234802601"
    ]
  }
}

The original event is now in the "history" node, including the timeStamp and guid that were passed in. The event header contains the new timeStamp and guid generated by EventHub. Applications that receive events, enhance them and generate new events derived fom one or more prior events should behave this way; moving the original event(s) "head" to the end of the "history" so consumers can see the trail of events that produced the one they ultimately receive.

 

Example of event with optional paramList, body, and history included:

{
  "head": {
    "domain": "edu.byu.finance",
    "entity": "MyFinancialCenter",
    "type": "TuitionDue",
    "version": "1.0",
    "timeStamp": "2013-03-29T23:22:42.367-06:00",
    "guid": "20130329TuitionDue234802601"
  },
  "paramList": {
    "params": [
      {
        "name": "PersonId",
        "value": "234802601"
      }
    ]
  },
  "body": {
    "tuition" : {
      "balance": 235.42,
      "dueBy": "2013-11-30"
    }
  },
  "history": {
    "head": [
      {
        "domain": "edu.byu.oit.edge.motion",
        "type": "MotionStopped",
        "entity": "OIT-Edge-Motion-Sensor",
        "version": "1.0",
        "timeStamp": "2012-10-29T14:08:30",
        "guid": "generated"
      },
      {
        "domain": "edu.byu.oit.edge.motion",
        "type": "MotionSensed",
        "entity": "OIT-Edge-Motion-Sensor",
        "version": "1.0",
        "timeStamp": "2012-10-29T14:07:30",
        "guid": "generated"
      }
    ]
  }
}