Managing product information in SDL Tridion

Product information presentationManaging product information in your CMS is always a big topic for discussion. Typically a CMS is not suited for managing product data like price and stock, on the other hand not every PIM system has the ability to manage multilingual descriptions of your products that you might want to display on your website or product catalog. So combining two systems is obviously the thing to do here. Nothing new under the sun there, but with the release of SDL Tridion 2013 we have ECL which can shed a complete new light on this topic.

The External Content Library is an API for developing Providers, Template Building Blocks and Event Handlers that communicate with an external system and expose its multimedia content in SDL Tridion. But that does not mean it is limited to only multimedia content, because we have the option to expose external metadata as well. So when I was trying to find the limits of what I could do with ECL (and what I shouldn’t try), I came up with an ideal scenario, being the realm of product information.

Let’s take a look at what we have in a typical PIM system, it will contain all your product related information like SKU, dimensions, price, stock and a whole lot more information which should never have to be translated. Typical stuff, which we don’t want to copy over to our CMS, but we do need to have it available on our product catalog on the web. Now if you also have an image or icon available for every product in your PIM system, then we could use that as the basis for our ECL integration (together with the unique id of the product of course). Through the ECL provider you will now have the ability to show a complete list of all your products in your PIM system, visualizing that using the image or icon. It can even be made searchable and can sort your products in a structure similar as the one you have in your PIM system. ECL product overview

The ECL provider will make all the product information from the PIM system available in the External Metadata tab of the ECL Component, which will make it directly available for use in templates (i.e. on your Page). Now for the marketing information that needs to be added to this product (which we want managed in SDL Tridion so it can easily be translated in our BluePrints) we can use the normal Metadata of the ECL Component. This basically is the same as adding Metadata to a Multimedia Component and it will be directly available when you open your ECL Component (allowing you to localize and translate in BluePrinted Publications). We can then also start tagging our products with SDL Tridion keywords, so we can add relations between our (marketing) information in our CMS (i.e. articles, blog posts etc.).

ECL Component
ECL MetadataPIM system data

So with a relatively simple ECL provider we have completely integrated our PIM system and made all its data directly available for use in our CMS managed product catalog. And the marketing information in our product catalog is manageable from our CMS and can be translated using our integrated translation technology.

Fixing Tridion Content Delivery Deployment Errors: “Unable to load DLL ‘xmogrt’” and “System.BadImageFormatException”

I’ve recently helped a colleague with an issue when trying to deploy our Tridion DD4T .NET project to a Dev machine.   The issue was a “System.BadImageFormatException” related to the Tridion’s Java wrapper Juggernet.  

However, at first we were getting the error: “Unable to load DLL ‘xmogrt’: The specified module could not be found. (Exception from HRESULT: 0x8007007E)”.  It was weird because on my VM, with the exact same files in the bin, it ran fine.  Turns out, it worked on my VM because my %TRIDION_HOME% was set with the file in it.  

We followed the answers in this post (which you’ve probably read already before coming to this article: http://stackoverflow.com/questions/13918310/unable-to-load-dll-xmogrt-from-tridion-metadata-query) and placed the xmogrt.dll and its dependencies in the bin.  However, we now ended with the “System.BadImageFormatException”:

An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

Server Error in '/' Application.

An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

Here is how we solved the problem: 

  1. Uninstall all Java (you may have several versions of the JVM installed.  Uninstall all of them)
  2. Install the latest Java 6 JRE (though we installed the JDK 1.6_45).
  3. Check that it’s successfully installed by typing java –version from the command line.
  4. Verify that ‘xmogrt.dll’ is in the bin folder of your app and is not corrupt.  In our case the ‘xmogrt.dll’ file was only 840kb for some reason.  It should be 1630 KB.
  5. Do an iisreset.

Here is the long answer

xmogrt.dll is an unmanaged C++ assembly that is largely the Juggernet Java wrapper used by Tridion (if you’ve wondered about those jar files in the bin/lib).  This compilation version of this DLL must match the CPU instructionset, i.e. x86 or x86-64).  It must also match the latest Tridion-supported Java version, i.e. 1.6_xx x86 or 1.6_xx 64-bit (of java 1.7 for Tridion 2013).  If there is a mismatch in either, then you’ll receive the “System.BadImageFormatException” error.Look at the Juggernet documentation for more details about how Juggernet works and this error here: http://codemesh.com/products/vfour/tutorial/dotnet/v3/L_02_run_app.html, scroll down to the section “Common Runtime Issues You Might Encounter”.  Also, the Juggernet architecture diagram (found here: http://codemesh.com/products/vfour/dotnetruntimes.html) provides a nice deal of insight into understanding how the Tridion CD API is converted to .NET.

 

