Creating Leap Events

What Are Leap Events?

Leap Events can be created at the System level in the <SystemEvents> element as well as the Service level within the <Events> element. These events can contain as much or as little data as you’d like. In addition to the level of detail and content of the event, you also have the ability to customize how the event is published by using an EventDispatcher.

To learn about different ways to publish an event, see the Dispatch Channel documentation

System Events

System Events are a specific type of event that can get triggered by any service currently enabled within a Feature. By default, the Leap Framework implements three types of System Events. Each of these are defined inside of a <SystemEvents> container element.

<SystemEvent id="SERVICE_COMPLETION_SUCCESS"
	description="Standard Event for sucess of every service Type"
	isEnabled="true">
	<CamelSystemEventBuilder 
	fqcn="com.attunedlabs.eventframework.camel.eventproducer.ServiceCompletionSuccessEventBuilder" 
	beanRefid="ServiceEventBuilder" />
	<dis:EventDispatchers>
		<dis:EventDispatcher>
			<dis:DispatchChanelId>FILE_STORE</dis:DispatchChanelId>
			<dis:EventTransformation Type="JSON">
			</dis:EventTransformation>
		</dis:EventDispatcher>
	</dis:EventDispatchers>
</SystemEvent>
<SystemEvent id="SERVICE_COMPLETION_FAILURE"
	description="Standard Event for failure of every service Type"
	isEnabled="true">
	<CamelSystemEventBuilder 
	fqcn="com.attunedlabs.eventframework.camel.eventproducer.ServiceCompletionFailureEventBuilder" 
	beanRefid="ServiceFailureEventBuilder" />
	<dis:EventDispatchers>
		<dis:EventDispatcher>
			<dis:DispatchChanelId>FILE_STORE</dis:DispatchChanelId>
			<dis:EventTransformation Type="JSON">
			</dis:EventTransformation>
		</dis:EventDispatcher>
	</dis:EventDispatchers>
</SystemEvent>
<SystemEvent id="SERVICE_PERFORMANCE_LOGGING"
	description="Measures Performance for services"
	isEnabled="true">
	<CamelSystemEventBuilder 
	fqcn="com.attunedlabs.eventframework.camel.eventproducer.ServicePerformanceLoggingEventBuilder" 
	beanRefid="PerformanceEventBuilder" />
	<dis:EventDispatchers>
		<dis:EventDispatcher>
			<dis:DispatchChanelId>FILE_STORE</dis:DispatchChanelId>
			<dis:EventTransformation Type="JSON">
			</dis:EventTransformation>
		</dis:EventDispatcher>
	</dis:EventDispatchers>
</SystemEvent>

System Event Definitions

1. Success Event

As the event name suggests, this is an event that is generated when any of the services successfully complete their function without any error. There are several reasons to use this event, but, most commonly, it is used to validate that the proper service is being called.

This would be a great event to dispatch in order to track service usage for particular tenants when service calls have usage limits implemented. The EventId used when defining a new SystemEvent is a reserved keyword. This means that in order to use the success event you must use the exact name “SERVICE_COMPLETION_SUCCESS”.

2. Failure Event

When any service fails, it’s a good practice to keep a record of that occurrence. Using a generic System Failure Event to log this behavior removes the need for service-level error events. The only exception being, when a custom dispatcher or event should be created based on the failure of a specific service.

Tracking service failure events provides great insight into the services which are not functioning properly or service that are difficult for users to understand how to use. The EventId used when defining a new SystemEvent is a reserved keyword. This means that in order to use the failure event you must use the exact name “SERVICE_COMPLETION_FAILURE”.

3. Performance Log Event

By logging a Performance Event you are able to see a detailed breakdown of the time elapsed for each individual component of a service call. Usually, this is best used in a development environment and used when debugging a particular issue.

Using performance log events in a production environment may lead to unnecessary disc space and CPU resources being used. Make sure this is turned off in prod. The EventId used when defining a new SystemEvent is a reserved keyword. This means that in order to use the performance logging event you must use the exact name “SERVICE_PERFORMANCE_LOGGING”.

System Event Output Examples

