Personal tools
You are here: Home Idea Workspace Imp Documentation Anatomy of Typical Packaging-Shipping Jobs
Document Actions

Anatomy of Typical Packaging-Shipping Jobs

by rmoskal last modified 2006-05-24 22:40

The easiest way to figure out how to package and ship, is to look at the jobs created for each retailer. However, as these tasks constitute the primary application use cases, a little more detail is in order

My hope was to create a system in which a minimum of new code needs to be written; relying instead on prexisting tasks for operations such as creating directories, tranforming media files, creating retailer specific manifest files, and sending files by ftp.

The normal workflow is to set up the job context, by placing directives on the hash map passed to each job and then to use a common skeleton for most common tasks. Packaging tasks in which separate directories are created for each release can get by with just a ContextPreparer, and perhaps an  IXMLTransformer  for carrying out  operations on the XML Manifest files created for each release or shipment as a whole. For example, the itunes packager adds a task to the VendorManifestProducer to insert a file hashes for all the media into the xml file.

Packaging

IExtractor

A packaging job first calls a IExtractor task that creates the shipments it is to act on.  See Job System Workflow

ContextPreparer

Before anything else can happen the job context should be set .  This is done by a class usually called the ContextPreparer.  Almost every retailer specific job includes on of these, and by convention we've been putting all retailer specific classes in a package named  comp.idea.imp.service.retailername. In what follows you'll describe all the tasks and what must be done in the ContextPreparer to set them up.

Packager.

FileSystemStructureBuilder

After setting up the context, the FileSystemStructureBuilder task is usually called, this creates all the required directories for a shipment based in information on the context. This is what the connect packager ContextPreparer does in the visitShipment method  to create the root shipment directory:

PackagerHelpers. addObjectToContext (decoratedObject, PackagerHelpers.CREATE_DIR, shipmentDirName);

It does something similar in the visitRelease method  for each Release. 

The napster packager works a little differently in that it creates several directories per shipment. It aggregates the media files in a single directory, same for the graphics, and creates a single XML file in yet another directory for each shipment. It uses the visitShipment method to decorate the Shipment object in such a way that multiple directories are created:

PackagerHelpers.addMultipleToContext(decoratedObject,PackagerHelpers.CREATE_DIR, shipmentDirName);
PackagerHelpers.addMultipleToContext(decoratedObject,PackagerHelpers.CREATE_DIR,xmlDir);     PackagerHelpers.addMultipleToContext(decoratedObject,PackagerHelpers.CREATE_DIR,graphicsDir );
PackagerHelpers.addMultipleToContext(decoratedObject,PackagerHelpers.CREATE_DIR, audioDir);

Source Media File Decoding

Most packagers require the source media to be decoded from flac to wav format for encoding.  This done  by including the following  definition in the job:

<bean class= "com.idea.imp.service.packager.TemporaryFileDecoder">
<constructor-arg><ref bean="flacDecoder"/></constructor-arg>
<property name="stopProcessingOnFailure">
<value>true</value>
  </property>
</bean>  

Media File Creation

Music files are shipped to every retailer.  Often they require multiple files with different quality encodings, lengths (for preview), and even formats.  So far encodors have been created for:
  • wma files
  • atrac files
  • aac files
  • mp3 files
  • flac files
We've chosen a simple method for controlling the various encoders, we simply build up the command line for each on.  This is normally done in the visitTrack method of the ContextPreparer.  Because multiple files might need to be created, each TrackTranformerTask, is keyed to a particular value on the context. Here's an example of two track tranforming tracks.  Both produce wma files, the first is executed with the information found under the _009.wma key in the job context, the next under the _007.wma key in the context.

<bean class="com.idea.imp.service.packager.TrackTransformerTask>
<constructor-arg><ref bean="wmaEncoder"/></constructor-arg>
<constructor-arg><value>%cmdExtra% -silent -input %in%
-a_setting 192_44_2 -output %out%</value></constructor-arg>               
<constructor-arg><value>_009.wma</value></constructor-arg> 
<!--Task is run if packager specific key found on context-->
</bean>
           
<bean class="com.idea.imp.service.packager.TrackTransformerTask">     
<constructor-arg><ref bean="wmaEncoder"/></constructor-arg>
<constructor-arg><value>%cmdExtra% -silent -input %in%
-profile a128 -output %out%</value></constructor-arg>
<constructor-arg><value>_007.wma</value></constructor-arg> 
<!--Task is run if packager specific key found on context-->
</bean>

In the ContextPreparer, these are set up like this, notice additional information can be passed  for command line switches under the orginal key with a PackagerHelpers.CMD_Extra appended:

public static final String _128 = "_007.wma";
public static final String _192 = "_009.wma";

PackagerHelpers.addObjectToContext(decoratedObject, _128, targetfileBase + _128 );
PackagerHelpers.addObjectToContext(decoratedObject,
_128 + PackagerHelpers.CMD_EXTRA, cmdExtra);

PackagerHelpers.addObjectToContext(decoratedObject, _192, targetfileBase + _192);
PackagerHelpers.addObjectToContext(decoratedObject,
 _192 + PackagerHelpers.CMD_EXTRA, cmdExtra);

Consult the ContextPreparer source code for the connect, itunes, and napster packagers (the test cases can also be helpful).  You'll find examples for all sorts of operations, different bit rates, providing metadata, encoding only a portion of a file, etc.

Graphic File Encoding

This is just a variation on file encoding (ideed at bottom it's the same class that does the work).  Typically, this is a matter of changing the size and color/bit depth of the output file.  If you do not specify a context key for the ExternalMediaTransformerTask  it will pick up the information from the following key in the job context: PackagerHelpers.EXTERNALMEDIATRANFORMER_TASK. This is usually sufficient since there is usually one image per release.  You can generate multiple images by declaring multiple ExternalMediaTransformerTasks each keyed appropriately (as with the TrackTransformerTasks where multiple files are normal).

VendorManifestProducer

This task has a list of subtasks, all of which implement the IXMLTransformer interface. It is an xml pipeline with the results of each tranformation being fed to the next.  First  it marshalls an xml representation of a complete shipment graph using Castor.  Then, carries out an XSL tranform that creates a retailer specific manifest file.   Other tranforms can be inserted into this pipeline to further massage the xml manifest file.  The last transform should be the DocumentSerializer which writes the manifest file disk.  Two things need to be done to set up this task.

Any xsl parameters required by the transforms must be put under the context. Up until now this has been done in the visitShipment method like so:

context.put(XSLTransformer.class.getSimpleName(),someProps);
The name of the xml file to be written must also be specified. Here's an example of a task that is set up to create  an xml file for each release. It does this  in the visitRelease method:

PackagerHelpers.addObjectToContext(decoratedObject,
DocumentSerializer.class.getSimpleName(),
currentReleaseDirectory + File.separator + aRelease.getUPC() + ".xml");

PackagerFinalizer


As of May 2006, packagers preparing releases for shipment and  that create separate directories for each release can just rely on the the default com.idea.imp.service.packager.PackagerFinalizer.  When creating a packager that aggregates releases look at the one in the napster package.

PackagerFinalizer examines the state of each shipment, removes releases that failed packaging, sets error states etc.

Shipping

Related content

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: