Hacking the Tridion UDP Library

Home > Blog > Hacking the Tridion UDP Library

With the introduction of Tridion Sites 9.5 and Tridion Docs 14 SP2, there is a new set of UDP libraries (i.e. content delivery libraries), which includes JAR files such as these:

  • udp-datalayer-11.5.0-1095.jar
  • udp-data-model-compatible-11.5.0-1044.jar
  • udp-common-config-legacy-11.5.0-1055.jar
  • etc.

Note that some, but not all, of these JARs may be available in the SDL Maven repository, as of December, 2020. However, you can also pull these from your content delivery server(s), if necessary.

Sometimes, products are so new that there may still be kinks or issues with backward compatibility. This is fairly normal and is usually worked out through hotfixes and the like. Well, this appears to be exactly what we recently encountered while upgrading to Tridion Docs 14 SP2 from version 13. Similar issues would likely be encountered upgrading to Tridion Sites 9.5 from an earlier version.

We have a storage extension integrated with our deployer, that we originally implemented for Tridion Docs 13, following the standard procedure. In our case, we needed to operate on Tridion Docs publications, so we were using the Publication DAO parent classes (as opposed to the Page DAOs used in the documentation):

public class MyPublicationDAO extends JPAPublicationDAO implements PublicationDAO

All was working fine in Tridion Docs 13 – when we published a publication from Tridion Docs, we could see the publishing event log with all steps successfully completed, the deployer log looked fine, we could see our publication successfully sent to the broker database, and our storage extension code was getting reached, which was simply responsible for sending off a publication ID notification to an external system.

Now, when we upgraded to Tridion Docs 14 SP2, we naturally started by updating the UDP JAR versions in our build to match the versions used by our deployer. Our code built fine and we deployed our new storage extension JAR for testing. What we saw is that, while publishing still appeared to work, our storage extension code was not getting reached, which we could see by inspecting the deployer log to determine that none of our log statements were being logged.

At this point, scratching our heads, we tried many, many (many!) things. Nothing worked. We tried reverting the JAR versions, adding more JAR files, overriding different Publication DAO methods, changing the base classes (i.e. from JPAPublicationDAO to JPABaseDAO), etc. etc. Nothing worked. I even tried siccing The Destroyer (Harald Hoffelinck) on it.

We started inspecting the JAR libraries, and although we could not pinpoint the root cause of the issue, it was clear that there were significant changes in the code between versions 11.0.0.1024 and 11.5.0.1095:

From this, we inferred that there was very likely an issue or discrepancy with the latest JARs. While RWS is certain to fix this (if there is indeed an underlying issue), we were under a tight schedule and needed at least a workaround, fast! Time to get creative…

We started inspecting the deployer logs, to gain a better understanding of the DAO processes. We were looking for another item type, other than Publication, that was logging correctly to the deployer log. Searching through the logs, we could see many examples for JPAPageDAO:

However, this wouldn’t work, because for a given publication, multiple pages get processed. We needed an item type that only gets processed once per publication.

We could see that JPAItemDAO was a candidate. It was being called once for each publication that was published, and it had some methods that we could potentially override and use to retrieve the publication ID value that we required for the core functionality of our storage extension:

Unfortunately, item was not one of the available type mapping values required for our configuration.

Finally, we came across the JPATaxonomyDAO. Bingo! This gave us the solution we needed – it had an existing type mapping value and it was invoked once per publication (actually twice, but we were able to add some logic to determine which call to use to process our publication). In the end, our solution looked something like this:

public class MyTaxonomyDAO extends JPATaxonomyDAO implements TaxonomyDAO

And the methods we chose to override, for publishing and unpublishing, respectively, were:

  • storeListOfItems(List<TaxonomyItem> taxonomyItemList, int publicationId, int taxonomyId)
  • removeByNamespaceAndPublicationId(int namespaceId, int publicationId, String entityName)

The idea is to override these methods and for each, call the super class’s version of the method, then add some custom logic. This way, none of the existing functionality is affected, in theory:

I would love to hear some suggestions on alternative ways to do this.

A special thanks to my colleague, Saurabh Gangwar, who also contributed to this solution.


Related Posts