{
   "EventParam":{
      
   },
   "EventId":"SERVICE_COMPLETION_SUCCESS",
   "EventHeader":{
      "CamelTimeStamp":"Mon Sep 13 09:29:23 PDT 2021",
      "EVT_CONTEXT":{
         "valid":true,
         "implementationName":"eventdoc",
         "featureName":"evtest",
         "requestId":"kLQXKBwf",
         "featureGroup":"testing",
         "vendor":"attunedlabs",
         "tenantId":"all",
         "siteId":"all",
         "configurationContext":{
            "implementationName":"eventdoc",
            "featureName":"evtest",
            "featureGroup":"testing",
            "tenantId":"all",
            "siteId":"all",
            "vendorName":"attunedlabs",
            "version":"1.0"
         },
         "version":"1.0"
      },
      "requestUUID":"kLQXKBwf",
      "tenantId":"all",
      "siteId":"all",
      "CamelContextId":"baseroute",
      "CamelRouterId":"leapEventDispatcherServiceRoute"
   }
}
{
   "EventParam":{
      
   },
   "EventId":"SERVICE_COMPLETION_FAILURE",
   "EventHeader":{
      "CamelTimeStamp":"Mon Sep 13 09:31:41 PDT 2021",
      "EVT_CONTEXT":{
         "valid":true,
         "implementationName":"eventdoc",
         "featureName":"evtest",
         "requestId":"kLQXKBwf",
         "featureGroup":"testing",
         "vendor":"attunedlabs",
         "tenantId":"all",
         "siteId":"all",
         "configurationContext":{
            "implementationName":"eventdoc",
            "featureName":"evtest",
            "featureGroup":"testing",
            "tenantId":"all",
            "siteId":"all",
            "vendorName":"attunedlabs",
            "version":"1.0"
         },
         "version":"1.0"
      },
      "requestUUID":"kLQXKBwf",
      "tenantId":"all",
      "siteId":"all",
      "CamelContextId":"baseroute",
      "CamelRouterId":"leapEventDispatcherServiceRoute",
      "CamelFailedEndpoint": "/ecomm/rest/testing/evtest/test",
      "CamelFailureMsg": "could not find applicable route",
      "CamelRouteRolledBack": "true"
   }
}
{
   "EventParam":{
      
   },
   "EventId":"SERVICE_PERFORMANCE_LOGGING",
   "EventHeader":{
      "serviceType":"hello-world",
      "DEEP_TRACING":[
         "{time =0ms, operation =setProperty[subscriptionInvocation], routeId =route17}",
         "{time =0ms, operation =Processor@0xd7c00de, routeId =route17}",
         "{time =0ms, operation =Processor@0x29ddaa8e, routeId =route17}",
         "{time =31ms, operation =Processor@0x217009bd, routeId =route17}",
         "{time =172ms, operation =, routeId =route17}",
         "{time =0ms, operation =log, routeId =route16}",
         "{time =0ms, operation =setProperty[subscriptionInvocation], routeId =route16}",
         "{time =0ms, operation =when[{header{header(kafkaComponentInvocation)} is null}]choice[], routeId =route16}",
         "{time =0ms, operation =Processor@0x3a89226e, routeId =route16}",
         "{time =172ms, operation =loop[header{header(routingRuleLoopCount)}], routeId =route16}",
         "{time =139ms, operation =doTry, routeId =route16}",
         "{time =0ms, operation =Processor@0x1390a415, routeId =route16}",
         "{time =139ms, operation =when[{header{header(Action)} == InvokeCamelRoute}]choice[when[{header{header(Action)} == HttpPostRequest}]choice[when[{header{header(Action)} == Pipeline}]choice[], routeId =route16}",
         "{time =0ms, operation =Processor@0x4932d580, routeId =route16}",
         "{time =139ms, operation =when[{header{header(camelRouteDestination)} is not null}]choice[], routeId =route16}",
         "{time =139ms, operation =, routeId =route16}",
         "{time =0ms, operation =log, routeId =subscriber-execution-route}",
         "{time =0ms, operation =log, routeId =subscriber-execution-route}",
         "{time =139ms, operation =direct:transactionForSubscriber, routeId =subscriber-execution-route}",
         "{time =139ms, operation =transacted[ref:PROPAGATION_REQUIRED], routeId =subscriber-transaction-route}",
         "{time =18ms, operation =doTry, routeId =subscriber-transaction-route}",
         "{time =2ms, operation =bean:leapDataContextInit?method=createAndInitializeLeapContext, routeId =subscriber-transaction-route}",
         "{time =0ms, operation =bean:handlersBean?method=fetchHandlers, routeId =subscriber-transaction-route}",
         "{time =16ms, operation =direct:preServiceHandlersInvocation, routeId =subscriber-transaction-route}",
         "{time =0ms, operation =log, routeId =route11}",
         "{time =0ms, operation =log, routeId =route11}",
         "{time =16ms, operation =bean:handlersBean?method=syncOrAsyncDeciderForPreService(${in.header.pre-service},${in.header.pre-service-async}), routeId =route11}",
         "{time =0ms, operation =when[simple{${in.header.asyncRouteName} != null }]choice[], routeId =route11}",
         "{time =0ms, operation =removeHeader[${in.header.pre-service}], routeId =route11}",
         "{time =0ms, operation =removeHeader[${in.header.pre-service-async}], routeId =route11}",
         "{time =0ms, operation =setHeader[Access-Control-Allow-Origin], routeId =subscriber-transaction-route}",
         "{time =0ms, operation =setHeader[Access-Control-Allow-Methods], routeId =subscriber-transaction-route}",
         "{time =0ms, operation =setHeader[Access-Control-Allow-Headers], routeId =subscriber-transaction-route}",
         "{time =0ms, operation =setHeader[Exchange.HTTP_METHOD], routeId =subscriber-transaction-route}",
         "{time =32ms, operation =direct:entryroute, routeId =subscriber-transaction-route}",
         "{time =0ms, operation =bean:requestIdGenrator?method=uuidgenrate, routeId =entryRoute}",
         "{time =0ms, operation =direct:basetransformation, routeId =entryRoute}",
         "{time =0ms, operation =log, routeId =BaseTransformation}",
         "{time =15ms, operation =bean:leapEndpoint?method=validateLeapEndpointRequest, routeId =entryRoute}",
         "{time =0ms, operation =bean:leapConfigUtil?method=storePermastoreConfigurationInServiceContext('LeapDefault_Taxonomy.json'), routeId =entryRoute}",
         "{time =0ms, operation =bean:basedynamicExecution?method=route, routeId =entryRoute}",
         "{time =17ms, operation =, routeId =entryRoute}",
         "{time =17ms, operation =direct:evtest-hello-world-ExecutionRoute, routeId =hello-world-executionEnrichmentRoute}",
         "{time =17ms, operation =bean:executionFeatureDynamic?method=route, routeId =hello-world-ExecutionRoute}",
         "{time =0ms, operation =direct:evtest-hello-world-ImplementationSelectionRoute, routeId =hello-world-ExecutionRoute}",
         "{time =0ms, operation =log, routeId =hello-world-ImplementationSelectionRoute}",
         "{time =0ms, operation =, routeId =hello-world-ImplementationSelectionRoute}",
         "{time =0ms, operation =direct:evtest-hello-world-IR, routeId =hello-world-implEnrchimentRoute}",
         "{time =0ms, operation =log, routeId =hello-world-implRoute}",
         "{time =0ms, operation =direct:evtest-hello-world-executionExitRoute, routeId =hello-world-implRoute}",
         "{time =0ms, operation =, routeId =hello-world-executionExitRoute}",
         "{time =0ms, operation =log, routeId =ExitRoute}",
         "{time =0ms, operation =bean:identityService?method=setAccountDetailsInHeader, routeId =ExitRoute}",
         "{time =0ms, operation =bean:persistEventDetails, routeId =ExitRoute}",
         "{time =0ms, operation =bean:leapEndpoint?method=getResponseForLeapEndpoint, routeId =entryRoute}",
         "{time =0ms, operation =direct:exitRoute, routeId =entryRoute}",
         "{time =0ms, operation =log, routeId =ExitRoute}",
         "{time =0ms, operation =bean:identityService?method=setAccountDetailsInHeader, routeId =ExitRoute}",
         "{time =0ms, operation =bean:persistEventDetails, routeId =ExitRoute}",
         "{time =0ms, operation =direct:postServiceHandlersInvocation, routeId =subscriber-transaction-route}",
         "{time =0ms, operation =bean:handlersBean?method=syncOrAsyncDeciderForPostService(${in.header.post-service},${in.header.post-service-async}), routeId =route10}",
         "{time =0ms, operation =when[simple{${in.header.asyncRouteName} != null }]choice[], routeId =route10}",
         "{time =0ms, operation =removeHeader[${in.header.post-service}], routeId =route10}",
         "{time =0ms, operation =removeHeader[${in.header.post-service-async}], routeId =route10}",
         "{time =0ms, operation =setHeader[isServiceCompleted], routeId =subscriber-execution-route}",
         "{time =0ms, operation =direct:resourceClosingAndDispatcher, routeId =subscriber-execution-route}",
         "{time =0ms, operation =log, routeId =resourceClosingAndDispatcherRoute}",
         "{time =0ms, operation =seda:leapResourceRetentionRoute?waitForTaskToComplete=never, routeId =resourceClosingAndDispatcherRoute}",
         "{time =0ms, operation =seda:leapEventDispatcherServiceRoute?waitForTaskToComplete=never, routeId =resourceClosingAndDispatcherRoute}",
         "{time =0ms, operation =log, routeId =leapEventDispatcherServiceRoute}",
         "{time =0ms, operation =doTry, routeId =leapEventDispatcherServiceRoute}",
         "{time =0ms, operation =bean:leapEventDispatcher?method=dispatchEvents, routeId =leapEventDispatcherServiceRoute}"
      ],
      "CamelTimeStamp":"Wed Sep 15 11:54:32 PDT 2021",
      "EVT_CONTEXT":{
         "valid":true,
         "implementationName":"eventdoc",
         "featureName":"evtest",
         "featureGroup":"testing",
         "vendor":"attunedlabs",
         "requestId":"4HTwWWRo",
         "tenantId":"all",
         "siteId":"all",
         "configurationContext":{
            "implementationName":"eventdoc",
            "featureName":"evtest",
            "featureGroup":"testing",
            "tenantId":"all",
            "siteId":"all",
            "vendorName":"attunedlabs",
            "version":"1.0"
         },
         "version":"1.0"
      },
      "feature":"evtest",
      "requestUUID":"4HTwWWRo",
      "featureGroup":"testing",
      "tenantId":"all",
      "siteId":"all",
      "CamelContextId":"baseroute",
      "TOTAL_TIME":203,
      "CamelRouterId":"leapEventDispatcherServiceRoute"
   }
}