Issues with the TridionRsaContainer registration!

Scenario

We’d copied a CM instance (VirtualMachine) from the PRD environment and placed this into the UAT environment, all configurations done as we’d tested and expected.

To avoid getting the error stating that the [clientUATdomain]\MTSUser does not have access to the tridion.security configuration setting we executed the TridionRsaContainer command

aspnet_regiis -pa "TridionRsaKeyContainer" "[clientUATdomain]\MTSUser"

This failed with the MTSUser. On confirming we had the correct [domain]/username/password and further investigation we found that no-one knew the actual account that had been used to install SDL Tridion 2011 CM. We needed this account so we could log into the UAT CM machine in order to give the MTSUser access to the tridion.security configuration setting. This is because this config setting is protected using this windows functionality : http://msdn.microsoft.com/en-us/library/yxw286t2(v=vs.100).aspx

Solution
We could see that file in question is actually a file in c:\programdata\microsoft\crypto\rsa

This file is accessible only to a small number of users (the production domain mtsuser had access to it). So we tried this:

  • log in on the PRD machine as the production domain mtsuser
  • export the rsa key via this command
aspnet_regiis -px "TridionRsaKeyContainer" keys.xml -pri

We then placed this keys.xml file onto the UAT CM box and then executed the import command

aspnet_regiis -pi "TridionRsaKeyContainer" c:\temp\keys.xml

and finally, the following command

aspnet_regiis -pa "TridionRsaKeyContainer" "[clientUATdomain]\MTSUser"

So, on booting up the CM Browser… boom… We got an error in the GUI after a quick dig into the respective ‘Tridion Configuration’ error in the Event system … we then executed

aspnet_regiis -pa "TridionRsaKeyContainer" "nt authority\network service"

Quick restart of the services and all is well again.

The motto of the story – DO NOT ‘LET SLIP‘ WHICH USER INSTALLED THE CM - especially if you want to clone the machine during a setup!

If you’ve had a similar experience we’d be very interested to hear if there are other ways around this – other than simply re-installing the CM with a noted user :)

Special thanks to Harald Hoffelinck on this solution!

How to Debug Tridion Workflow

With all the anticipation and excitement of the new 2013 Bundle Workflow coming out, I thought I’d dig into my notes about the regular ol’ single item workflow for those still on pre-2013 systems.  In this post I discuss some lessons learnt about debugging workflow.  Note, this is when I was working with Tridion 2009 SP1, but the same should apply all the way up to Tridion 2011 SP1 HR1.

There are a few methods available for troubleshooting your workflow code.  There is no way to use a real debugger on the Workflow VB script since there is no way to set breakpoints in the Visio Automatic Activity Script editor.  You can instead keep your VB code as light as possible and keep your workflow logic in C#.  

Attach to Process and Set Breakpoints/Debug Normally

To do this, your code must be outside of VBScript editor in a C# Class Library DLL as mentioned above.

One approach to this is to write a stand-alone executable that you call via the workflow VBScript.  This stand-alone exe would need to impersonate a user on the CM server, but then can do anything you want.  And since this is a stand-alone program running from some directory on the server you can deploy it with a PDB file and attach to its process.

