First create a working pom and directory structure for your distribution module. I've found it easiest to copy the streaming distribution module and modify, just make sure to edit the pom.xml and OSGI-INF files!
pom.xml
Create a working pom.xml maven project file by basing it on an existing distribution module and changing names and add dependencies. If you have any runtime depenencies make sure to add a line to maven-bundle-plugin configuration like the following after the Service-Component element:
<Embed-Dependency>fedora-client;inline=true|jersey-client;inline=true</Embed-Dependency>
OSGI module definition
Create a OSGI module definition file in src/resources/OSGI-INF by basing this on an existing OSGI module definition xml file and changing names where necessary. Later you may need to add references to other matterhorn OSGI modules:
<reference name="WorkflowService" cardinality="1..1" interface="org.opencastproject.workflow.api.WorkflowService" policy="static" bind="setWorkflowService" />
Distribution Service
Your distribution service should be defined in a class that extends AbstractJobProducer and implements DistributionService. Again it is probably easiest to base this on an existing implementation. First carefully replace all class names, package names, and other strings containing the distribution name with appropriate names for your service. Now take a look at the activate method. This is where configuration and initialization should happen. For example, you can read from the common config file (conf/config.properties):
hydrantUrl = StringUtils.trimToNull(cc.getBundleContext().getProperty("org.opencastproject.hydrant.url"));
Next are the distribute and retract methods that return Job objects. These methods only create Job objects that are operated on by other methods so not much should be changed there except error handling.
The two methods that do the real work are the distribute and retract methods which take a job, mediapackage, and elementId string. The distribute method should do the actual work of transferring the element. At the end of the method you should create a media package element to represent the newly distributed element and return it. The retract method should do the actual work of removing the element from the distribution channel (if possible) returning the element that was removed.
Rest Endpoint
This lives in a directory called endpoint where your DistributionService lives (e.g. src/main/java/org/opencast/distribution/fedora/endpoint/FedoraDistributionRestService.java). All you need to do a clone of an existing implementation is change class and package names.
Compiling
Compile your module with maven. Note that the compilation will also run tests (if any exist) and check code style against Matterhorn's practices.
mvn clean install
Installing
Installing is easy to do even with a running Matterhorn instance. All you need to do is run maven with a deploy directory that points to your felix instance:
mvn -DdeployTo=/opt/matterhorn/felix/matterhorn
Adding your workflow step to the conductor
First create a OSGI module definition in matterhorn-conducter/OSGI-INF/operations/. Basing it on an existing operation definition should require only changing the name of the module. Add this definition file to the list of operation files in Service-Components element under the maven-bundle-plugin configuration in matterhorn-conductor's pom file. Finally deploy it to felix:
mvn clean install -DdeployTo=/opt/matterhorn/felix/matterhorn
Modifying a workflow
See Matterhorn's documentation about creating workflows. Define a new workflow that incorporates the new module and restart Matterhorn to test it out. Matterhorn will try to autoload the workflow but sometimes it gets confused. If basing your workflow off an existing one make sure to change the id!