System Event Options

NameRequiredDefaultDescription
<SystemEvents>Y(Element) This is the main container that must contain all of the <SystemEvent> instances
<SystemEvent>Y(Element) Identifies that a system level event is defined within
idYN/A(String) A Unique ID that identifies this system event in the database. Belongs to <SystemEvent>
descriptionYN/A(String) A value that explains the purpose of the event. Belongs to <SystemEvent>
isEnabledYN/A(Boolean) Indicates whether the Event should be generated or not. Belongs to <SystemEvent>
<CamelSystemEventBuilder>Nnull(Element) Wrapper for a the bean that defines the structure of the Event being created
fqcnYN/A(String) The fully qualified class name of the Java Bean that implements the required logic for event creation. Belongs to <CamelSystemEventBuilder>
beanRefidY(String) Identifies the bean definition within Spring. Belongs to <CamelSystemEventBuilder>
<EventDispatcher>YN/A(Element) Contains the details required for publishing the event.
<DispatchChanelId>YN/A(String) The corresponding dispatchers id
<EventTransformation>YN/A(String) set the “type” to JSON if no further transformation is required

Service Events

Service Events are custom events that you can trigger on service completion. There are two ways to build a service event. The first is an OGNL builder and the second is a CUSTOM event type and the final is a Default Event. These are defined within the <Events> container element.

