Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

represents a "best practice" for new DSpace architecture and implementation of extensions to the DSpace application. DSpace Services are best described as a "Simple Registry" where plugins FIXME. The DS2 (DSpace 2.0) core services are the main services that make up a DS2 system. These includes services for things like user and permissions management and storage and caching. These services can be used by any developer writing DS2 plugins (e.g. statistics), providers (e.g. authentication), or user interfaces (e.g. JSPUI).

The Service Manager

DSpace Kernel

The DSpace Kernel manages the start up and access services in the DSpace Services framework. It is meant to allow for a simple way to control the core parts of DSpace and allow for flexible ways to startup the kernel. For example, the kernel can be run inside a single webapp along with a frontend piece (like JSPUI) or it can be started as part of the servlet container so that multiple webapps can use a single kernel (this increases speed and efficiency). The kernel is also designed to happily allow multiple kernels to run in a single servlet container using identifier keys.

The Service Manager

The ServiceManager provides a developer API of service lookups and manages the overall lifecycle control for the DSpace Application. During this Lifecycle it also manages the configuration of services by allowing properties to be pushed into the services as they start up (mostly from the ConfigurationService). The ServiceManagerSystem abstraction allows the DSpace ServiceManager to use different systems to manage its services. The current implementation is Spring Framework based. The original design intent of the Service Manager was to support The ServiceManager provides a developer API of service lookups and manages the overall lifecycle control for the DSpace Application. During this Lifecycle it also manages the configuration of services by allowing properties to be pushed into the services as they start up (mostly from the ConfigurationService). The ServiceManagerSystem abstraction allows the DSpace ServiceManager to use different systems to manage its services. The current implementation is Spring Framework based. The original design intent of the Service Manager was to support more than one IoC/DI Solution and and implementation that included Google Guice was provided. This allows DSpace to have very little service management code but still be flexible and not tied to specific technology. Developers who are comfortable with these API can consume the services from a parent Spring ApplicationContext or a parent Guice Module without an awarness that they are doing so. The abstraction also means that we can replace Spring/Guice or add other dependency injection systems later without requiring developers to change their code. The interface provides simple methods for looking up services by interface type for developers who do not want to have to use or learn a dependency injection system or are using one which is not currently supported.

...

The life cycle of the container and the services therein is controlled by the Web-application context or the DSpace CLI ScriptLauncher main executable in which the servlet has been deployed. The Lifecycle assures that when the Service managers (and specifically Spring in this case) are initialized, the required core and addon services are wired and made available to your application.

The ServiceManager Request Cycle

The ServiceManager Request Cycle is similar to the Webapplication Request Cycle.  In the case of the Service Request, There is an incoming "Request" object with the state of the a call from the client, this Request is then enterpreted by the Container and mapped to a specific Servlet, which executes to completion, On Completion, the Serlvet Generates a

When a request is made by either the Webapplication or the CLI initialization, then the Request Lifecycle is engaged:

The Service Manager Interface is defined as follows:

Get Service By Type

Allows developers to get the desired service singleton by the provided type. This should return all instantiated objects of the type specified (may not all be singletons). Accepts a type for the requested service (this will typically be the interface class but can be concrete as well) The return the list of service singletons OR empty list if none is found.

Code Block
public <T> List<T> getServicesByType(Class<T> type);

Get Service By Name

Allows developers to get the desired service singleton by the provided name and type. 

NOTE: This also allows special access to the underlying service manager objects. If using Spring this allows access to the underlying ApplicationContext object like so: getServiceByName(ApplicationContext.class.getName(), ApplicationContext.class);

Code Block
public <T> T getServiceByName(String name, Class<T> type);

Check If Service Exists

Will verify if a service of a specific name exists int he configuration.

Code Block
public boolean isServiceExists(String name);

Get Service Names:

Get the names of all registered service singletons. By convention, the name typically matches the fully qualified class name.

Code Block
public List<String> getServicesNames();

Register Services

Allows adding singleton services and providers in at runtime or after the service manager has started up.  This is primarily useful for registering providers, filters, and plugins with the DSpace core. In all the DSpace Web and Commandline Applications, calls will register and unregister the Services in the ServiceManager during the application Lifecycle.

Code Block
public void registerService(String name, Object service);

Register a Singleton Service Classes

Allows adding singleton services and providers in at runtime or after the service manager has started up. This is the same as the above method, however,  it allows the core service manager to startup your service for you instead of you providing a service to the core.

In general, it is better if you use your own service manager (like Spring or Guice) to manage your services and simply inherit the core service beans from the DSpace core service manager using the special capabilities of ServiceManager.getServiceByName(String, Class)

Code Block
public <T> T registerServiceClass(String name, Class<T> type);

Unregister a Service

Allows a service to be unregistered (which will only work if nothing depends on it).

This is primarily used for providers, filters, plugins, etc. which were registered but are no longer available because the context they are running in is shutting down or restarting.

WARNING: This should not be used to attempt to unregister core services as that will fail.

Code Block
public void unregisterService(String name);

