Developer frameworks for Experience Services

Experience Services are made accessible when building an application via a set of developer frameworks and SDKs. The frameworks and SDKs are described below.

Experience Services - Core

Experience Services - Core is a set of frameworks at the core of ADEP. It is comprised of three frameworks: Apache Jackrabbit, Apache Felix, and Apache Sling.

  • Apache Jackrabbit is a fully conforming implementation of the Content Repository for Java Technology API (JCR, specified in JSR 170 and 283). This is a highly scalable Content Repository that can be used to store and manage unstructured content such as documents, media, user generated content, and application metadata. Experience Services - Core does not rely on a relational database (RDBMS); instead, it stores the content in a highly optimized manner within the JCR content model.

  • Apache Felix is an implementation of the Open Services Gateway Initiative (OSGi) R4 Service Platform and related subprojects that implement specific parts of OSGi and related technologies.

  • Apache Sling is a Web framework that uses the Java Content Repository and Felix OSGi framework to build RESTful applications with support for scripting within the server, including JSP, server-side JavaScript, and Scala.

For more information on each of these Apache projects that make up Experience Services - Core, please consult their home pages:

All three frameworks within Experience Services - Core are exercised when you build a web application using the Apache Sling framework.

Apache Sling

Apache Sling is a web framework that uses a Java Content Repository, such as Apache Jackrabbit, to store and manage content. Sling applications use either scripts or Java servlets, selected based on simple name conventions, to process HTTP requests in a RESTful way. The embedded Apache Felix OSGi framework and console provide a dynamic runtime environment, where code and content bundles can be loaded, unloaded, and reconfigured at runtime. Traditional web applications make use of Java servlets. These can also be deployed as OSGi bundles and then used by Sling when processing an HTTP request with endpoints that get registered for the URL path to the servlet. As the first web framework dedicated to JSR-170 Java Content Repositories, Sling makes it very simple to implement simple applications, while providing an enterprise-level framework for more complex applications.

Apache Sling is a scriptable application layer (JSP, [JavaScript] etc) that invokes application business logic deployed as OSGi bundles (Apache Felix). Sling provides RESTful access to repository resources (content nodes in JCR) via HTTP, as shown in this figure:

The figure below contains a detailed view of the Sling architecture:

View full size graphic
Sling architecture

Key concepts

OSGi: Java business logic for an application based on Sling is built as a series of OSGi bundles and uses OSGi core and compendium services. OSGi is a Java framework that provides modularization of the server functionality. OSGi provides dynamic loading (and unloading) of byte code in the form of bundles. OSGi has facilities for managing bundle versioning and dependencies. The OSGi specification is governed via an open industry alliance.

Sling API: To implement content based web applications with Sling, an API has been defined that extends the Servlet API and provides more functionality to work on the content.

Request processing: Sling takes a unique approach to handling requests. A request URL is first resolved to a resource, then based solely on that resource it selects the actual servlet or script to handle the request.

Resources: The central idea of Sling is the resource, which represents the resource addressed by any request URL. It is the resource that is first resolved when handling a request. Based on the resource, a first servlet or script is then accessed to handle the request.

Servlets and scripts: Servlets and scripts are handled uniformly since they are represented as resources themselves and are accessible by a resource path.

Sling URL decomposition

Web applications written to run on Sling thus rely on JCR nodes in the Content Repository through a process known as Sling URL decomposition. For example, consider the following JCR node tree:

The URL path in an HTTP request matches the location of a node called s4 in the JCR node tree. Within that node definition, the resource type specified points to cars under the apps folder in the content repository. The selector (details) and the extension (.html) from the URL are used to locate the script that renders the page (html.jsp).

Packaging

Having built an application, you need a way to bundle up the various libraries, components, and collateral into a one deployable unit that can be delivered to production and eventually patched or upgraded.

View full size graphic
Content Repository package