1. Custom Event

In order to define a CUSTOM event you must define a new <Event> containing a <CamelEventProducer> with a builder type of “CUSTOM”. This tells the event framework that the event will be created by a specific bean.

The bean that is referenced will be completely responsible for building the event structure and providing all of the event data.

2. OGNL Event

When defining a new <Event> and you’d like to build it’s content using OGNL, you need to add the builder type of “OGNL” within your <CamelEventProducer>. The benefit of using OGNL for building an event is that you can create the event without writing any bean methods.

Instead of manually building an event using a bean, OGNL Mappings allow you to put data that is inside of the CamelExchange into your EventParams of the outgoing event instead.

For example, if you have a Camel Header called “servicetype” and you want to map that to an EventParam called “TYPE” on your outgoing event. You can accomplish this with the following mapping:

<EventMapping destination="eventParam['servicetype']" source="In.headers['servicetype']" />

Custom Event Examples

<Event id="hello_service_logger" type="internal" description="Logs the Event Body of Events coming to the Hello-World Service" isEnabled="true">
	<EventParams></EventParams>
	<CamelEventProducer>
		<CamelProducerConfig serviceName="hello-world" feature="evtest" component="" raiseOn="all" />
		<CamelEventBuilder type="CUSTOM">
			<EventBuilder fqcn="com.attunedlabs.events.BodyEventBuilder" beanRefid="eventBodyBuilderBean" />
		</CamelEventBuilder>
	</CamelEventProducer>
	<dis:EventDispatchers>
		<dis:EventDispatcher>
			<dis:DispatchChanelId>FILE_STORE</dis:DispatchChanelId>
			<dis:EventTransformation Type="JSON"></dis:EventTransformation>
		</dis:EventDispatcher>
	</dis:EventDispatchers>