Push Configuration

Allows new configuration settings to be pushed into the core DSpace configuration. These will cause a settings refresh action to be called for all services which are listening and will cause any bean properties to be pushed into existing beans.

Code Block
public void pushConfig(Map<String, String> settings);

Core Services

Request Service

A request is an atomic transaction in the system. It is likely to be an HTTP request in many cases but it does not have to be. This service provides DSpace with a way to manage atomic transactions so that when a request comes in which requires multiple things to happen they can either all succeed or all fail without each service attempting to manage this independently.

In a nutshell this simply allows identification of the current request and the ability to discover if it succeeded or failed when it ends. Nothing in the system will enforce usage of the service, but we encourage developers who are interacting with the system to make use of this service so they know if the request they are participating in with has succeeded or failed and can take appropriate actions.

Code Block
public interface Request {

    public String getRequestId();

    public Session getSession();

    public Object getAttribute(String name);

    public void setAttribute(String name, Object o);

    public ServletRequest getServletRequest();

    public HttpServletRequest getHttpServletRequest();

    public ServletResponse getServletResponse();

    public HttpServletResponse getHttpServletResponse();

}

The DSpace Session

The Session represents a user's session (login session) in the system. Can hold some additional attributes as needed, but the underlying implementation may limit the number and size of attributes to ensure session replication is not impacted negatively. A DSpace session is like an HttpSession (and generally is actually one) so this service is here to allow developers to find information about the current session and to access information in it. The session identifies the current user (if authenticated) so it also serves as a way to track user sessions. Since we use HttpSession directly it is easy to mirror sessions across multiple servers in order to allow for no-interruption failover for users when servers go offline.

Basic Usage

To use the Framework you must begin by instantiating and starting a DSpaceKernel. The kernel will give you references to the ServiceManager and the ConfigurationService. The ServiceManager can be used to get references to other services and to register services which are not part of the core set.

The Service Manager Interface

Code Block
public interface ServiceManager {

    /**
     * Allows developers to get the desired service singleton by the provided type.
     * This should return all instantiated objects of the type specified
     * (may not all be singletons).
     *
     * @param <T>
     * @param type the type for the requested service (this will typically be the interface class but can be concrete as well)
     * @return the list of service singletons OR empty list if none is found
     */
    public <T> List<T> getServicesByType(Class<T> type);

    /**
     * Allows developers to get the desired service singleton by the provided name and type.
     * Provide {@code null} for the name if it is not known, but it is better to ensure it is set.
     * <p>
     * <em>NOTE</em>: This also allows special access to the underlying
     * service manager objects.  It is possible to get the underlying Spring ApplicationContext object like so:
     * <xmp>
     * getServiceByName(ApplicationContext.class.getName(), ApplicationContext.class);
     * </xmp>
     *
     * @param <T>
     * @param name (optional) the unique name for this service.
     * If null then the bean will be returned if there is only one
     * service of this type.
     * @param type the type for the requested service (this will typically be the interface class but can be concrete as well)
     * @return the service singleton OR null if none is found
     */
    public <T> T getServiceByName(String name, Class<T> type);