The solution is an Experience Package, which is a type of ZIP archive with additional metadata. You can put all application components in the package, after which the deployment process not only explodes the zip into the server, but sorts its contents into the correct areas of the server, including libraries (OSGi bundles), configuration directories, and content directories. In the case of patches or upgrades, a package can contain only the pieces that have changed, which are overlaid onto the application being patched. In addition, OSGi bundles can still be installed, enabled, edited, or removed through the OSGi Console.

OSGi

OSGi is the pattern used for building modular Java application logic with ADEP through its inclusion of Apache Felix, which implements the OSGi R4 Service Platform.

By adopting OSGi at its core, ADEP enables you to package applications as logically independent modules, and to deploy only those pieces needed for a given installation (solution). Applications are able to use different versions of the same resource‚ without conflicts or collisions, and multiple versions of the same application may be concurrently deployed.

OSGi defines an architecture for developing and deploying modular applications and libraries. The OSGi model is essentially a way of managing components. A component in OSGi is a set of related Java classes, kept together and managed as a unit. These components are provided by a bundle.

Extending Sling with application-specific components is equivalent to creating a bundle. A bundle is a JAR file with additional metadata.

A bundle requires a descriptor file called MANIFEST.MF (located in META-INF). For example:

Manifest-Version: 1.0 
Bundle-[ManifestVersion]: 2 
Bundle-Name: [HelloWorld] Plug-in 
Bundle-[SymbolicName]: [HelloWorld] 
Bundle-Version: 1.0.0 
Import-Package: org.osgi.framework;version="1.3.0", 
 org.apache.sling.jcr.api,org.slf4j 
Export-Package: com.day.samples;version="1.0.0" 
Private-Package: com.day.samples.impl 
Service-Component: OSGI-INF/serviceComponents.xml
Note: The Java package names used in the implementing class above must be imported. Also, the packages exposed from your bundle to other bundles must be marked as exported.

In OSGi development it is common practice for an OSGi component to define OSGi Services through interfaces and implementing classes. This is provided in descriptor file references in the MANIFEST.MF, as shown above, and located under OSGI-INF/serviceComponents.xml.

The serviceComponents.xml file defines the interface and implementation classes used by services, and it can also describe the configuration, activation and binding behavior of a component lifecycle:

View full size graphic
Component lifecycle

Furthermore, the serviceComponents.xml file referenced within a manifest can be produced from annotations when classes for the OSGi component are compiled. This is achieved using the Apache Felix Maven SCR Plug-in at compile time. For example, consider the following serviceComponents.xml file:

<scr:component name=„org.sample.Component 
    activate="activate" deactivate="deactivate" 
    xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"> 
    <implementation class="org.sample.Component" /> 
    <reference interface="org.osgi.service.log.[LogService]" 
        bind="bindLogService" unbind="unbindLogService" /> 
    <property name="p1" value="sample" /> 
    <property name="p2" type="Integer"> 
        1 
        2 
    </property> 
</component>

These are the Java annotations for the activation phase:

View full size graphic
Activation phase

These are the Java annotations for the binding phase:

These are the Java annotations for the configuration phase:

View full size graphic
Configuration phase

For more information about the Apache Felix Maven SCR Plug-in, see http://felix.apache.org/site/apache-felix-maven-scr-plugin.html.

OSGi bundles, components, and services can be deployed and managed using the ADEP OSGi Console:

View full size graphic
Apache Felix Web Console components

Composite Application Framework

Applications built on ADEP are often made up of a variety of content, including forms, data, charts, and video. Some of this is Flash content, and some is HTML. Consider the behavior of the following application:

View full size graphic
Composite application

Authors want this content not only to exist side-by-side on the same page, but to interact. For example, clicking or typing in a SWF should affect the appearance of HTML and vice versa. Selecting a currency value might bring up an RSS feed of news stories in currency markets. The Composite Application Framework is designed to address these needs. It provides the Experience Services SDK and server runtime for applications whose layout and modular HTML or SWF based components are managed as content in the Content Repository provided by the Experience Server.

