Blog

Q: Why should I test my CMIS application against multiple repositories?

by | May 26, 2011 | Alfresco, Design, SharePoint, Software Development | 2 comments

A: To uncover my hidden assumptions!

Let me tell you a story about SharePoint, Alfresco, design choices, and downloading files.

My Java-based application uses SharePoint 2010 to store files.  CMIS is the obvious tool for my app to talk to SP 2010, and in fact, CMIS and SP2010 work just fine together, as you may have gathered from my colleague Tim Lisko’s last few articles.

So it came time for me to write the download feature, thus allowing users to download the files stored in SP2010 from my application.  Chemistry makes it very easy to retrieve a file object by ID:

@Override
public InputStream getFileContentStream(Session session, String objectId)
{
try
{
Document file = (Document) session.getObject(objectId);
ContentStream csFile = file.getContentStream();
InputStream retval = csFile.getStream();
return retval;
}
catch (CmisBaseException cbe)
{
throw new AcmRepositoryException(“Could not get file contents”,
cbe);
}
}

So I said to myself: OK, I’ll just construct a URL including the CMIS object ID, then I’ll pass that object ID straight through to my Java method.

All you guys that have used CMIS against both Alfresco and SharePoint (hi Colin!) know what’s coming next.

SP2010’s object ID looks like this: 42-512.  So my URL’s looked like this:

https://<host>/<context>/docs/download/2316/42-512

No problems here!  A nice valid URL, and my download code worked great!

So yesterday, I had an idea (actually, my boss had the idea). Let’s stand up the app against Alfresco!

Alfresco’s object IDs turn out to look like this:

workspace://SpacesStore/ecd60ff9-adbb-45fb-824d-9bc93aa61b0f

Which turned my download URL into this grim-looking thing:

https://<host>/<context>/docs/download/2316/workspace://SpacesStore/ecd60ff9-adbb-45fb-824d-9bc93aa61b0f

I’ll leave what happened when I clicked that link to your imagination (hint: it wasn’t pretty!).

Since I wanted to be up and running on Alfresco pretty quickly, I applied a short-term fix: I replace the colons and slashes in the object ID with strings that should not be part of any real object ID, and my download controller reverses the process.  Now my URLs look like this:

https://<host>/<context>/docs/download/2316/workspace-c!–s!–s!-SpacesStore-s!-ecd60ff9-adbb-45fb-824d-9bc93aa61b0f

The good: the download code works again.  The bad: I shouldn’t have to encode and decode my own download URL this way!  The ugly: as you can see, the aesthetics of the above URL leave a lot to be desired.

The long-term fix (by “long-term” I mean “by Monday”) is to not place the object ID in the URL in the first place, and use an opaque sequence-driven numeric database ID instead.  Then all my URLs will look like this, no matter what repository is in use at the moment:

https://<host>/<context>/docs/download/2316/42

Why didn’t I do this in the first place?  Well, I certainly should have.  For the most part I would never use a natural key such as the CMIS object ID in this situation.  I’m pretty sure I was trying to avoid a database lookup.  In the end I needed to do a database lookup anyway, but it never occurred to me to rethink my earlier design choices.

Categories

2 Comments

  1. Tim Lisko

    I’m not quite following – where were you storing your object IDs before if not in the database? Are you still using the alfresco object ID in the getObject method? How is that different in the generated URL than before?

    Reply
  2. David Miller

    The object ID is in the database now, and the Alfresco object ID is the parameter for the getObject method. The problem was my decision to put the object ID in the download URL. The reason that was a bad decision is vendors are free to use any representation for their CMIS Object IDs. As you can see, Alfresco chose to use a full URL for their object ID. Placing a full URL into a path component of another URL doesn’t work that well! So what I should have done from the start is just put a database numeric key in the download URL, and then do a lookup to find the CMIS object ID.

    Reply

Submit a Comment

Your email address will not be published. Required fields are marked *