(Opinionated) App Engine Template
By Chris Malek | Mon, Aug 21, 2023
PeopleTools Application Engine (AE) is batch processing tool used to execute logic against a PeopleSoft database. The programmatic logic is executed with PeopleCode language or SQL or a combination of both. In this article I want to introduce a skeleton/template application engine that you may find useful in some situations. Specifically, when your application engine just needs to execute some PeopleCode and some basic SQL.
I have found that this pattern can simplify your Application Engine programs and set the foundation for later changes that always come as the business changes.
This skeleton is useful if:
- You primarily need to only execute PeopleCode and maybe some light SQL
- This might be opening a file, reading the contents and invoking a Component Interface or calling a web service
- It could be anything that is not SQL or even some light SQL statements. Any SQL you need to run can be run in PeopleCode with SQL Objects,
- Your program has parameters defined in a run control record.
- This is NOT a requirement and there may not be any parameters.
What is the benefit of this:
- Changes to run control records are fairly insulated from your code.
- A much more simple structure. All the code is in one place (no separate run control step)
- Much easier to back-up and poor-man version control with file back-up.
- You don’t need to worry about State Records or Temporary Tables and having logic spread out over different steps and actions which can make debugging, changes and branching logic more complex. No more SQL steps to populate state records and then picking those up later. It can get really ugly.
- First we will create a new simple Application Engine program.
- There is one step and one action which is PeopleCode.
- This is the only step and action you will need and all the logic will be in this action. In general, I like to keep things simple and not have multiple steps and actions unless I really need to. Everything will be in this PeopleCode program. Of course, you can add whatever you want but I have found that often this structure is all you need.
- Go into the settings and disable restart. This is important as this type of app engine is not going to be designed for restart. Those can be very complex to create. If you need restart, this article is NOT for you. In my experience 98% of all application engines do NOT need to be designed for restart. If you are not sure, then you probably don’t need restart functionality.
- Next we will find a “State Record” to use.
- This is optional and really only provides value if you have a run control record where your process needs to read user parameters from.
- I generally like to just find an existing Derived record that is a state record that has the following fields
- In this example, I am using the record
PSPMARCHIVE_AETwhich has those two fields which I care about. You could literally choose any other record or create your own. I just like to use an existing one if I can. Since all the logic will be in a single PeopleCode program any sort of “state” can be stored in PeopleCode variables. State records are only needed if you need to pass parameters between steps or actions and we are intentionally not doing that here.
- When the application engine runs, the framework will populate the
PROCESS_INSTANCEfields for you. There is no dynamic way to get these values in PeopleCode so you need to use a state record. We will use this state record to read the run control parameters. The alternative is to create a custom state record and then a SQL step, but I am trying to remove this step as it is less code to maintain as we will see shortly.
- We set the state record in the settings.
- Generally App Engines have a run control record to pickup parameters from the user. Here I will choose a completely random one that exist because we don’t really care what the fields are on it for this specific example. When you create your own app engine following this template you will choose or create a run control record that is specific for your scenario.
- Now to the PeopleCode.
- The first section will make use of the state record to read the run control parameters.
- We define record object called
&recParmswhich will represent the run control record.
- We then create the record object with the
- We then populate the
OPRIDfields with the values from the state record and the current user context.
- The thing to notice here is that we are referencing the state record field
PSPMAARCHIVE_AET.RUN_CNTL_IDdirectly. This is because the framework has already populated these fields for us and at the time of writing there is no way that I know of to get the current state RUN_CNTL_ID.
- The thing to notice here is that we are referencing the state record field
/* Get Run Control Parameters */
Local Record &recParms;
&recParms = CreateRecord(Record.PS_ERR_RUNCNTL);
&recParms.OPRID.Value = %OperatorId;
&recParms.RUN_CNTL_ID.Value = PSPMAARCHIVE_AET.RUN_CNTL_ID;
/* The rest of your logic goes here */
/* Run Control parameters are accessed like this:
or &recParms.ANY_FIELD_ON_RUN_CONTROL_RECORD.Value */
When the above code runs the
&recParmsrecord object will be populated with the values from the run control record. You can then access the fields on the record object to get the values. For example, if you had a field called
URLon your run control record you could get the value with
&recParms.URL.Value. You can then use these values in your logic.
A nice thing here is that during development you can add fields to your turn control record and the
&recParmsobject will automatically be populated with the new fields. You don’t need to do anything else. This is a nice benefit of using this record object pattern. Alternatively, if you were using a custom state record and a SQL step to populate the run control parameters you would need to add the new fields to the SQL statement as well as the state record. This is more work and more code to maintain. Here is a random delivered SQL step that pulls run control parameters and populates a state record. Notice how the SQL statement needs to be updated with the new fields. I have always hated this approach that App Engine forces on you.
- The rest of the logic can then be code inside the PeopleCode program. So if you need to open a file, read the contents and invoke a Component Interface you can do that here. If you need to call a web service you can do that here. If you need to do some light SQL you can do that here with SQL Exect or other SQL Logic. You can do anything you want here. You don’t need other PeopleCode actions or steps or potentially even SQL steps.
What do you gain from this approach:
- Easier debugging when everything is in one place and in PeopleCode.
- I would check out our Introduction to the DataDumper Logger
- State values are stored in PeopleCode variables and not in a state record(s) so you are not having to create a field on a state record and then update the SQL statement to populate the field. This make changes and much faster and easier in my experience.
- It becomes very easy later to branch logic. Did you have a merger or the original logic changed and you need to add some simple if/then logic based on data? That is easy to do in PeopleCode. When you have huge nasty App Engine with multiple steps and actions and SQL steps and state records and temporary tables it can be very difficult to add branching logic. This is a much simpler structure and easier to maintain.
PeopleSoft Simple Web Services (SWS)
Do you need a quick way to create web services?
Introducing a small but powerful PeopleSoft bolt-on that makes web services very easy. If you have a SQL statement, you can turn that into a web service in PeopleSoft in a few minutes.
Integration Broker - The Missing Manual
I am in the process of writing a book called "Integration Broker - The Missing Manual" that you can read online.