Interaction between HTML and Flash

There is an object model behind the scenes that is used in the user interface. Events, messages, and properties emitted in Flash Player are transferred through the object model to the HTML layer and vice versa. Each layer acts as a view of the object model so they remain in sync and the user is presented with a consistent model. The user interacts with both Flash and HTML content in a unified experience.

Other frameworks used by composite applications

Applications built using the Composite Application Framework also make use of other frameworks in ADEP.

  • Adobe Digital Enterprise Platform Experience Services - Client Component Framework 10.0: The Client Component Framework takes advantage of interface-based dependency injection. Permits the use of multiple versions of the Flex SDK used by different tiles within a composite application, if necessary.

  • UX Components: Reusable Flex components for which the look and feel of a component can be tailored to the final application.

View full size graphic
Composite Application Framework

Client Component Framework

The Client Component Framework offers dependency injection for ActionScript developers, as well as an OSGi dynamic plug-in runtime for Flex applications. The Client Component Framework contains two key concepts:

  • Bundles: Bundles are the deployment abstraction. Physically, each bundle is a SWF.

  • Services: Services are the run time abstraction, referenced using ActionScript objects.

Within bundles, there is an Application Domain Hierarchy that is used to implement a service exposed through an interface. Each application domain can have its own shared Flex SDK and interface definitions.

Similar in principle to an OSGi bundle used for server-side Java business logic, a bundle defined with the Client Component Framework contains a manifest to define services implemented or consumed by the bundle. For example:
<?xml version="1.0" encoding="UTF-8"?> 
<manifest xmlns="http://ns.adobe.com/gravity/manifest/1.0"> 
    <interface> 
        <library location="my-core.swf"/> 
        <library location="my-extra.swf"/> 
        <service/> 
        <service/> 
    </interface> 
    <bundle location="my-bundle.swf" loader="flex-application">       
        <services> 
            <interface name="com.example::[IMyBar]"/> 
        </services> 
    </bundle> 
    <bundle location="foo-bundle.swf">  
        <services> 
            <interface name="com.example::[IMyFoo]"/> 
            <interface name="com.example::[IMyBar]"/> 
        </services> 
    </bundle> 
</manifest>

UX components

UX components employ a design where the component is separate from its skin and uses interfaces and domain objects to communicate with remote services. The component can be inherited for specialization, and because its skin is separated from the component, the look and feel of the component can be tailored to the final application.

Separating the component into presentation layer, domain model, and services eases configuration and reuse. The Client Component Framework can be used to load different components into an application at runtime, and to inject service implementations into the component, such as different data sources or alternative business logic.

There are several key points about UX components:
  • A UX component has replicable skins and styles (presentation layer).

  • Interfaces are used in front of the implementation of services consumed by the UX component.

  • Services are injectable using the Client Component Framework.

Applications based on content

Experience Services - Core provides three essential capabilities: an application framework, an application runtime, and a content repository. The RESTful nature of the application framework (Sling), the modular (OSGi-based) nature of the application runtime (Felix), and the node-oriented nature of the open standards (JCR 2.0) compliant content repository provide a robust foundation for composite applications.

By thinking of both SWFs and HTML as content, you can use your favorite authoring environments to create components and tiles. That content is then deployed into a catalog on a server. From there it is composed into applications that are tailored for delivery to the user. The platform-specific application provides the tailored navigation tuned to the device, while sharing content across platforms.

View full size graphic
Composition enabling multiple application types

Data Services

