Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: adding a TOC

Tao of DSpace Services

Table of Contents
minLevel2
outlinetrue
stylenone

Introduction

During the last DSpace Committer meeting, I was prodded to start to show the community how one uses the Service Manager with some real world examples,  I've decided to start to create a few of these HowTo's to assist you in learning to use the DSpace Services in intelligent ways.  I had this little project floating around for some time and I decided it was something I could get down on paper fairly quickly for you.  DSpace Services are about using Spring to Simplify your development life. And for our first example showing how to create services we will refactor the DSpace Launcher to no longer utilize the launcher.xml and instead load configured Commands from a spring configuration.  The result of this approach will allow for Addons to easily provide additional commands into the launcher without having to physically alter a configuration.xml file in a config directory.  To start with we will review the ScriptLauncher and discuss the problems that exist with it. For a full view of the source please see: ScriptLauncher.java

...

We will do this initial example directly in the dspace-api project so you do not get sidetracked in terms of dealing with Maven poms....

Step 1: Domain model

Command

...

Command holds the details about the command we will call. Notice it doesn't parse any xml and most importantly it does not instantiate any Step directly, that is decoupled from the Command and we will show you later how it is assembled. All Commands do when getting created is sit there like a good old JAVA Bean should. It just "IS"

...

This location allows us to "augment the existing services without actually overriding them", we generally reserve this for the core dspace services like RequestService, ConfigurationService, SessionService, etc

Wiki Markup

...

spring-dspace-addon-\[a unique name\]-services.xml

...

This location allows us to "override" the XML loading a specific service by overwriting its configuration in one of our own
Now to show you our Launcher Service. The trick here is we will use a feature in Spring called, autowire byType, it will collect all the Commands and wire them together for us, not matter the type. I'll save you having to view the whole file, you can see it here if you like .

...

One of the luxuries we get from using the autowire byType in our spring configuration within the ServiceManager, is that now we can allow others to toss in their commands regardless of what they are named we just need to know that they implement our Command interface and provide Steps we can execute.  For instance, to introduce a command that will allow us to index discovery or operate on teh statistics indexes, we can, in our Discovery and Statistics Addons_ add additional src/main/resources/spring/spring-dspace-addon-discovery-services.xml_, do the following:

Discovery (dspace/trunk/dspace-discovery/dspace-discovery-provider/src/main/resources/spring)

Code Block
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-2.5.xsd">

   <bean class="org.dspace.app.launcher.Command">
      <property name="name" value="update-discovery-index"/>
      <property name="description" value="Update Discovery Solr Search Index"/>
      <property name="steps">
        <list>
          <bean class="org.dspace.app.launcher.Step">
             <property name="className" value="org.dspace.discovery.IndexClient"/>
          </bean>
        </list>
      </property>
    </bean>
</beans>

...

Code Block
<?xml version="1.0" encoding="UTF-8"?>
<!--

    The contents of this file are subject to the license and copyright
    detailed in the LICENSE and NOTICE files at the root of the source
    tree and available online at

    http://www.dspace.org/license/

-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">


    <bean class="org.dspace.app.launcher.Command">
        <property name="name" value="stats-log-converter"/>
        <property name="description" value="Convert dspace.log files ready for import into solr statistics"/>
        <property name="steps">
            <list>
                <bean class="org.dspace.app.launcher.Step">
                    <property name="className" value="org.dspace.statistics.util.ClassicDSpaceLogConverter"/>
                </bean>
            </list>
        </property>
    </bean>

    <bean class="org.dspace.app.launcher.Command">
        <property name="name" value="stats-log-importer"/>
        <property name="description" value="Import previously converted log files into solr statistics"/>
        <property name="steps">
            <list>
                <bean class="org.dspace.app.launcher.Step">
                    <property name="className" value="org.dspace.statistics.util.StatisticsImporter"/>
                </bean>
            </list>
        </property>
    </bean>

    <bean class="org.dspace.app.launcher.Command">
        <property name="name" value="stats-util"/>
        <property name="description" value="Statistics Client for Maintenance of Solr Statistics Indexes"/>
        <property name="steps">
            <list>
                <bean class="org.dspace.app.launcher.Step">
                    <property name="className" value="org.dspace.statistics.util.StatisticsClient"/>
                </bean>
            </list>
        </property>
    </bean>

</beans>

Summary

So in this tutorial, I've introduced you to The ServiceManager, how to rethink your approach using Spring and not hardwire your application by binding its business logic to the parsing of a configuration file or other source of configuration, and how to lightly wire it together so that others can easily extend the implementation on their own. Likewise, I've show you the power of how to separate the configuration of the Script Launcher to a file that can be added to DSpace Maven Addon Module so that you can write your own commands without having to do anything at all in the dspace.cfg or launcher.xml in the DSpace config directory to enable them. A solution that will no doubt make your maintenence of those code changes much much easier as DSpace releases new versions and you need to merge yout config files to stay in line.  The final take home mantra for you to repeat 1000 times tonight before going to sleep... "If I don't have to alter configuration to add my changes into DSpace, I wouldn't need to merge differences when I upgrade."