SHEBanG enrolment plugin/module for Banner(r) LMB data import.
This enrollment plugin provides a way for Moodle to consume Banner® LMB (Luminis Message Broker) messages. This module is not an Ellucian product, and is neither endorsed nor supported by Ellucian. It is contributed by Fred Woolard.
Messages are POSTed by LMB to a configured target URL; that URL should end up resolving to $CFG->wwwroot/enrol/shebang/secure/post.php either by means of direct address, symbolic link, or Apache server configuration (e.g. alias; aliases will not work from Moodle 2.6 and later). An alternate method of import is the file upload feature.
There already is an enrolment plugin, LMB (enrol_lmb) developed by Eric Merrill that processes Banner data, and has many more configuration options and features. We used Eric's plugin for several years at Appalachian State with only a few basic alterations.
Why write a new one? Why reinvent?
There were a few reasons.
In our particular installation of Banner/LMB, we kept getting several essentially identical messages which resulted in duplicate rows in one of the staging tables. Normally not a big problem, but eventually the staging table becomes bloated with duplicates, and since this table is involved in JOINs where a singleton query result is expected. We also wanted to log each of the XML messages received, but not in the database; logging the messages in a text file is more practical for us.
Messages sent by the LMB are logged to the file-system in the Moodle data directory rather than the database; this message log file is locked exclusively while the message is being processed in order to serialize message processing.
In the case where additional data from the XML message was needed, a regular expression had to be added--most often this is simple enough given an existing pattern from which to start, but in some instances where the message format changes ever so slightly (e.g. recstatus), it makes more sense to use DOMXPath queries to extract message data.
XMLParser is used to break up the input, whether from file or posted XML, into the principle elements we want (<group>, <person>, and <membership>), and from that point use the DOMDocument and DOMXPath to query for the needed values.
Some other differences
- Messages imported from a file are not logged since there's already a source file;
- A cross-list course parent is created only when the first <membership> message for that cross-list arrives, and then it will be created by making a copy of the child course.
- The Moodle user's idnumber column is populated with the SCTID/Banner userid, rather than the Luminis sourcedid/id.
- The only cron activity is the monitor for last message arrival time. Some Moodle sites may have a very frequent cron activity (5-10 min) so it didn't seem practical to put directory/file check tasks in a common script--rather use a dedicated cron task, if needed at all, for the Banner extract/batch-file imports.
SHEBanG requires that PHP modules XMLParser, DOMDocument, and DOMXPath be loaded.
- Select the correct version of the "shebang.zip" plugin for your Moodle installation
- Unpack the .zip file into the enrol folder of your Moodle site
- Access the notifications page (Admin block->Notifications) to initiate database setup.
- Enable and configure the plugin (Courses->Enrolments->SHEBanG[Edit]).
- Configure your Banner/LMB to POST messages to the target URL corresponding to the enrol/shebang/secure/post.php file, for example: https://moodle.someuniversity.edu/enrol/shebang/secure/post.php
Important: Secure the target URL
THIS URL NEEDS TO BE SECURED IN SOME FASHION TO PREVENT UNAUTHORIZED USERS FROM INJECTING ERRANT DATA INTO YOUR DATABASE. THE METHODS FOR SECURING THIS URL INCLUDE, BUT ARE NOT LIMITED TO, APACHE HTTP AUTH CONFIGURED--IDEALLY WITH SSL--AT THE SERVER/VHOST/DIRECTORY LEVEL OR WITH AN .htaccess FILE. ANOTHER OPTION, IS TO USE THE AUTHENTICATION FEATURE IN THE MODULE, BUT THIS SHOULD NOT BE YOUR FIRST CHOICE. AGAIN, IT IS STRONGLY RECOMMENDED TO USE A SECURE SOCKET (SSL) CONNECTION IN ADDITION TO HTTP BASIC OR DIGEST AUTHENTICATION SINCE EITHER THE USERID/PWD INFORMATION WILL BE EXPOSED WHEN SENT IN CLEAR-TEXT (BASIC) OR THE HASH (DIGEST) WILL BE EXPOSED.
There is no Moodle authentication protection in the post.php since it is accessed by an external, non-interactive service where a userid/password will be configured by the Moodle server admin and shared with the Luminis admins.
If Oracle is being used, the NLS_DATE_FORMAT session setting has to be adjusted from the default. SHEBanG expects it to be set to 'YYYY-MM-DD HH24:MI:SS', but if that is not practical for your installation (conflicts with other plugins, etc.) then the format used by SHEBanG can be changed in the lib.php (DATEFMT_SQL_VALUE).
Considerations For Blocking Issues
Because SHEBanG serializes message processing using a file lock, it is possible, in some cases likely, that a blocking bottleneck will take place when a large number of messages are sent by Banner/LMB at or near the same time. To mitigate the risk of the all the Apache worker processes being occupied and blocked, and thus freezing out the application end-users, consider setting up another Apache daemon to handle LMB messages exclusively on an alternate port such as 8080. In this way you can tailor the configured number of initial, max-min spare worker processes, etc., and if these processes should become consumed, the end-users will not be impacted.
How Entities are Associated and Referenced
A staging record in the [mdl_enrol_shebang_section] table is inserted or updated, using the <sourcedid><id> value (the CRN) as the alternate key. This same value is placed in the [mdl_course](idnumber) column so that table can be queried directory. The course's (idnumber) value can not be changed after that or the association will be lost.
A staging record in the [mdl_enrol_shebang_person] table is inserted or updated, using the <sourcedid><id> value (the Luminis Id for that Banner identity, distinct from the Banner identity value). Susbsequent <membership> messages for this person will use this <sourcedid><id> so we need to use this as an alternate identifying key value. A <person> message also contains the <userid useridtype="SCTID"> value, the Banner identity, and it's this value that is placed in the [mdl_user] (idnumber) column.
So, upon arrival of a <person> message, and after the staging record is handled, the [mdl_user] table is queried on the (idnumber) column for the SCTID value--if no record is found, then an attempt is made to insert one, otherwise the found record is updated. Because other columns in the [mdl_user] table are unique (enforced either by the application or the database), a collision on email or username by prevent the insert. In such cases, manual inspection of the existing user account should be done to determine if it can be deleted (no access, no enrolments, etc.) or if it should be associated with the corresponding [mdl_enrol_shebang_person] row by placing the appropriate Banner identity value in the user's (idnumber) column.
Until any such collision is resolved, course enrollments for that person/user will fail since no association exists between the person entity and the user entity.
In versions for Moodle 2.x, an option was added allowing selection of what is placed in the [mdl_user](idnumber) column--either the SCTID value, or the Luminis Id value. The referenced [mdl_user](id) column value is now placed in the [enrol_shebang_person] table.
Where to Find
The plugin can be found in the Modules and plugins database here.