Data Services is a server-side framework that offers the following capabilities to Flex applications, including mobile applications built using Flex:
  • Remoting: Allows Flex client applications to invoke methods on Java server objects directly. Similar to Java remote method invocation (RMI), remoting handles data marshalling automatically and uses a binary data transfer format.

  • Messaging: Provides the publish portion of the publish/subscribe design pattern. The Flash client can publish events to a topic defined on the server, and subscribe to events broadcast from the message service.

  • Data Management: Provides a programming model for automatically managing data sets that have been downloaded to the Flex client. Once data is loaded from the server, changes are automatically tracked and can be synchronized with the server at the request of the application. Clients are also notified if changes to the data set are externally updated. The server communicates with the client to present live data to subscribed clients.

Data Services has been traditionally deployed as a Java EE application (formerly known as LiveCycle Data Services). Now it is a central component within ADEP using Apache Sling and OSGi, which makes possible the new behavior and capabilities summarized below.

For a developer already familiar with Data Services from previous releases, the following topics should be understood for Data Services within ADEP:
  • Configuration behavior

  • Use of OSGi

  • Integration with SQL Data Sources

  • Using JCR as persistence for Data Management

  • Current restrictions on protocols

Configuration

Data Services uses the Content Repository to mange its configuration files (under /etc/aep/config/dataservices). For example, this includes Data Services Remoting destinations.

View full size graphic
Configuration files

In addition to simply hosting configuration files in CRX, it is also possible to provide incremental XML snippets of additional configuration under the /etc/aep/config/destinations folder. This means that a base configuration can be maintained, but individual applications deployed through Experience Packages can carry additional configuration for the needs of one application.

Use of OSGi

In order to expose a Java class for Remoting with Data Services, the Java class must be deployed through an OSGi bundle, typically as part of an Experience Package. In addition, it is possible to enable Remoting for a Java class by using an OSGi configuration property in its bundle, instead of relying on explicit configuration using the Data Services XML configuration files.

In the example below, the osgi-context.xml file is placed under the /META-INF/spring folder of an OSGi bundle in which a Java class is used for remoting:

View full size graphic
Enabling remoting using OSGi

In this example, the osgi-context.xml defines a remote object called taskmanagement.taskManager for a Spring bean within the bundle identified by lc.processmanagement.taskManagerImpl. The OSGi service is defined as a bean element defined in the Blueprint schema namespace:
<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    .. 
    <bp:blueprint> 
        <bp:service ref="lc.processmanagement.taskManagerImpl" auto-export="interfaces"> 
            <bp:service-properties> 
                <entry key="connectors.remoting.id" value="taskmanagement.taskManager" /> 
                <entry key="implementation.type" value="standard"/> 
            </bp:service-properties> 
        </bp:service> 
        .. 
    </bp:blueprint> 
</beans>

Integration with SQL data sources

In order to use SQL data sources with Data Management, the data sources must be configured under new entries for the JDBC Connections Pool in the OSGi Console. For example, here is a JDBC Connections Pool at http://localhost:4502/system/console/configMgr:

View full size graphic
JDBC Connections Pool

Each JDBC data source is then assigned settings, as shown in the following example:

View full size graphic
JDBC data sources

The JDBC driver class used for a JDBC data source must also already be deployed in an OSGi bundle. JDBC drivers that you might have already as plain JAR files must be converted into OSGi bundles, for example, by using the Apache Felix Bundle Plugin for Maven, which is available at http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html.

Using JCR as persistence for Data Management

Data Management allows you to author a data model in Flash Builder and deploy it to the Experience Server. This creates new Data Services destinations, which expose CRUD (create, read, update delete) and filter operations for the entities in the data model. At runtime, these operations are implemented on the server by a Data Services Assembler that traditionally has used Hibernate to manage data in a SQL database.

As part of Data Services with ADEP, an option is available to use the Content Repository for persistence in an application built using Data Management. This is supported by a new Data Services Assembler built using JCR. This option is enabled by authoring a data model in Flash Builder with a Preference set to use the Content Repository as the Deployment Handler for persistence, as shown in the following example:

