Getting Started Connect Your Systems Build a Smart Ticketing System

Build a Smart Ticketing System

45 minutes

In this exercise, you will build on the Red Light Violation application used in the Interoperability QuickStart. This exercise assumes you have completed the Interoperability QuickStart, as it builds on the code used in that exercise. Here, you will add another route to identify at-risk intersections based on data from Chicago traffic system. This involves:

  • Building a simple interface to consume data from a file and store data to a file.
  • Adding in logic to only list intersections that have been deemed high risk based on the number of red light violations.
  • Adding in routing to consume additional data about populations using REST from public APIs.
  • Modifying the data to be in the right format for the downstream system.

Get set up

  1. First, make sure you have an instance of InterSystems IRIS and an IDE ready to go. Sandbox settings will appear below after you log in and launch a sandbox.

    If you don’t have InterSystems IRIS yet, get a free, online development sandbox here. Log in with your InterSystems universal account, or register for one below.

  2. Import the starting files from GitHub into the shared directory. To do this, in the Theia IDE’s built-in terminal, type:
    cd /home/project/shared
    git clone
  3. Now go to the Management Portal , or back in the Theia IDE, use the menu at the top to navigate to the Management Portal. Select InterSystems > Management Portal.
  4. Import classes by going to System Explorer > Classes, then click Import. Enter /home/project/shared/Samples-Integration-SmartTicketing/Setup/CustomCensusComponents.xml as the file to import and then click Import again.
If you get a cross-origin error, simply change the Management Portal URL from https:// to http:// (with no s). Based on the way this lab environment is set up to share content between containers, this is required to successfully upload a file.

Add a new interface

You will first create the simplest interface that includes consuming data from a file (using a record map and business service) and storing it in another file (using a business operation). We will make this more complex as we go through the exercise, but for now, notice how easy it is to consume and map data from a file to a structure you prefer within InterSystems IRIS® data platform. No coding is required for simple tasks like this, which leverage the many built-in components within InterSystems IRIS.

  1. Create a new file record mapper business service that will consume archived information about intersections in Chicago, using the following steps:
    1. Open the Management Portal and navigate to Interoperability > Build > Record Maps > Go.
    2. Click CSV Wizard and navigate to /home/project/shared/Samples-Integration-SmartTicketing/SampleFiles/Red_Light_Camera_Violations_Test.csv with the following fields set:
      Sample File/home/project/shared/Samples-Integration-SmartTicketing/SampleFiles/Red_Light_Camera_Violations_Test.csv
      RecordMap nameDemo.CameraViolationsMap
      Record TerminatorLF
      Samples has header rowChecked

      If you get a cross-origin error, simply change the Management Portal from https:// to http:// (with no s). Based on the way this lab environment is set up to share content between containers, this is required to successfully upload a file.
    3. Verify you have the following fields (or add them manually using the Plus icon and defining a comma as the separator):

      Camera Violations Map chart shows the following fields as type %String: Intersection, Camera ID, Address, Violation Date, Violations, X coordinate, Y coordinate, Latitude, Longitude, Location.
    4. Click Generate to generate the corresponding classes for this record map.
    5. Go to the Production Configuration page by selecting Interoperability > Configure > Production and add a new business service, specifying the Service Class as EnsLib.RecordMap.Service.FileService, a prebuilt file record mapper business service, and the Service Name as From_RedLightArchive. Specify no other fields and click OK.
      If you do not yet have a production running, you should click New and then specify Demo as the package and RedLights as the production.
    6. Select the new component, the Settings tab on the right, and supply the following values for each field:
      File Path/home/project/shared/Samples-Integration-RedLights/data/In/
      File SpecRed_Light_Camera_Violations*.csv
      Archive Path/home/project/shared/Samples-Integration-RedLights/data/SampleFiles/
    7. Click Apply.
  1. We next need a business operation that will output a list of the dangerous intersections.
    1. Create a new record mapper using the same process as the last step. This time specify the RecordMap name as Demo.HighRiskArchiveMap. You can use the same sample file or add the fields manually to look like the following:
      High Risk Archive chart now shows the following fields as type %String: Intersection, Camera ID, Address, Violation Date, Violations, X Coordinate, Y Coordinate, Latitude, Longitude, Location.
    2. Go back to the Production Configuration page and add a new business operation using Operation Class EnsLib.RecordMap.Operation.FileOperation and call it To_HighRiskArchive. You can ignore the rest of the fields for now. Specify the following fields in the Settings tab:
      File Path/home/project/shared/Samples-Integration-RedLights/data/Out/
      File Name%Q_HighRisk.txt
  1. Select the From_RedLightArchive business service and update the Target Config Names setting to point to the new To_HighRiskOperation business operation. Remember to click to save the changes.
  2. Verify the production is running. If not, click the Start button at the top:
    Start button highlighted on Production Configuration page
  3. Now let’s test this simple interface.
    1. In the integration IDE, copy the Red_Light_Camera_Violations_Test.csv file to the In folder in the provided IDE. The integration will consume this file from the folder and delete it.
    2. Back in the Management Portal, navigate to the Message Viewer by going to Menu > Message Viewer and select the top message.
    3. On the right pane, click View Full Trace to view the trace of how messages have been passed through the interface.

