Sunday, April 14, 2013

Folder Existence Workaround for Alfresco Solr's "eventually consistent" nature

I'm using Alfresco 4.1.2 configured with the Apache Solr search engine.  When uploading new documents into the repository, indexing is asynchronous so there is a period of time for the index to "catch-up", which is what the term "eventually consistent" means.  This can be quite burdomesome when you are expecting a folder to be recognized in a search.  Since Alfresco 4.0 and higher, the default search engine configured uses Solr.

What to Solve

  • You want to store documents in a date folder hierarchy in Alfresco based on when it was imported
... > documentLibrary > 2013 > 04 > 13 > cherryshoe1.tif
                                       > cherryshoe2.tif
  • Two documents came in on the same day right after the other, the code you write will need to check if each date folder portion has been created yet (and create it if it doesn't)
The Problem
  • You may think a call to Alfresco's Java FileFolderService Foundation API search function for folder existence is good enough.  It's not.  You will eventually get a race condition where the call to searchSimple will return null, you then try to create the folder, but you get a FileExistsException.

The Possible Solutions

  1. If you're using Alfresco, you can use the RetryingTransactionHelper.  Here's some documentation on how to do that.
  2. Roll your own workaround:
    • Call FileFolderService.searchSimple first, most of the time this will work just fine in retrieving an existing folder
    • If it doesn't work, then it'll return null
    • Go ahead and try to create the folder now
    • If the folder exists, then you'll get a FileExistsException
    • When that happens, do a FileFolderService.searchSimple inside that catch to retrieve the existing folder
    This is a simple, yet awesome, workaround for the problem. This solution works where the folder doesn't exist yet AND when the folder already exists.

    The resulting code looks like this:
        public void createFolder(NodeRef parentContainer, String newFolderName) throws Exception {
            NodeRef folderNodeRef =  
                    fileFolderService.searchSimple(parentContainer, newFolderName);
            if (folderNodeRef == null) {
              try {
                folderNodeRef = fileFolderService.create(
              } catch (FileExistsException ex) {
                folderNodeRef =  fileFolderService.searchSimple(parentContainer, newFolderName);

No comments:

Post a Comment

I appreciate your time in leaving a comment!