View full size graphic
Authoring a simple data model
View full size graphic
Choosing the Content Store preference
View full size graphic
CRUD and filter operations that manage data stored in the Content Repository

At run time, instance data created by your application, based on entities in the data model, are stored in a JCR node tree, as shown in the following example:

View full size graphic
Data model instance data stored in the Content Repository

Current restrictions on protocols

Experience Services - Data Services currently does not support the RTMP protocol, and does not support HTTP Java New Input/Output (NIO) Endpoints using a NIO-based socket server.

Task Management

The Experience Server provides the following capabilities for Task Management, utilized by developers as part of the Experience Services SDK:
  • A framework to manage the lifecycle of User Tasks. The framework provides two default provider implementations for User Tasks; one using content in the Content Repository and one using the Document Server running a business process management process. Regardless of the implementation chosen, the APIs and UX components used by the web application do not need to change. This approach permits other custom providers to be written for integration with third party task management systems. The two implementations are:
    • Stand-alone User Task: A Stand-alone User Task can be assigned to users with custom properties, payload and status. These User Tasks do not need to originate from a BPM process. Instead, they can be created and assigned in an ad-hoc fashion by applications that manage appointments or To-Do items for their end users. Stand Alone User Tasks are managed in the CRX Repository as data in a JCR node tree.

    • Document Server User Task: User Tasks are generated by a business process management process running on the Document Server, using Process Management. Web applications deployed on the Experience Server can use the Task Management framework to access and manage these User Tasks through the same set of UX components used to manage Stand-alone User Tasks.

  • A set of UX components available in Flash Builder to help build applications that manage User Tasks and display the work payload of a User Task.

  • A set of services (exposed via Data Services Remoting) that can be used in Flex applications to interact with Stand-alone and Document Server User Tasks.

UX Components

The Task Management framework provides the following UX components, distributed via the ADEP Experience Services SDK. These UX components are:

  • Task List

  • Task Action

  • Task Details

  • Task Attachments

  • Task Document Submit

  • Web Document Viewer

UX components

The naming pattern in each of the UX components above is <Function Name> and <Function Name>Component. The difference between each is that the Component variation consumes a Service Interface used as a Flex Data Provider for the UX Component. For example the TaskListComponent uses an ITaskManager, which offers query operations (for example, getTasks() calls the UX Component to fetch a list of ITask Objects). The simpler TaskList just uses a statically supplied list of ITask Objects.

Each UX component provides a set of libraries that correspond to the UX design pattern discussed above. These libraries provide the domain logic, a component wrapper, a service, and one or more skins. For example, in the case of the Task List UX component:
  • task_list_domain.swc (domain logic)

  • task_list_component.swc (UX component wrapper)

  • task_list_ui_service.swf (Service implementation)

  • task_list_datagrid_skin.swc (custom skin)

Note: The Task List and Task Details UX components can be used with either Stand-alone User Tasks or Document Server User Tasks. However, the UX components for Task Attachments, Task Action, and Task Document Submit are only used for Document Server User Tasks since that is what their service implementation supports. Their service implementation relies on the Experience Server having been configured to access a Document Server for retrieving User Task information, and will do so based on the identity of the user who has been authenticated to the Experience Server.

Task Management Services

The Experience Server exposes a set of services that applications can use through a Client SDK to manage User Tasks. These services are visible in the OSGi Console.

View full size graphic
Task Management services

The Task Management services are:

  • ITaskManager: Exposes a standard API for managing User Tasks (Stand-alone or Document Server based).

  • ITaskTypeRegistry: Exposes a standard API for managing User Tasks (Stand-alone or Document Server based).

  • ILCTaskManager: Exposes a set of operations specific to managing Document Server User Tasks.

  • TaskDao and TaskTypeDao: These services are an implementation of the interface used to persist and query Stand-alone User Tasks. Their default implementation uses JCR for the Content Repository, but other custom implementations are possible.