</Event>
<Event id="PRINT_SERVICE" type="internal"
		description="print service" isEnabled="true">
	<EventParams></EventParams>
	<CamelEventProducer>
		<CamelProducerConfig
		serviceName="getAllEmployee" feature="employee" component=""
		raiseOn="all" />
		<CamelEventBuilder type='OGNL'>
			<OGNLMapping>
				<Source from="CamelExchange">
					<EventMapping
		destination="eventParam['servicetype']"
		source="In.headers['servicetype']" />
					<EventMapping destination="eventParam['tenantid']"
		source="In.headers['tenantid']" />
					<EventMapping destination="eventHeader['name']"
		source="In.headers['name']" />
				</Source>
			</OGNLMapping>
		</CamelEventBuilder>
	</CamelEventProducer>
	<dis:EventDispatchers>
		<dis:EventDispatcher>
			<dis:DispatchChanelId>FILE_STORE</dis:DispatchChanelId>
			<dis:EventTransformation Type="JSON"></dis:EventTransformation>
		</dis:EventDispatcher>
	</dis:EventDispatchers>
</Event>

Service Event Options

For more detail, please see the previously mentioned examples or reference the eventframework.xsd file that is included in the /leap-framework/src/resources/ directory.

NameRequiredDefaultDescription
<Events>Y(Element) Container for all service-level event definitoins
<Event>Y(Element) Specific Event being defined. Belongs to <Events>
typeY(String) { “CUSTOM” | “OGNL”}. Belongs to <Event>
<EventParams>Y(Element) May contain multiple <EventParam> definitions for mapping static data into the Event. Belongs to <Event>
nameN(String) Name of the event param
dataTypeN(String) Type of the event param
validationRegExN(String) RegEx to evaluate the validity of a param
<CamelEventProducer>N(Element) Contains the details for generating a new event. Belongs to <Event>
<CamelProducerConfig>Y(Element) contains details about which service the event should be raised. Belongs to <CamelEventProducer>
servicenameY(String) Service for the event
featureY(String) Feature Name of the service for this event
raiseOnN(String) {“all” | “failure” | “success”}
componentN(String) Documentation the component the service is part of
<CamelEventBuilder>Y(Element) Contains the details for building an event
<OGNLMapping>N(Element) Optional, only used if the event type is set as “OGNL”.
<EventMapping>Y(Element) Used to define OGNL syntax for event building
destinationY(String) The field to map on the output. Usually this will be an EventParam.
sourceY(String) The field to map from the original exchange data. Access this data using IN syntax
fromY“CamelExchange”(String) Indicates that the values being mapped are coming from the CamelExchange
<EventBuilder>N(Element) Used with the Event type is “CUSTOM”. Contains details for the Event Builder bean that is called
fqcnY(String) The fully qualified class name of the bean to call for building an event
beanRefidY(String) Uniquely identifies the bean in Spring
<EventDispatchers>Y(Element) Contains one or more Dispatch channels to use when emitting the event
<DispatchChanelId>(String) The corresponding dispatchers id
System Event Options
Updated on September 15, 2021

Was this article helpful?

Related Articles