If all worked successfully, you will receive the same message in the Out folder and the Visual Trace will show no errors. If you have any items that are marked with a red diamond: , please see the Troubleshooting Guide at the bottom of the page.

Add business orchestration logic

Now you will add business orchestration and a ruleset that will determine which intersections are high risk and only output that data to the file. You will use what is known as the Business Process Designer to easily apply logic — such as checking a condition, or applying a ruleset — and forward the appropriate data to the previous business operation to write to the file.

  1. Navigate to the Business Process Designer by going to Home > Interoperability > Build > Business Processes.
  2. Click the New button and specify Package as Demo and Name as HighRiskIntersectionsBPL.
  3. You need to define the type of the message that will be received by the business process, the type of the message that will be sent back to whatever called it, and any variables that will be used within this business process. To do this, select the Context tab on the right and specify the following values:
    Request ClassDemo.CameraViolationsMap.Record
    Response ClassEns.Response
    Context propertiesIntersectionRisk with type %String(MAXLEN=50)
    VIOLATIONS with type %Integer
  4. Next, in the center section, add in an activity to set up the context property, or the variables that will be used within this business process. To do this, select <start>, then the —Add Activity— drop-down, and choose Assign. Set property context.VIOLATIONS equal to request.VIOLATIONS. Click Save.
    Action field set to set, Property field set to context.VIOLATIONS, and Value field set to request.VIOLATIONS
  5. Next, add a rule activity. Rules can be set up to allow certain people to access and change their values. This particular rule activity will determine the number of violations in a day that will mark an intersection as very high, high, or low risk.
    1. Add a new rule activity using the Add Activity drop-down > Rule.
    2. Define the name of the activity as Check if high risk intersection.
    3. Next you need to define the ruleset. Click the Rule Editor button (in the Activity tab) and specify Demo as the package and IntersectionRiskRule as the name. The Context Class should be Demo.HighRiskIntersectionsBPL.Context. This object passes the context properties, which include the number of violations for a particular intersection to the ruleset.
    4. Select ruleSet and then click Plus sign to add a new rule.
    5. Select the new rule and then click Plus sign to add a when statement.
    6. Double-click the condition box and supply VIOLATIONS > 15 as the condition.
    7. Select the when and add a return with the value “very high”.
    8. Continue until your ruleset looks like the following:

      Ruleset, rule 1. When violations are greater than 15, return a value of very high. Rule 2. When violations are greater than 10, return a value of high. Rule 3. Otherwise, return a value of low.
    9. Click Save to save this ruleset.
  6. The Rule Editor most likely opened in a new tab. You can now close this tab and go back to the business process designer. In the Business Process Designer, set Rule Name to Demo.IntersectionRiskRule and Result Location to context.IntersectionRisk.
  7. After the rule activity (select this activity to automatically connect it to the next activity), add an if activity. This adds both an if activity and the join activity where both the true and false branches eventually join back together.
  8. Name the if activity Check if high risk and supply the following for Condition: (context.IntersectionRisk = "high") || (context.IntersectionRisk = "very high")
  9. If a high-risk intersection was identified, we want to add it to the file. Click the true line, add a Call activity, and supply the following values:
    NameCall High Risk Operation
    TargetSelect Operations > To_HighRiskOperation
    Request Message ClassDemo.HighRiskArchiveMap.Record
    Response Message ClassEns.Response (the default)
  10. Click the Request Builder button to define how the fields will be populated in the request message class that will be sent to the business operation.
  11. Copy all properties in the request to the callrequest by clicking the circle next to each field in the request and dragging and dropping to the callrequest field. The field should turn orange before you let go.
    Graphical interface showing line connecting Intersection field on one side with the same field on the other side.
  12. Click OK when %Source through Location have been mapped.
  13. Back in the Business Process Designer, click the end of the if activity and drag it to the join activity to create the false branch.
  14. Then finish the diagram by connecting the end of the join with the <end> activity. By now, the diagram may be quite messy. To quickly organize, click the Arrange icon to arrange the layout of items.
  15. Click Compile to compile the resulting classes. Your business process should now look like the following:
    Flow diagram in which Start points to an assigned activity called Set Context. Flow then goes to “Check if High Risk” activity. If true, call high-risk operation. If false, do nothing. End flow diagram.
  16. Let’s next add this business process to the integration solution. Navigate back to the Production Configuration page by going to Menu (in the top right) > Production.
  17. Next to Processes, click Plus sign.
  18. For Business Process Class, choose Demo.HighRiskIntersectionsBPL and click Enable Now > OK.
  19. Update the business service to send a message to this business process before writing to the file by selecting From_RedLightArchive and changing Target Config Names to be DemoHighRiskIntersectionsBPL instead. Click Apply.
  20. Send a test message by copying the same Red_Light_Camera_Violations_Test.csv file to the In folder again. Notice in the Message Viewer that some messages stop at the business process since they are not high-risk intersections:
    Message called Record goes from business service to business process. No message is sent back.
    Others are sent to the business operation.