Access to the Task Management services is provided through the Task Management Client SDK supplied as part of the overall Experience Services SDK.

Configuring Stand-alone Tasks

The default storage implementation for Stand-alone Tasks uses the Content Repository. The service that provides this implementation exposes a configuration property that can be used to change the default root location at which data for Stand-alone Tasks will be saved in the Content Repository.

View full size graphic
Stand-alone tasks

For more information, see Add business process management to a client application using out-of-the-box components .

Security

ADEP provides a server-side framework and Experience Services SDK designed to address typical security related requirements during the development of rich Internet applications:
  • Username/password authentication using either the Content Repository or a Document Server as the provider of user identity. There is also a plug-in model based on the Java Authentication and Authorization Service (JAAS) for delegating authentication to other identity providers.

  • Single Sign-On and identity propagation for an already logged-on end user across all Experience Services. For example, when a client application is invoking Data Services, accessing Composite Application Services or making HTTP Requests using Apache Sling, re-authentication is not required.

  • Client access to the user details for the current logged in user with the notion of an ActionScript User object. This includes access to any third party tickets and assertions used to authenticate the user against an external system.

  • Client access to SSO cookies and a SAML Assertion or the current logged in user. This is typically needed when services are accessed across multiple domains, thus preventing cookie-based authentication.

  • Handling a session time-out in a Flex application and triggering a custom method to re-authenticate the user.

  • Client access to roles and permissions for the logged in user.

  • Log out handling.

Considerations for authentication

Applications built on the Experience Server must authenticate their users via the Sling Web framework. In general, there are two ways to accomplish this, based on either HTML or Flex.

Authentication using HTML

Applications can authenticate an HTTP request using a standard HTML form, in which the action for a POST is set to use to /j_security_check. The Form supplies a sling.auth.redirect value for the page to be redirected after successful authentication. The following example shows this as a snippet from a typical HTML form:
<form action="/j_security_check" 
  method="post" accept-charset="UTF-8" enctype="application/x-www-form-urlencoded"> 
  <table width="96%" border="0" summary="Enter User ID and Password" cellspacing="2" cellpadding="2"> 
     <tr> 
        <td align="center" nowrap="nowrap" colspan="2" class="boldText"> 
            <font face=tahoma size=4>Please Login</font> 
        </td> 
     </tr> 
     <tr> 
        <td align="center" nowrap="nowrap" colspan="2" class="boldText">&nbsp;</td> 
     </tr> 
     <tr> 
        <td align="right" class=""><font face=tahoma size=3>User ID:&nbsp;&nbsp;</font></td> 
        <td align="left"> 
            <input name="j_username" id="loginName" type="text" value="" width="200"/> 
        </td> 
     </tr> 
     <tr> 
        <td align="right" class=""><font face=tahoma size=3>Password:&nbsp;&nbsp;</font></td> 
        <td align="left"> <input name="j_password" type="password" value="" width="200"/></td> 
        <input type="hidden" name="sling.auth.redirect" value="/content/myapp/welcome.html" /> 
     </tr> 
     <tr> 
        <td height="40" class="noBorderCell" align="center" colspan="2"> 
        <div class="buttonWrapperLeft"> 
            <input type="submit" class="buttonGenericPrimary" value="Login"/> 
        </div></td> 
     </tr> 
  </table> 
</form>

Authentication using Flex and Data Services

For building Flex applications using ADEP, a Security Client API, provided as part of the Experience Services SDK, allows a Flex application to authenticate using Apache Sling. This is particularly important when using Data Services in ADEP, as the traditional Flex ChannnelSet.login() and ChannelSet.logout() will not work in this scenario.