    /**
     * Lookup to see if a service exists with the given name.
     *
     * @param name the unique name for this service
     * @return true if it exists, false otherwise
Code Block

public interface Session extends HttpSession {

    /**
     * @return the session identifier.  This is not the {@link #getId()}
     * from HttpSession unless no session id was specified when the
     * session was bound.
     */
    public boolean isServiceExists(String getSessionId(name);

    /**
     * ReturnGet the internalnames userof IDall forregistered thisservice sessionsingletons.  By
     *
 convention, the name typically *matches @returnthe internalfully userqualified IDclass
 for the user using this* sessionname).
     *
 This   is null* if@return the session is anonymous.list of all current registered services
     */
    public StringList<String> getUserIdgetServicesNames();

    /**
     * Allows Getadding singleton theservices external/enterpriseand userproviders IDin forat thisruntime session.or
     *
 after the service manager has started up.
  * @return the external/enterprise* userThis idis ofprimarily theuseful userfor associatedregistering withproviders, thisfilters, sessionand
     */
 plugins with the publicDSpace String getUserEID();

core.
     /**
     * @return@param truename ifthe thisname sessionof isthe activeservice OR(must falsebe ifunique)
 the session has timed out or been invalidated
     */
 @param service the publicobject boolean isActive();

    /**to register as a singleton service
     * @return@throws idIllegalArgumentException ofif the serverservice withcannot which this session is associated.be registered
     */
    public void registerService(String getServerId( name, Object service);

    /**
     * @returnAllows theadding IPsingleton Addressservices fromand whichproviders thisin sessionat originatedruntime or
     */
 after the service publicmanager String getOriginatingHostIP();

    /**has started up.
     * @returnThis is the hostnamesame fromas which this session originated{@link #registerService(String, Object)}
     */
 except that it publicallows the String getOriginatingHostName();

    /**core service manager to startup your
     * Getservice anfor attributeyou frominstead the session if one existsof you providing a service to the core.
     * @param key  the key for the attribute In general, it is better if you use your own service manager
     * (like @returnSpring theor valueGuice) ifto onemanage existsyour ORservices null ifand nonesimply
     */
    public String getAttribute(String key);

 inherit the core service beans from the DSpace core service
     /**
     * Set an attribute on a session* manager using the special capabilities of
     * {@link #getServiceByName(String, Class)}.
     *
     * @param key for the attribute@see ServiceManager#getServiceByName(String, Class)
     * @param valuename (ifthe thisname isof nullthe thenservice the(must attributebe is removedunique)
     */
 @param type the publicclass voidtype setAttribute(String key, String value);

    /**of the service (must be in the current classloader)
     * Get@throws allIllegalArgumentException attributesif ofthe thisservice session.
cannot be registered because the *name @returnis ataken copyor oftype theis attributesinvalid in this session.or other
     */
 Modifying  it haspublic no<T> effectT on the session attributes.registerServiceClass(String name, Class<T> type);

     /**/
    public Map<String,* String> getAttributes();

    /**
     * Purges all data from this session and effectively resets it to anAllows a service to be unregistered (which will only work if
     * nothing depends on it).
     * anonymousThis session.is primarily Doesused notfor invalidateproviders, thefilters, sessionplugins, thoughetc.
     */
 which were registered public void clear();

Behind APIs

 can be reimplemented without affecting developers who are using the services. 

Most of the services have plugin/provider points so that customizations can be added into the system without touching the core services code.

Example, specialized authentication system and wants to manage the authentication calls which come into the system. The implementor can simply implement an AuthenticationProvider and then register it with the DS2 kernel's ServiceManager. This can be done at any time and does not have to be done during Kernel startup. This allows providers to be swapped out at runtime without disrupting the DS2 service if desired. It can also speed up development by allowing quick hot redeploys of code during development.

Configuration Service

Code Block
/* Instantiate the Utility Class */
DSpace dspace = new DSpace();

/* Access get the Service Manager by convenience method */
ConfigurationService service = dspace.getSingletonService(ConfigurationService.class);

Legacy Configuration

Wiki Markup
_\[dspace\]/config/dspace.cfg{_}

ConfigurationService contributed to DSpace 1.7.1 (Service Manager Version 2.0.3) 
support for reading the same "dspace.cfg" legacy file is supported. Example of Usage:
ConfigurationService cs = new DSpace().getConfigurationService();
String prop = cs.getProperty("property");

Code Block
String prop = ConfigurationManager.getProperty("property");

Default Configuration

Wiki Markup
_\[addon.jar\]/config/\[service\].cfg_
\\

Any service can provide sane defaults in a java properties configuration file. These properties will be able to be looked up directly using a prefix as syntax.

Example of Usage:

Code Block

ConfigurationService cs = new DSpace().getConfigurationService();
String prop = cs.getProperty("prefix.property");

N/A

Modularization of Configuration

Wiki Markup
_\[dspace\]/config/module/\[prefix\].cfg_

Any service can provide overrides in the DSpace home configuration directory sane defaults in a java properties configuration file. These properties will be able to be looked up directly using a prefix as syntax.

Example of Usage:

Code Block
ConfigurationService cs = new DSpace().getConfigurationService();
String prop = cs.getProperty("prefix.property");

In DSpace 1.7.0 enhanced capabilities were added to the ConfigurationManager to support the separation of of properties into individual files. The name of these files is utilized as a "prefix" to isolate properties that are defined across separate files from colliding.

Example of Usage:

Code Block
String prop = ConfigurationManager.getProperty("prefix", "property");

Mirrors DSpace Configuration
dspace/config/dspace.cfg
dspace/config/modules/addon.cfg
Defaults supported in Addon Jars.
addon.jar/spring/

Test Driven Development

Wiki Markup
{*}Test-driven development*&nbsp;(*TDD*) is a&nbsp;[software development process|http://en.wikipedia.org/wiki/Software_development_process]&nbsp;that relies on the repetition of a very short development cycle: first the developer writes a failing automated&nbsp;[test case|http://en.wikipedia.org/wiki/Test_case]&nbsp;that defines a desired improvement or new function, then produces code to pass that test and finally&nbsp;[refactors|http://en.wikipedia.org/wiki/Code_refactoring]&nbsp;the new code to acceptable standards.&nbsp;[Kent Beck|http://en.wikipedia.org/wiki/Kent_Beck], who is credited with having developed or 'rediscovered' the technique, stated in 2003 that TDD encourages simple designs and inspires confidence.\[http://en.wikipedia.org/wiki/Test-driven_development\]

http://en.wikipedia.org/wiki/Test-driven_development#cite_note-Beck-0

We want to clarify that that the Testing Framework in the DSpace Services Module Predated the actual JUnit testing support that was added to dspace-api.  Testing is a very beneficial practice where the developer writes small java based test of the code they are going to produce.  The 

Wiki Markup
Test-driven development is related to the test-first programming concepts of&nbsp;[extreme programming|http://en.wikipedia.org/wiki/Extreme_programming], begun in 1999,\[[2]\|http://en.wikipedia.org/wiki/Test-driven_development#cite_note-Cworld92-1\]&nbsp;but more recently has created more general interest in its own right.\[[3]\|http://en.wikipedia.org/wiki/Test-driven_development#cite_note-Newkirk-2\]

ACCESSING REGISTERED SERVICES

DEFINING SERVICES
SPRING CONFIGURATION
PROTOTYPES VS SINGLETONS
Example: Creating a Comments Service
Ac dolor ac adipiscing amet bibendum nullam, massa lacus molestie ut libero nec, diam et, pharetra sodales eget, feugiat ullamcorper id tempor eget id vitae. Mauris pretium eget aliquet, lectus tincidunt.
The IMPLEMENTATION
TEST DRIVEN DEVELOPMENT

Using the Service Manager Testing Framework

DSpaceAbstractRequestTest

This is an abstract class which makes it easier to test execution of your service within a DSpace "Request Cycle" and includes an automatic request wrapper around every test method which will start and end a request, the default behavior is to end the request with a failure which causes a rollback and reverts the storage to the previous values

Code Block

public abstract class DSpaceAbstractRequestTest extends DSpaceAbstractKernelTest {

    /**
     * @return the current request ID for the current running request
     */
    public String getRequestId() {
        return requestId;
    }

    @BeforeClass
    public static void initRequestService() {
        _initializeRequestService();
    }

    @Before
    public void startRequest() {
        _startRequest();
    }

    @After
    public void endRequest() {
        _endRequest();
    }

    @AfterClass
    public static void cleanupRequestService() {
        _destroyRequestService();
    }

}

DSpaceAbstractKernelTest

This is an abstract class which makes it easier to test things that use the DSpace Kernel, this will start and stop the kernel at the beginning of the group of tests that are in the junit test class which extends this

Code Block

public abstract class DSpaceAbstractKernelTest extends DSpaceAbstractTest {

    @BeforeClass
    public static void initKernel() {
        _initializeKernel();
        assertNotNull(kernelImpl);
        assertTrue(kernelImpl.isRunning());
        assertNotNull(kernel);
    }

    @AfterClass
    public static void destroyKernel() {
        _destroyKernel();
    }

    /**
     * Test method for {@link org.dspace.kernel.DSpaceKernelManager#getKernel()}.
     */
    @Test
    public void testKernelIsInitializedAndWorking() {
        assertNotNull(kernel);
        assertTrue(kernel.isRunning());
        DSpaceKernel k2 = new DSpaceKernelManager().getKernel();
        assertNotNull(k2);
        assertEquals(kernel, k2);
    }

}

DEFINING AN IN-MEMORY DATABASE
API
Defining the API of the SERVICE
The DATABASE IMPLEMENTATION
Defining the SERVICE in SPRING
THE SERVICE MANAGER
THE SPRING CONFIG

The XMLUI OVERLAY
AspectS
Consectetuer arcu ipsum ornare pellentesque vehicula, in vehicula diam, ornare magna erat felis wisi a risus. Justo fermentum id.
THEME RESOURCES
Developing with DSpace
Architectural Introduction
Maven Archetype
Project Generation
Maven Module Wiring
Dependencies
Tiers
Persisitence
Business
Application
Tools
Maven
Jar Projects
Dependencies
Inheritance
modularity
War Projects
overlays
modularity
Spring
ServiceManager
Core Services
ConfigurationService
Configuration via Spring vs. ConfigurationService
DatabaseService
Opening Doors to Persistence Frameworks
DAO Repositories
Defining, Replacing and Augmenting Storage
Whats a Service?
Defining and Replacing Business Services
Creating Your Own Services
Webapplications
XMLUI / Cocoon
JSPUI (WebMVC)
Example
Facebook Authentication for DSpace
Spring Security
OAuth 2.0 for Spring Security
Facebook Authentication
Implementation
Spring Security Authenticator
Authentication Service

Architectural Overview

DSpace Kernel

The DSpace Kernel manages the start up and access services in the DSpace Services framework. It is meant to allow for a simple way to control the core parts of DSpace and allow for flexible ways to startup the kernel. For example, the kernel can be run inside a single webapp along with a frontend piece (like JSPUI) or it can be started as part of the servlet container so that multiple webapps can use a single kernel (this increases speed and efficiency). The kernel is also designed to happily allow multiple kernels to run in a single servlet container using identifier keys.

Kernel registration

The kernel will automatically register itself as an MBean when it starts up so that it can be managed via JMX. It allows startup and shutdown and provides direct access to the ServiceManager and the ConfigurationService. All the other core services can be retrieved from the ServiceManager by their APIs. Image Removed

Service Manager

Image Removed

The DS2 kernel is compact so it can be completely started up in a unit test (technically integration test) environment. (This is how we test the kernel and core services currently). This allows developers to execute code against a fully functional kernel while developing and then deploy their code with high confidence.

Basic Usage

To use the Framework you must begin by instantiating and starting a DSpaceKernel. The kernel will give you references to the ServiceManager and the ConfigurationService. The ServiceManager can be used to get references to other services and to register services which are not part of the core set.

Access to the kernel is provided via the Kernel Manager through the DSpace object, which will locate the kernel object and allow it to be used.

...

but are no longer available because the
     * context they are running in is shutting down or restarting.
     * <br/>
     * WARNING: This should not be used to attempt to unregister core
     * services as that will fail.
     *
     * @param name the name of the service (must be unique)
     * @throws IllegalArgumentException if the bean cannot be unregistered
     */
    public void unregisterService(String name);

    /**
     * Allows new configuration settings to be pushed into the core
     * DSpace configuration.
     * These will cause a settings refresh action to be called for all
     * services which are listening and will cause any bean properties
     * to be pushed into existing beans.
     *
     * @param settings a map of keys (names) and values
     */
    public void pushConfig(Map<String, String> settings);

}

Core Services

Request Service

A request is an atomic transaction in the system. It is likely to be an HTTP request in many cases but it does not have to be. This service provides DSpace with a way to manage atomic transactions so that when a request comes in which requires multiple things to happen they can either all succeed or all fail without each service attempting to manage this independently.

In a nutshell this simply allows identification of the current request and the ability to discover if it succeeded or failed when it ends. Nothing in the system will enforce usage of the service, but we encourage developers who are interacting with the system to make use of this service so they know if the request they are participating in with has succeeded or failed and can take appropriate actions.

Code Block
public interface Request {

    public String getRequestId();

    public Session getSession();

    public Object getAttribute(String name);

    public void setAttribute(String name, Object o);

    public ServletRequest getServletRequest();

    public HttpServletRequest getHttpServletRequest();

    public ServletResponse getServletResponse();

    public HttpServletResponse getHttpServletResponse();

}

The DSpace Session

The Session represents a user's session (login session) in the system. Can hold some additional attributes as needed, but the underlying implementation may limit the number and size of attributes to ensure session replication is not impacted negatively. A DSpace session is like an HttpSession (and generally is actually one) so this service is here to allow developers to find information about the current session and to access information in it. The session identifies the current user (if authenticated) so it also serves as a way to track user sessions. Since we use HttpSession directly it is easy to mirror sessions across multiple servers in order to allow for no-interruption failover for users when servers go offline.

Code Block

public interface Session extends HttpSession {

    /**
     * @return the session identifier.  This is not the {@link #getId()}
     * from HttpSession unless no session id was specified when the
     * session was bound.
     */
    public String getSessionId();

    /**
     * Return the internal user ID for this session.
     *
     * @return internal user ID for the user using this session.
     * This is null if the session is anonymous.
     */
    public String getUserId();

    /**
     * Get the external/enterprise user ID for this session.
     *
     * @return the external/enterprise user id of the user associated with this session
     */
    public String getUserEID();

    /**
     * @return true if this session is active OR false if the session has timed out or been invalidated
     */
    public boolean isActive();

    /**
     * @return id of the server with which this session is associated.
     */
    public String getServerId();

    /**
     * @return the IP Address from which this session originated
     */
    public String getOriginatingHostIP();

    /**
     * @return the hostname from which this session originated
     */
    public String getOriginatingHostName();

    /**
     * Get an attribute from the session if one exists.
     * @param key  the key for the attribute
     * @return the value if one exists OR null if none
     */
    public String getAttribute(String key);

    /**
     * Set an attribute on a session.
     *
     * @param key for the attribute
     * @param value (if this is null then the attribute is removed)
     */
    public void setAttribute(String key, String value);

    /**
     * Get all attributes of this session.
     * @return a copy of the attributes in this session.
     * Modifying it has no effect on the session attributes.
     */
    public Map<String, String> getAttributes();

    /**
     * Purges all data from this session and effectively resets it to an
     * anonymous session.  Does not invalidate the session, though.
     */
    public void clear();

Behind APIs

 can be reimplemented without affecting developers who are using the services. 

Most of the services have plugin/provider points so that customizations can be added into the system without touching the core services code.

Example, specialized authentication system and wants to manage the authentication calls which come into the system. The implementor can simply implement an AuthenticationProvider and then register it with the DS2 kernel's ServiceManager. This can be done at any time and does not have to be done during Kernel startup. This allows providers to be swapped out at runtime without disrupting the DS2 service if desired. It can also speed up development by allowing quick hot redeploys of code during development.

Configuration Service

The ConfigurationService controls the external and internal configuration of DSpace 2. It reads Properties files when the kernel starts up and merges them with any dynamic configuration data which is available from the services. This service allows settings to be updated as the system is running, and also defines listeners which allow services to know when their configuration settings have changed and take action if desired. It is the central point to access and manage all the configuration settings in DSpace 2.

Manages the configuration of the DSpace 2 system. Can be used to manage configuration for providers and plugins also.

Benefits over the DSpace ConfigurationManager:

1.) Type Casting and Array Parsing: Configuration Service will slip your comma separated values for you.

Recommendation: Why parse values if you do not have to, avoid Parsing Values where-ever possible.

Use commas for lists of values, use lookups

If you end up thinking you want to create maps in your properties, your doing it in the wrong place look instead at Spring Configuration and objectifying your configuration

Objectifying Configuration

wiring your default configuuration

overriding defaults

Acquiring the Configuration Service

Code Block
/* Instantiate the Utility Class */
DSpace dspace = new DSpace();

/* Access get the Service Manager by convenience method */
ConfigurationService service = dspace.getSingletonService(ConfigurationService.class);

Legacy Configuration

Wiki Markup
_\[dspace\]/config/dspace.cfg{_}

ConfigurationService contributed to DSpace 1.7.1 (Service Manager Version 2.0.3) 
support for reading the same "dspace.cfg" legacy file is supported. Example of Usage:
ConfigurationService cs = new DSpace().getConfigurationService();
String prop = cs.getProperty("property");

Code Block
String prop = ConfigurationManager.getProperty("property");

Default Configuration

Wiki Markup
_\[addon.jar\]/config/\[service\].cfg_
\\

Any service can provide sane defaults in a java properties configuration file. These properties will be able to be looked up directly using a prefix as syntax.

Example of Usage:

Code Block

ConfigurationService cs = new DSpace().getConfigurationService();
String prop = cs.getProperty("prefix.property");

N/A

Modularization of Configuration

Wiki Markup
_\[dspace\]/config/module/\[prefix\].cfg_

Any service can provide overrides in the DSpace home configuration directory sane defaults in a java properties configuration file. These properties will be able to be looked up directly using a prefix as syntax.

Example of Usage:

Code Block
ConfigurationService cs = new DSpace().getConfigurationService();
String prop = cs.getProperty("prefix.property");

In DSpace 1.7.0 enhanced capabilities were added to the ConfigurationManager to support the separation of of properties into individual files. The name of these files is utilized as a "prefix" to isolate properties that are defined across separate files from colliding.

Example of Usage:

Code Block
String prop = ConfigurationManager.getProperty("prefix", "property");

Mirrors DSpace Configuration
dspace/config/dspace.cfg
dspace/config/modules/addon.cfg
Defaults supported in Addon Jars.
addon.jar/spring/

Test Driven Development

Wiki Markup
{*}Test-driven development*&nbsp;(*TDD*) is a&nbsp;[software development process|http://en.wikipedia.org/wiki/Software_development_process]&nbsp;that relies on the repetition of a very short development cycle: first the developer writes a failing automated&nbsp;[test case|http://en.wikipedia.org/wiki/Test_case]&nbsp;that defines a desired improvement or new function, then produces code to pass that test and finally&nbsp;[refactors|http://en.wikipedia.org/wiki/Code_refactoring]&nbsp;the new code to acceptable standards.&nbsp;[Kent Beck|http://en.wikipedia.org/wiki/Kent_Beck], who is credited with having developed or 'rediscovered' the technique, stated in 2003 that TDD encourages simple designs and inspires confidence.\[http://en.wikipedia.org/wiki/Test-driven_development\]

http://en.wikipedia.org/wiki/Test-driven_development#cite_note-Beck-0

We want to clarify that that the Testing Framework in the DSpace Services Module Predated the actual JUnit testing support that was added to dspace-api.  Testing is a very beneficial practice where the developer writes small java based test of the code they are going to produce.  The 

Wiki Markup
Test-driven development is related to the test-first programming concepts of&nbsp;[extreme programming|http://en.wikipedia.org/wiki/Extreme_programming], begun in 1999,\[[2]\|http://en.wikipedia.org/wiki/Test-driven_development#cite_note-Cworld92-1\]&nbsp;but more recently has created more general interest in its own right.\[[3]\|http://en.wikipedia.org/wiki/Test-driven_development#cite_note-Newkirk-2\]

ACCESSING REGISTERED SERVICES

DEFINING SERVICES
SPRING CONFIGURATION
PROTOTYPES VS SINGLETONS
Example: Creating a Comments Service
Ac dolor ac adipiscing amet bibendum nullam, massa lacus molestie ut libero nec, diam et, pharetra sodales eget, feugiat ullamcorper id tempor eget id vitae. Mauris pretium eget aliquet, lectus tincidunt.
The IMPLEMENTATION
TEST DRIVEN DEVELOPMENT

Using the Service Manager Testing Framework

DSpaceAbstractRequestTest

This is an abstract class which makes it easier to test execution of your service within a DSpace "Request Cycle" and includes an automatic request wrapper around every test method which will start and end a request, the default behavior is to end the request with a failure which causes a rollback and reverts the storage to the previous values

Code Block

public abstract class DSpaceAbstractRequestTest extends DSpaceAbstractKernelTest {

    /**
     * @return the current request ID for the current running request
     */
    public String getRequestId() {
        return requestId;
    }

    @BeforeClass
    public static void initRequestService() {
        _initializeRequestService();
    }

    @Before
    public void startRequest() {
        _startRequest();
    }

    @After
    public void endRequest() {
        _endRequest();
    }

    @AfterClass
    public static void cleanupRequestService() {
        _destroyRequestService();
    }

}

DSpaceAbstractKernelTest

This is an abstract class which makes it easier to test things that use the DSpace Kernel, this will start and stop the kernel at the beginning of the group of tests that are in the junit test class which extends this

Code Block

public abstract class DSpaceAbstractKernelTest extends DSpaceAbstractTest {

    @BeforeClass
    public static void initKernel() {
        _initializeKernel();
        assertNotNull(kernelImpl);
        assertTrue(kernelImpl.isRunning());
        assertNotNull(kernel);
    }

    @AfterClass
    public static void destroyKernel() {
        _destroyKernel();
    }

    /**
     * Test method for {@link org.dspace.kernel.DSpaceKernelManager#getKernel()}.
     */
    @Test
    public void testKernelIsInitializedAndWorking() {
        assertNotNull(kernel);
        assertTrue(kernel.isRunning());
        DSpaceKernel k2 = new DSpaceKernelManager().getKernel();
        assertNotNull(k2);
        assertEquals(kernel, k2);
    }

}

DEFINING AN IN-MEMORY DATABASE
API
Defining the API of the SERVICE
The DATABASE IMPLEMENTATION
Defining the SERVICE in SPRING
THE SERVICE MANAGER
THE SPRING CONFIG

The XMLUI OVERLAY
AspectS
Consectetuer arcu ipsum ornare pellentesque vehicula, in vehicula diam, ornare magna erat felis wisi a risus. Justo fermentum id.
THEME RESOURCES
Developing with DSpace
Architectural Introduction
Maven Archetype
Project Generation
Maven Module Wiring
Dependencies
Tiers
Persisitence
Business
Application
Tools
Maven
Jar Projects
Dependencies
Inheritance
modularity
War Projects
overlays
modularity
Spring
ServiceManager
Core Services
ConfigurationService
Configuration via Spring vs. ConfigurationService
DatabaseService
Opening Doors to Persistence Frameworks
DAO Repositories
Defining, Replacing and Augmenting Storage
Whats a Service?
Defining and Replacing Business Services
Creating Your Own Services
Webapplications
XMLUI / Cocoon
JSPUI (WebMVC)
Example
Facebook Authentication for DSpace
Spring Security
OAuth 2.0 for Spring Security
Facebook Authentication
Implementation
Spring Security Authenticator
Authentication Service

Anchor
standalone
standalone
Standalone Applications

For standalone applications, access to the kernel is provided via the Kernel Manager and the DSpace object which will locate the kernel object and allow it to be used.

Code Block

/* Instantiate the Utility Class */
DSpace dspace = new DSpace();


/* Access get the Service Manager by convenience method */
ServiceManager manager = dspace.getServiceManager();


/* Or access by convenience method for core services */
EventService service = dspace.getEventService();

The DSpace launcher (

Code Block
bin/dspace

) initializes a kernel before dispatching to the selected command.

Application Frameworks (Spring, Guice, etc.)

Similar to Standalone Applications, but you can use your framework to instantiate an org.dspace.utils.DSpace object.

Code Block
xml
xml

    <bean id="dspace" class="org.dspace.utils.DSpace"/>

Web Applications

In web applications, the kernel can be started and accessed through the use of Servlet Filter/ContextListeners which are provided as part of the DSpace 2 utilities. Developers don't need to understand what is going on behind the scenes and can simply write their applications and package them as webapps and take advantage of the services which are offered by DSpace 2.

Providers and Plugins

For developers (how we are trying to make your lives easier): The DS2 ServiceManager supports a plugin/provider system which is runtime hot-swappable. The implementor can register any service/provider bean or class with the DS2 kernel ServiceManager. The ServiceManager will manage the lifecycle of beans (if desired) and will instantiate and manage the lifecycle of any classes it is given. This can be done at any time and does not have to be done during Kernel startup. This allows providers to be swapped out at runtime without disrupting the service if desired. The goal of this system is to allow DS2 to be extended without requiring any changes to the core codebase or a rebuild of the code code.

Activators

Developers can provide an activator to allow the system to startup their service or provider. It is a simple interface with 2 methods which are called by the ServiceManager to startup the provider(s) and later to shut them down. These simply allow a developer to run some arbitrary code in order to create and register services if desired. It is the method provided to add plugins directly to the system via configuration as the activators are just listed in the configuration file and the system starts them up in the order it finds them.

Provider Stacks

Utilities are provided to assist with stacking and ordering providers. Ordering is handled via a priority number such that 1 is the highest priority and something like 10 would be lower. 0 indicates that priority is not important for this service and can be used to ensure the provider is placed at or near the end without having to set some arbitrarily high number.

Core Services

The core services are all behind APIs so that they can be reimplemented without affecting developers who are using the services. Most of the services have plugin/provider points so that customizations can be added into the system without touching the core services code. For example, let's say a deployer has a specialized authentication system and wants to manage the authentication calls which come into the system. The implementor can simply implement an AuthenticationProvider and then register it with the DS2 kernel's ServiceManager. This can be done at any time and does not have to be done during Kernel startup. This allows providers to be swapped out at runtime without disrupting the DS2 service if desired. It can also speed up development by allowing quick hot redeploys of code during development.

Caching Service

Provides for a centralized way to handle caching in the system and thus a single point for configuration and control over all caches in the system. Provider and plugin developers are strongly encouraged to use this rather than implementing their own caching. The caching service has the concept of scopes so even storing data in maps or lists is discouraged unless there are good reasons to do so.

For standalone applications, access to the kernel is provided via the Kernel Manager and the DSpace object which will locate the kernel object and allow it to be used.

Code Block

/* Instantiate the Utility Class */
DSpace dspace = new DSpace();


/* Access get the Service Manager by convenience method */
ServiceManager manager = dspace.getServiceManager();


/* Or access by convenience method for core services */
EventService service = dspace.getEventService();

The DSpace launcher (

Code Block
bin/dspace

) initializes a kernel before dispatching to the selected command.

Application Frameworks (Spring, Guice, etc.)

Similar to Standalone Applications, but you can use your framework to instantiate an org.dspace.utils.DSpace object.

...


    <bean id="dspace" class="org.dspace.utils.DSpace"/>

Web Applications

In web applications, the kernel can be started and accessed through the use of Servlet Filter/ContextListeners which are provided as part of the DSpace 2 utilities. Developers don't need to understand what is going on behind the scenes and can simply write their applications and package them as webapps and take advantage of the services which are offered by DSpace 2.

Providers and Plugins

For developers (how we are trying to make your lives easier): The DS2 ServiceManager supports a plugin/provider system which is runtime hot-swappable. The implementor can register any service/provider bean or class with the DS2 kernel ServiceManager. The ServiceManager will manage the lifecycle of beans (if desired) and will instantiate and manage the lifecycle of any classes it is given. This can be done at any time and does not have to be done during Kernel startup. This allows providers to be swapped out at runtime without disrupting the service if desired. The goal of this system is to allow DS2 to be extended without requiring any changes to the core codebase or a rebuild of the code code.

Activators

Developers can provide an activator to allow the system to startup their service or provider. It is a simple interface with 2 methods which are called by the ServiceManager to startup the provider(s) and later to shut them down. These simply allow a developer to run some arbitrary code in order to create and register services if desired. It is the method provided to add plugins directly to the system via configuration as the activators are just listed in the configuration file and the system starts them up in the order it finds them.

Provider Stacks

Utilities are provided to assist with stacking and ordering providers. Ordering is handled via a priority number such that 1 is the highest priority and something like 10 would be lower. 0 indicates that priority is not important for this service and can be used to ensure the provider is placed at or near the end without having to set some arbitrarily high number.

Core Services

The core services are all behind APIs so that they can be reimplemented without affecting developers who are using the services. Most of the services have plugin/provider points so that customizations can be added into the system without touching the core services code. For example, let's say a deployer has a specialized authentication system and wants to manage the authentication calls which come into the system. The implementor can simply implement an AuthenticationProvider and then register it with the DS2 kernel's ServiceManager. This can be done at any time and does not have to be done during Kernel startup. This allows providers to be swapped out at runtime without disrupting the DS2 service if desired. It can also speed up development by allowing quick hot redeploys of code during development.

Caching Service

Provides for a centralized way to handle caching in the system and thus a single point for configuration and control over all caches in the system. Provider and plugin developers are strongly encouraged to use this rather than implementing their own caching. The caching service has the concept of scopes so even storing data in maps or lists is discouraged unless there are good reasons to do so.

Configuration Service

The ConfigurationService controls the external and internal configuration of DSpace 2. It reads Properties files when the kernel starts up and merges them with any dynamic configuration data which is available from the services. This service allows settings to be updated as the system is running, and also defines listeners which allow services to know when their configuration settings have changed and take action if desired. It is the central point to access and manage all the configuration settings in DSpace 2.

Manages the configuration of the DSpace 2 system. Can be used to manage configuration for providers and plugins also.

Benefits over the DSpace ConfigurationManager:

1.) Type Casting and Array Parsing: Configuration Service will slip your comma separated values for you.

Recommendation: Why parse values if you do not have to, avoid Parsing Values where-ever possible.

Use commas for lists of values, use lookups

If you end up thinking you want to create maps in your properties, your doing it in the wrong place look instead at Spring Configuration and objectifying your configuration

Objectifying Configuration

wiring your default configuuration

overriding defaults

EventService

Handles events and provides access to listeners for consumption of events.

SessionService

Examples

Configuring Event Listeners

...

(This registers the listener externally – the listener code assumes it is registered.)

TODO: examples in Guice

TODO: examples of implementing and registering configurations in Spring and Guice

TBS: how we did X before : how we do it using the Framework

Recommendations for DSpace 2.0