Add routing

Now we will add more routing. Data coming in can easily be routed to multiple locations with the Business Process Designer using low- to no-code.

In this section, you will update the Demo.HighRiskIntersectionsBPL to retrieve information about population density for each intersection. This information will be added to the file so that better decisions can be made on how to handle dangerous intersections. To do this, the business process will orchestrate calling a service provided by the US Census using REST to get a GeoJSON code for the intersection’s latitude and longitude, a format used throughout other datasets to indicate location. It will then make another call to get population information from a different service provided by the US Census. This population information will then be added, for each high risk intersection, to the high-risk archive file.

  1. In the Production Configuration page, create a new business operation using the Demo.ToCensusGeoServiceBO class (built by another developer). Leave the Name field blank so it defaults to the name of the class. Specify the following fields in the Settings tab:
    SSL ConfigurationRESTSSL

    If RESTSSL does not exist, create it by navigating to:

    1. Home > System Administration > Security > SSL/TLS Configurations.
    2. Click Create New Configuration.
    3. Call it RESTSSL and click Save.

  2. Select Production Settings > Development and Debugging. Then check Testing Enabled and click Apply. This allows us to test components, such as business operations, and send sample data through a component to see how it works.
  3. Test this business operation by selecting the Demo.ToCensusGeoServiceBO component and then going to the Actions tab > Test. Provide -87.70807749 for longitude and 41.95402905 for latitude. Click Invoke Business Service to test.
  4. Add another business operation called Demo.ToCensusDS with the following settings:
    SSL ConfigurationRESTSSL
  5. Navigate back to the business process by selecting HighRiskIntersectionsBPL. Next to the Class Name, click the magnifying glass to open the business process:
    Magnifying glass icon highlighted next to the Class Name field
  6. In order for the GeoJSON information, retrieved from the Geo service, to be used in the subsequent call to the Census service, we need a few more context properties/variables. To add these, go to the Context tab and add GeoResponse of type Demo.GeoResponse, and Population of type %String(MAXLEN=50).
  7. Not all intersections in the archive folder have latitude and longitude, so we cannot include that information. To handle this, click the true line between the if and the call to the High Risk Operation, and add another if action. Provide the following values:
    NameCheck if has geo info
  8. Add two calls if there is geography information after the Check if has geo info if activity. Call #1:
    NameGet Geo Info
    AsynchronousUncheck this to wait for the response before proceeding
    Request Message ClassDemo.GeoRequest (select Persistent Classes on the left to find this)
    Request ActionsSet action of property callrequest.Latitude has value rest.LATITUDE. Set action of property callrequest.Longitude has value request.LONGITUDE.
    Response Message ClassDemo.GeoResponse
    Response Actions

    Call #2:

    NameGet Population Info
    AsynchronousUncheck this to wait for the response before proceeding
    Request Message ClassDemo.PopulationRequest
    Request ActionsSet action of property callrequest.State has value context.GeoResponse.State. Set action of property callrequest.County has value context.GeoResponse.County. Set action of property callrequest.Tract has value context.GeoResponse.Tract. Set action of property callrequest.BlockGroup has value context.GeoResponse.BlockGroup.
    Response Message ClassDemo.PopulationResponse
    Response Actions
  9. If there is no geography information, the business process cannot get population density information and should just create the high risk file without this information. Click the bottom of the Check if geo info diamond and drag it straight down, dropping it on the join to create the false branch.
    False branch that skips GetGeoInfo and GetPopulationInfo is highlighted on interface.
  10. Make sure to compile the business process using the Compile button at the top.
  11. In order to use the new population information in the list of high-risk intersections file, you first need to update the record map to include this information.
    1. Select Home > Interoperability > Build > Record Maps. Make sure Demo.HighRiskArchiveMap is open.
    2. Add another field at the bottom called PopulationDensity of type %String.
      High Risk Archive map now contains PopulationDensity field of type %String.
    3. Remember to click Generate to save and generate the resulting classes.
  12. Back in the Business Process designer, select Call High Risk Operation and update the request by using the Request Builder to set callrequest.PopulationDensity to context.Population. Make sure to compile.
  13. Let’s test and see in the visual trace that we get the information from the REST services properly. Send another message through by copying the Red_Light_Camera_Violations_Test.csv file to the In folder. View the messages again in the Message Viewer to see that data was sent, in many of the traces, to these two REST services and successfully retrieved data (notice the Body contents).