In the example code snippet below, the call to securityManager.performSSO() determines whether the end user has already been authenticated and, if not, triggers a call to authenticate the user using securityManager.login():
<s:Application .. creationComplete="initApp()"> 
    <fx:Script> 
        <![CDATA[ 
            .. 
            protected var securityManager:SecurityManager; 
 
            public function initApp():void 
            { 
                var securityConfig:SecurityConfig = ConfigUtil.getDefaultRIASecurityConfig(); 
                securityManager = SecurityManager.getInstance(securityConfig); 
                var token:IToken = securityManager.performSSO(); 
                token.addSuccessHandler(loginHandler) 
            } 
            private function loginHandler(ar:IAuthResult):void 
            { 
                switch (ar.status){ 
                    case AuthStatus.AUTHENTICATION_REQUIRED: 
                        .. 
                    case AuthStatus.AUTHENTICATION_SUCCESS: 
                        .. 
                    case AuthStatus.AUTHENTICATION_FAILED: 
                        .. 
                    case AuthStatus.LOGOUT_COMPLETE: 
                     .. 
                } 
            } 
            private function loginCommand():void 
            { 
                status("logging in with username:" + username.text + " and password: " + passwd.text); 
                var token:IToken = securityManager.login(username.text, passwd.text); 
                token.addSuccessHandler(loginHandler); 
            } 
            .. 
        ]]> 
    </fx:Script> 
    .. 
</s:Application>

When a Flex application uses Data Services to invoke a Remote Object deployed on ADEP, additional configuration is necessary for Data Services in order to enforce authentication via Apache Sling for invocation requests between the Flex application and the Data Services Destination used by the Remote Object.

To define a security constraint, in the services-config.xml file (found in the repository at /etc/aep/config/dataservices) add a security constraint to the <security> section of the file:
<security> 
 <login-command class="com.adobe.lcds.sling.impl.SlingLoginCommand" server="Sling"/> 
 
  <security-constraint id="sample-users"> 
    <auth-method>Custom</auth-method> 
      <roles> 
        <role>sampleusers</role> 
      <roles> 
  </security-constraint> 
</security>
In the destination configuration, reference the security constraint:
<destination id="EchoService"> 
  <security> 
    <security-constraint ref="sample-users" /> 
  </security> 
  <properties> 
    <source>features.remoting.EchoService</source> 
  </properties> 
</destination>

Document Server integration

Experience Server is integrated with the Document Server in two ways:
  • Ability to use Document Server as the Identity Provider for authentication and group membership of users who authenticate to the Experience Server. This is achieved by enabling a CRX Login Module supplied with ADEP that performs authentication using a separately deployed Document Server. Authentication is controlled by an Enterprise Domain on the Document, based on LDAP or locally administered users.

  • Invocation of Document Services and processes running on the Document Server via the Document Services SDK. This SDK can be used within an OSGi bundle or via scripting in a JSP.

In addition, you can use the Content Repository Connector to allow Document Services to use Experience Services as a repository. For more information about this Document Services Component (DSC), see The Content Repository Connector DSC.

Use the Experience Services SDK to invoke Document Services

Before a web application deployed on the Experience Server can invoke Document Services, the Experience Server must be configured with the location of the Document Server as well as a user account that it can use to perform system privileged operations on the Document Server (in cases where the Document Server is not invoked under the identity of a logged on end user). This bootstrap is achieved by running an auto-configuration tool in the OSGi Console and supplying a Document Server Administrator credential used to log into the Document Server during the bootstrap phase.

View full size graphic
Apache Felix Web Console Document Services Settings

After running the Configure option, a new configuration property is created under /apps/docservices/config in the JCR Node tree containing the properties needed by the Experience Server to invoke Document Services on the Document Server:

View full size graphic
Configuration properties

Once the Experience Server is configured to connect to the Document Server there are two common ways to invoke Document Services:
  • Calling Document Services from a JSP

  • Calling Document Services from an OSGi bundle

Calling Document Services from a JSP