Another common practice of writing workflow code is to write a DLL then register it as a COM+ object or drop it into the GAC.  Note that with the GAC approach you can’t easily put the PDB into the GAC with it (at least for the x86 architecture; for x64 there is a folder deeply nested somewhere in Windows where you’ll see your DLL,so you can put your PDB next to it). Then we simply use Process Explorer (http://technet.microsoft.com/en-ca/sysinternals/bb896653.aspx) to find the process using your DLL and attach to it.

Find Process using a DLL via Process Monitor

Print Logging Statements

If you have some logistical challenges with being able to attach to a process, then we need a way to print debug output statements somewhere – the old fashion way of debugging.  This “somewhere” can be two places:

  1. CM Server’s Event Viewer.
  2. The finish message.  However there is a character limit on how big this can be, and your code may never reach the finish statement.

Using Tridion’s Logger to Print Debug Output

This is the sure way of logging your debug output.

If you’ve moved your workflow code away from VBScript into a C# DLL, then:

Logging logger =  TDSE.GetLogging();
logger.LogEvent("my debug output", EnumSeverity.severityError, EnumEventCategory.EVENT_CATEGORY_WORKFLOW);

You can do the same thing right from the workflow VB script:

Dim logger
Set logger = TDSE.GetLogging()
Call logger.LogEvent("my debug output", 1, 22)

The log messages will appear in the CM server’s Event Viewer log.

If you don’t have sufficient access to the CM server, then you can use the method listed below.  However, in order to effectively develop Workflow you need to get that server access and the ability to freely see the CM’s Event Viewer.  So convince your PM or IT people to grant you that access or you’ll be burning a lot of rubber spinning wheels rather than getting traction.

Using the Finish Message to Print Debug Output

This is a really cheeky approach to debugging.  Do it as a very last resort or while waiting for IT requests to get processed instead of twiddling your thumbs.

Start with one line of code which is:

Call FinishActivity("my debug output", "Next Activity’s Title or TcmId")

Add some code before this line.  Any output you want to see should go in “my message” parameter of FinishActivity.

Note: there is a character limit to how large the finish message can be.  This is driven by the database column size.  So if you try and spit out too much debug output you’ll get an error.

So be warned.  This is a way to do some quick one off printouts, but don’t rely on this as the main way to debug your code (Although back in the day I’ve gotten through coding a massive workflow with this approach before I realized TOM provided a logger, duh!)

Again, a much better way to log debug output is to use the Logger that comes with TOM.

 

Some Workflow Errors and Things to Watch Out For

Position in the Workflow

CurrentWorkItem.ActivityInstance.Position

This one was fun to debug…  Actually if you carefully read the TOM API, which I did not, it provides an example of how to find out how many more activities are left in the flow.  There actually is a comment in the sample code that mentions that this works only if there are no loopbacks.  Be warned!  If you have a case where you need to find out what the previous activity was or what the next activity is, you can’t rely on the position that Tridion gives you because if you have a rejection of content that takes you back a few steps, the position still gets incremented.

Object reference not set to an instance of an object

An error occurred while executing the Workflow script.

The Script Engine returned the following information:

SOURCE:
  Line = 41
  Column = 0
  Number = -2147467261
  Source = ContentBloom.Tridion.Workflow
  Description = Object reference not set to an instance of an object.
  HelpContext = 0
caused by: ContentBloom.Tridion.Workflow
and description: Object reference not set to an instance of an object.
Source:
LogScriptError

This isn’t the VB dying; it’s a null reference exception somewhere in your C# code.  Unfortunately the error doesn’t tell us where – well it tell us which function is being called by VB and its line number – so throw in a bunch of logging statements into that C# code and see where it bugs out.

Application uses a value of the wrong type for the current operation.

Unable to finish the Workflow Activity (tcm:12-671-131104)
Application uses a value of the wrong type for the current operation.

The CM server’s event viewer may show a few errors with some being a blob of XML.  If you look closely you’ll see this message.  What it means is that the size of the FinishMessage is too big.  The database column for this field has reached its limit.

What’s new in SDL Tridion 2013

Last week SDL / Nuno Linhares gave a fantastic presentation to the SDL Tridion community (watch online and slides available) about the cool new technical features available in SDL Tridion 2013.

I’ve provided a little summary after the jump, but really you should be clicking the link above and watching this first major presentation for SDL Tridion 2013.   Thanks to all involved in the webinar :)

Continue reading

Simple Release Management with SDL Tridion 2013 and Bundles

I was fortunate to have a preview version the up and coming 2013 release of SDL Tridion to play with. One new feature is Bundles, which is basically a new type of organizational item, which allows you to group together related items, and do operations on them as a whole. Typically this would be putting it through workflow, or publishing them all together in a single transaction, but one nice thing about them is that you can use them however you want to, just add items into a bundle, and use it however you need to.

The new release of Content Porter will also be bundle-aware, which got me thinking that there should be an easy way to keep track of changed items during development using bundles to avoid the pain of keeping track manually. It turns out to be really easy using the Event System.

Continue reading

Content Porter: The partner transaction manager has disabled its support for remote/network transactions

I recently installed Content Porter 2009 SP2 Server and Client on the same server as the SDL Tridion Content Manager(CM) 2011 SP1.

Exporting worked totally fine, the zip was created and sat there just dying to be imported… so I thought ‘great, just a quick test of importing and I’m done’.

Continue reading

Extracting Keywords from PDF on Multimedia upload

I came across a nice library that allows you to create and manipulate PDF documents. Apart from creating PDF documents from scratch, you can also read existing ones, convert XML to PDF, fill out interactive PDF forms, stamp new content on existing PDF documents, split and merge existing PDF documents, and much more. The best part of it is that there is a C# port available which is open source, it’s called iTextSharp. Now I haven’t explored all features of it, like PDF creation, but so far it already looks very usable.

Continue reading