As we see more adaptation of our PMA.core SDK libraries with various OEM vendors now, we also have the opportunity to conduct broader testing. The various SDKs (PHP, Java, Python) are now used in many more scenarios, leading to bug reports, new features, richer methods calls with more arguments… all good things. We aim to please and are pushing updated revisions to our GitHub repository at a regular pace now. Very exciting!
Connecting to PMA.core
Here’s a simple example in Python: You connect to a PMA.core instance and retrieve an initial list of available root-directories. It’s three lines of code:
from pma_python import core
core.connect('https://server/pma_core_location', "user", "s3cr3t")
core.get_root_directories()
In PHP, it’s similarly trivial:
require_once "php/lib_pathomation.php";
Use Pathomation\PmaPhp\Core;
Core::connect("https://server/pma_core_location", "user", "s3cr3t");
print_r(Core::getRootDirectories());
And in Java:
import com.pathomation.Core;
Core.connect("https://server/pma_core_location", "yves", "s3cr3t");
Core.getRootDirectories();
The output is supposed to be something like this (PHP):
Bug spotting
Embedded in a Jupyter notebook, the output of the code looks like this:
However, occasionally, people would tell us that the code mysteriously stopped working, and they were getting this:
We couldn’t figure it out right away. It’s a typical “sometimes it works, sometimes it doesn’t”; the most frustrating kind of bugs.
Almost by accident we found out what the problem was. By turning on the debug_flag, we get a better understanding of what’s happening.
As it turns out, the authentication call goes through just fine. But the SessionID passed on to the get_rootdirectories() API call, doesn’t match the returned sessionID from said original call.
Under the hood of the SDK
We designed the interface of the SDK for convenience. We want end-users to pick it up as quick as possible (keeping Larry Wall’s “laziness”, “impatience”, and “hubris” virtues in mind, too).
This means that once you connect to a PMA.core instance, and only a single PMA.core instance, you can pretty much ignore the returned SessionID value and just use the SDK functions with default arguments; the SDK is smart enough to figure out that there is only a single SessionID in play anyway, and retrieves that automatically from an internal HashMap-like cache, passing it on to when the eventual PMA.core API are invoked. It’s convenience, it’s how we thought we could make our interface programmer-friendly.
Intended use
The approach works find in a scripted scenario like Jupyter Python scripts, where you use a PMA.core SessionID for the duration of your script, and then you’re off doing something else again.
In different contexts however, like our AEM plugin (which in turn relies on the PMA.java SDK), it’s possible for a SessionID to be suspended in between subsequent SDK/API calls.
And that’s when the problem occurs.
The solution
The solution is relatively simple: it suffices to capture the returned SessionID from the authenticate call, and pass that on explicitly to subsequent methods. Like this:
Now you can see that the SessionIDs match up, and the output remains as expected, even if the Session would be somehow terminated in the middle of the processing flow (as you as you keep re-authenticating at least).
Also note that in the back-end, the SDK now simply keeps track of two SessionID.
One of which is expired, which the SDK doesn’t know. But that’s all right, as long as you make sure that the correct SessionID is passed along explicitly.