The snippet below shows the basic pattern for invoking a Document Service from a JSP. With this pattern, the Document Service will be invoked based on the user identity of the end user logged on to the Experience Server with authentication configured to use the Document Server.
<%@page import=".. 
                com.adobe.livecycle.dsc.clientsdk.ServiceClientFactoryProvider, 
                com.adobe.idp.dsc.clientsdk.ServiceClientFactory, 
                com.adobe.idp.dsc.InvocationRequest, 
                com.adobe.idp.dsc.InvocationResponse, 
                com.adobe.idp.dsc.clientsdk.ServiceClient, 
 
SlingScriptHelper scriptHelper = bindings.getSling(); 
 
ServiceClientFactoryProvider scfp =  scriptHelper.getService(com.adobe.livecycle.dsc.clientsdk.ServiceClientFactoryProvider.class); 
ServiceClientFactory scf = scfp.getDefaultServiceClientFactory();
[HashMap]<String,Object> hmInput = new [HashMap]<String,Object>(); 
: 
: Required input parameters can be set here 
: 
[InvocationRequest] ir = scf.createInvocationRequest(MyService, MyOperation, hmInput, true); 
[InvocationResponse] iresp = scf.getServiceClient().invoke(ir); 
Object output = iresp.getOutputParameter(outputValue);

For additional information, see Integrate with Document Services .

Calling Document Services from an OSGi bundle

Java logic for a web application must be deployed as an OSGi bundle, as discussed the previous section. In order to use the Document Services SDK from within a bundle, it is necessary to inject a Service Client Factory that will be used within your Java implementation to invoke the Document Service. In this snippet, the behavior is to invoke the Document Service as the end user who is logged into the Experience Server, using the Document Server for authentication.

First the osgi-context.xml defined within the bundle must define the Service Client Factory that will be injected into the Java Class, within your application, that needs to invoke a Document Service:
<beans ..> 
    <bean id="serviceClientFactory" 
        factory-bean="serviceClientFactoryProvider" factory-method="getDefaultServiceClientFactory" scope="prototype"> 
    </bean> 
    .. 
    <bp:blueprint> 
        <bp:reference id="serviceClientFactoryProvider" 
            interface="com.adobe.livecycle.dsc.clientsdk.ServiceClientFactoryProvider" /> 
        .. 
          <bean id="lcinvoke" class="com.myapplication.InvokeServiceSingleImpl"> 
            <property name="svcClientFactory" ref="serviceClientFactory" /> 
            .. 
        </bean> 
        <bp:service interface="com.myapplication.InvokeServiceSingle" ref="lcinvoke"> 
            <bp:service-properties> 
               <entry key="connectors.httpinvoker" value="true" /> 
               <entry key="connectors.httpinvoker.id" value="/lcinvoke" /> 
               .. 
            </bp:service-properties> 
        </bp:service> 
    </bp:blueprint> 
</beans>
Then, within your implementation class, you use the Document Services SDK with the injected Service Client Factory to invoke the Document Service:
public class InvokeServiceSingleImpl implements InvokeServiceSingle 
{ 
    public ServiceClientFactory scf=null; 
 
    public void setSvcClientFactory(ServiceClientFactory scf) 
    { 
        this.scf = scf; 
    } 
    public ServiceClientFactory getSvcClientFactory() 
    { 
        return scf; 
    } 
 
    public InvokeServiceSingleImpl(ServiceClientFactoryProvider svcP) 
    { 
        this.scfP = svcP; 
    } 
 
    public String invokeMyDocumentServiceString subject, String body) 
    { 
        HashMap<String,Object> hmInput = new HashMap<String,Object>(); 
        hmInput.put("subject", subject); 
        hmInput.put("body", body); 
        InvocationRequest ir = scf.createInvocationRequest("MyApplication/MyDocumentService", "invoke", hmInput, true); 
 
        try { 
            InvocationResponse iresp = scf.getServiceClient().invoke(ir); 
            Object output = iresp.getOutputParameter("outForm"); 
            .. 
        } .. 
    } 
}