Explore custom business components

InterSystems IRIS provides many out-of-the-box components that require little to no coding. However, custom components can be coded to do just about anything you need them to do. The custom Demo.ToCensusGeoServiceBO and Demo.ToCensusDS business operations were previously created in this exercise. In the next several steps, you will explore this code, which is written in InterSystems ObjectScript.

Navigate to shared/Samples-Integration-SmartTicketing/Setup/src/cls and open the Demo.ToCensusDS class. In this class, you will notice the code calls a REST endpoint with a query, retrieves information, and sends data back to the calling business process.

  • tURL defines the URL along with the search parameters.
  • GetURL then sends the URL and gets an HTTP response.
  • ..JSONStreamToObject converts the JSON stream to a dynamic object within InterSystems IRIS.
  • A new Demo.GeoResponse is then populated with information from the dynamic object to be sent back in the method’s pResponse object.
/// Retrieves GeoJSON data from the USCensus using longitude and latitude.
Method GetGeoInfo(pRequest As Demo.GeoRequest, Output pResponse As Demo.GeoResponse) As %Status
  try {
      // Prepare and log the call
      // Append the city to the URL configured for adapter
      set tURL= ..Adapter.URL _ "query?geometry=" _ pRequest.Longitude _ "," 
      _ pRequest.Latitude _ "&geometryType=esriGeometryPoint&outfields=*"
      _ "&returnGeometry=true&returnIdsOnly=false&inSR=4326&f=geojson"
      // Execute the call
      $$$TRACE("Executing call")
      set tSC=..Adapter.GetURL(tURL,.tHttpResponse)
      // Return the response
      if $$$ISERR(tSC)&&$IsObject(tHttpResponse)&&$IsObject(tHttpResponse.Data)
        &&tHttpResponse.Data.Size {
         set tSC=
      if $IsObject(tHttpResponse) {
         // Instantiate the response object
         set pResponse = ##class(Demo.GeoResponse).%New()
         // Convert JSON into a Proxy Object
         set tSC = ..JSONStreamToObject(tHttpResponse.Data, .tProxy)
         if (tSC){                                 
            // Set response properties from the Proxy Object
            set pResponse.State = tProxy.features.GetAt(1).properties.STATE
            set pResponse.County = tProxy.features.GetAt(1).properties.COUNTY
            set pResponse.Tract = tProxy.features.GetAt(1).properties.TRACT
            set pResponse.BlockGroup = tProxy.features.GetAt(1).properties.BLKGRP
            $$$TRACE("Object created with " _ pResponse.State)
       set tSC=$$$SystemError
   quit tSC


Troubleshooting Guide

ProblemWhat to do
My lab environment won’t start or the pages won’t render.On the launcher, click Delete and Reset Your Lab and try again. If that does not fix it, contact
I do not see a message in the visual trace.Select From_RedLightArchive and verify the setting Target Config Names is set to To_HighRiskOperation or, for later in the exercise, to Demo.HighRiskIntersectionsBPL.
I get a cross-origin error.Change the Management Portal from https:// to http:// (with no s). Based on the way this lab environment is set up to share content between containers, this is required to successfully access files in the shared folder.
Testing of Demo.ToCensusGeoServiceBO causes an error.Verify you supplied longitude before latitude in the tester.
The Test button is disabled so I can’t test.Verify you have selected Production Settings > Development and Debugging and checked Testing Enabled.
The visual trace looks different than expected and uses Ens.Scheduler.Select the next message down. This message is related to a background process and can be ignored.
Up Next
Data-Driven SMS Alerts
20 minutes
Use InterSystems IRIS to easily turn on SMS alerting in a sample system.