Skip to content

Commit

Permalink
DateLastModifiedEvent framework documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsully83 authored Dec 2, 2020
1 parent f6691c0 commit f092266
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,18 @@ Most of the functionality provided by the ScheduledTasksTraversers and associate
```
That should be used to perform updates on entities in a scheduled tasks workflow. You pass in the entity you are about to make modifications to, which the helper object then makes a deep copy of using [Kryo](https://github.com/EsotericSoftware/kryo) and holds onto in a Map, returning the deep copy. Then, at the end of every scheduled tasks workflow, the code that executes each of your `EventTask`s will loop through this map and perform an update call on each entity in it. This allows you to make modifications to the same entity in different classes without making multiple API calls. After calling ``getOneEntityToSave``, any modifications made to the object returned will in turn be made to the copy being held by the helper object.

## Date Last Modified-based scheduled tasks
In some cases it may make more sense to write a scheduled task that operates off of a Bullhorn record's `dateLastModified` property, as opposed to writing a subscription-based scheduled task. An example of such a task would be one that runs every 5 minutes, and queries for JobOrder records that were added or updated in the last 5 minutes (i.e. where `dateLastModified > now() - 5 minutes`), and then performs some kind of business logic on them, perhaps updating an associated record such as the ClientContact. In such cases the starter-kit provides a framework that handles the interactions with the REST APIs required to retrieve such records, as well as managing the scheduling of the tasks themselves.

In order to write such a task, you would create a class (typically in `com.client.custom`, and annotated with `@Service`, so that it lives in the Spring Application Context) that extends the appropriate `${entityName}DateLastModifiedEventTask` (e.g. `JobOrderDateLastModifiedEventTask`). Doing so will force you to implement a constructor that takes a few parameters:
- `Integer intervalMinutes` - the number of minutes the task should look back to find new records, as well as how often it runs. Required
- `Set<String> fields` - the fields that should be returned/passed to the REST APIs. Optional, defaults to "id"
- `IncludeDateAdded includeDateAdded` - whether to also include dateAdded in the query the is constructed to pull records (i.e. the where clause gains an `OR dateAdded > now() - intervalMinutesAgo` term). Optional, defaults to YES

Finally you will need to implement the method to execute your business logic. This method is called `process` and takes one parameter, an instance of the entity that was modified (e.g. in our example above, it would take a `JobOrder` object), which will be populated with the fields passed in the `Set<String> fields` constructor parameter.

The framework itself runs every minute by default (controlled by the `date.last.modified.cron.expression` app parameter). The `com.client.core.dlmtasks.DateLastModifiedEventProcessing` class and other related ones @Autowired all instances of any `${entityName}DateLastModifiedEventTask`s in the Spring Application Context at app startup. Every minute it checks to see if any of those tasks should execute, and if so generates a `/query/` or `/search/` REST call using the properties passed in the class's constructor, and for each object returned it runs the `process` method. It minimizes REST calls made by making them in batches whenever it can...if there are two `JobOrderDateLastModifiedEventTask`s that both run every 5 minutes, it will only make the REST calls needed once. The first run of every task is determined by it's `intervalMinutes` property, and should occur at `intervalMinutes` past the hour, or any multiple of the value thereafter (e.g. in our example it would run at :05, :10, :15, whichever comes next after the app starts up)...specifically it runs when `now().getMinutesOfHours() % intervalMinutesAgo === 0`. Subsequently the framework keeps track of the last time each task ran and uses that value to determine when each task should be executed.

## Form triggers (deprecated, S-Release only)
Form triggers are a way for you to customize how a record is saved in the Bullhorn CRM. For each of the main entities, there is both an 'add' form trigger and an 'edit' form trigger. During the configuration of a given trigger, you provide a URL to Bullhorn that is called upon saving the form. Bullhorn passes all information on the form to the URL in the form of an HTTP POST request. The code receiving the request can reply in one of two ways, either stopping the save with a provided error message, or modifying the data that is about to be saved. The following form triggers are available for customization:
- Candidate (Add/Edit)
Expand Down

0 comments on commit f092266

Please sign in to comment.