Common API - Packt

52
Common API Most websites are dynamic, content-rich, and social. It is required to integrate different password policies, LDAP, and SSO in most cases for authorization and authentication. Tracking and auditing would be helpful to know about users’ actions in the portal. Rules engine integration helps us execute business rules in a runtime production environment, while reporting engine integration helps us to generate dynamic content. A polling mechanism would be useful to dynamically push data to a browser, without the browser explicitly requesting it. In addition, scripting engine, web services, and WSRP would be useful for building custom plugins via remote processes. These features are included in the common API. Therefore, the common API of the portal would be helpful to build dynamic, content-rich, and social websites, or WAP sites. This chapter will introduce user management and password policy first. Then it will address authentication and authorization. LDAP and SSO integration will be introduced afterwards. Tracking and auditing services API will be addressed in detail, in this chapter. Finally, it will address scripting engine, polling, web services, WSRP, and the OSGi framework. By the end of this chapter, you will have learned about the following: User management Password policy Authentication and authorization LDAP and SSO Tracking and auditing Rules engine and reporting engine Scripting engine and poller Web services

Transcript of Common API - Packt

Page 1: Common API - Packt

Common APIMost websites are dynamic, content-rich, and social. It is required to integrate different password policies, LDAP, and SSO in most cases for authorization and authentication. Tracking and auditing would be helpful to know about users’ actions in the portal. Rules engine integration helps us execute business rules in a runtime production environment, while reporting engine integration helps us to generate dynamic content. A polling mechanism would be useful to dynamically push data to a browser, without the browser explicitly requesting it. In addition, scripting engine, web services, and WSRP would be useful for building custom plugins via remote processes. These features are included in the common API. Therefore, the common API of the portal would be helpful to build dynamic, content-rich, and social websites, or WAP sites.

This chapter will introduce user management and password policy first. Then it will address authentication and authorization. LDAP and SSO integration will be introduced afterwards. Tracking and auditing services API will be addressed in detail, in this chapter. Finally, it will address scripting engine, polling, web services, WSRP, and the OSGi framework.

By the end of this chapter, you will have learned about the following:

• User management• Password policy• Authentication and authorization• LDAP and SSO• Tracking and auditing• Rules engine and reporting engine• Scripting engine and poller• Web services

Page 2: Common API - Packt

Common API

[ 2 ]

• WSRP producers and consumers• OSGi framework

User managementThe portal has defined user management with a set of entities, such as, User, Contact, Address, EmailAddress, Phone, Website, and Ticket at /portal/service.xml. In the following section, we’re going to address the User entity, its association, and relationship.

Models and servicesThe following figure depicts these entities and their relationships. The entity User has a one-to-one association with the entity Contact, which may have many contacts as children. And the entity Contact has a one-to-one association with the entity Account, which may have many accounts as children. The entity Contact can have a many-to-many association with the entities Address, EmailAddress, Phone, Website, and Ticket. Logically, the entities Address, EmailAddress, Phone, Website, and Ticket may have a many-to-many association with the other entities, such as Group, Organization, and UserGroup as shown in the following image:

Account Ticket Address EmailAddress

Contact Phone Website

c

c c c

c c c

*

* *

***

*

**

**

*

Userc

ServicesThe following table shows user-related service interfaces, extensions, utilities, wrappers, and their main methods:

Page 3: Common API - Packt

Chapter 11

[ 3 ]

Interface Extension Utility/Wrapper Main methodsUserService, UserLocal Service

PersistedModel LocalService

User(Local)ServiceUtil, User(Local)ServiceWrapper

add*, authenticate*, check*, decrypt*, delete*, get*, has*, search, unset*, update*, and so on.

ContactService, ContactLocal Service

PersistedModel LocalService

Contact(Local)ServiceUtil, Contact(Local)ServiceWrapper

add*, create*, delete*, get*, update*, dynamicQuery, and so on.

AccountService, AccountLocal Service

PersistedModel LocalService

Account(Local)ServiceUtil, Account(Local)ServiceWrapper

add*, create*, delete*, get*, update*, dynamicQuery, and so on.

AddressService, AddressLocal Service

PersistedModel LocalService

Address(Local)ServiceUtil, Address(Local)ServiceWrapper

add*, create*, delete*, get*, update*, dynamicQuery, and so on.

EmailAddress Service, EmailAddress LocalService

PersistedModel LocalService

Address(Local)ServiceUtil, Address(Local)ServiceWrapper

add*, create*, delete*, get*, update*, dynamicQuery, and so on.

PhoneService, PhoneLocal Service

PersistedModel LocalService

Phone(Local)ServiceUtil, Phone(Local)ServiceWrapper

add*, create*, delete*, get*, update*, dynamicQuery, and so on.

WebsiteService, WebsiteLocal Service

PersistedModel LocalService

Website(Local)ServiceUtil, Website(Local)ServiceWrapper

add*, create*, delete*, get*, update*, dynamicQuery, and so on.

TicketLocal Service

PersistedModel LocalService

TicketLocal ServiceUtil, TicketLocal ServiceWrapper

add*, create*, delete*, get*, update*, dynamicQuery, and so on.

Page 4: Common API - Packt

Common API

[ 4 ]

RelationshipsThe portal also defined many-to-many relationships between User and Group, User and Organization, User and Team, User and UserGroup, as shown in the following code:

<column name=”groups” type=”Collection” entity=”Group” mapping-table=”Users_Groups” /><column name=”userGroups” type=”Collection” entity=”UserGroup” mapping-table=”Users_UserGroups” />

In particular, you will be able to find a similar definition at /portal/service.xml.

Sample portal service portletThe portal provides a sample portal service plugin called sample-portal-service-portlet (refer to the plugin details at /portlets/sample-portal-service-portlet). The following is the code snippet:

List organizations = OrganizationServiceUtil.getUserOrganizations( themeDisplay.getUserId()); // add your logic

The previous code shows how to consume Liferay services through regular Java calls. These services include com.liferay.portal.service.OrganizationServiceUtil and the model involves com.liferay.portal.model.Organization. Similarly, you can use other services, for example, com.liferay.portal.service.UserServiceUtil and com.liferay.portal.service.GroupServiceUtil; and models, for example, com.liferay.portal.model.User, com.liferay.portal.model.Group. Of course, you can find other services and models—you will find services located at the com. liferay.portal.service package in the /portal-service/src folder. In the same way, you will find models located at the com.liferay.portal.model package in the /portal-service/src folder.

What’s the difference between *LocalServiceUtil and *ServiceUtil? The sign * represents models, for example, Organization, User, Group, and so on. Generally speaking, *Service is the remote service interface that defines the service methods available to remote code. *ServiceUtil has an additional permission check, since this method might be called as a remote service. *ServiceUtil is a facade class that combines the service locator with the actual call to the service *Service. While *LocalService is the internal service interface,*LocalServiceUtil is a facade class that combines the service locator with the actual call to the service *LocalService. *Service has a PermissionChecker in each method, and *LocalService usually doesn’t have the same.

Page 5: Common API - Packt

Chapter 11

[ 5 ]

AuthorizationAuthorization is a process of finding out if the user, once identified, is permitted to have access to a resource. The portal implemented authorization by assigning permissions via roles and checking permissions, and this is called Role-Based Access Control (RBAC).

The following figure depicts an overview of authorization. A user can be a member of Group, UserGroup, Organization, or Team. And a user or a group of users, such as Group, UserGroup, or Organization can be a member of Role. And the entity Role can have many ResourcePermission entities associated with it, while the entity ResourcePermission may contain many ResourceAction entities, as shown in the following diagram:

Group User Team

Organization Role ResourcePermission

c c

c c

*

*membership* * * *membership membership

membership

membership

membership*

*

membership

*

*

*

* *

*

*

*

*

membership

UserGroup

ResourceAction

c c

c c

The following table shows the entities Role, ResourcePermission, and ResourceAction:

Interface Extension Wrapper/SOAP Main methodsRole RoleModel,

PersistedModelRoleWrapper, RoleSoap

clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on.

Resource Action

Resource ActionModel, PersistedModel

ResourceAction Wrapper, ResourceActionSoap

clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on.

Resource Permission

Resource PermissionModel, PersistedModel

ResourcePermission Wrapper, ResourcePermissionSoap

clone, compareTo, get*, set*, toCacheModel, toEscapedModel, and so on.

Page 6: Common API - Packt

Common API

[ 6 ]

In addition, the portal specifies role constants in the class RoleConstants.

The entity ResourceAction gets specified with the columns name, actionId, and bitwiseValue as follows:

<column name=”name” type=”String” /><column name=”actionId” type=”String” /><column name=”bitwiseValue” type=”long” />

The entity ResourcePermission gets specified with the columns name, scope, primKey, roleId, and actionIds as follows:

<column name=”name” type=”String” /><column name=”scope” type=”int” /><column name=”primKey” type=”String” /><column name=”roleId” type=”long” /><column name=”ownerId” type=”long” /><column name=”actionIds” type=”long” />

In addition, the portal specified resource permission constants in the class ResourcePermissionConstants.

Password policyThe portal implements enterprise password policies and user account lockout using the entities PasswordPolicy and PasswordPolicyRel, as shown in the following table:

Interface Extension Wrapper/Soap DescriptionPassword Policy

Password PolicyModel, Persisted Model

PasswordPolicy Wrapper, PasswordPolicy Soap

Columns: name, description, minAge, minAlphanumeric, minLength, minLowerCase, minNumbers, minSymbols, minUpperCase, lockout, maxFailure, lockoutDuration, and so on.

Password PolicyRel

Password PolicyRelModel, PersistedModel

PasswordPolicy RelWrapper, PasswordPolicy RelSoap

Columns: passwordPolicyId, classNameId, and classPK.

Ability to associate the entity PasswordPolicy with other entities.

Page 7: Common API - Packt

Chapter 11

[ 7 ]

As you can see, the entity PasswordPolicy can be associated with other entities, like User, Group, Organization, and so on, via the entity PasswordPolicyRel.

Password generatorThe portal has defined the following properties related to password authentication, encryption algorithm, and digest encoding in the portal.properties as follows:

basic.auth.password.required=truepasswords.encryption.algorithm=SHApasswords.digest.encoding=base64

The property basic.auth.password.required can be set to true to require a password, when using basic (also called the portal default) authentication. You can set this property to false only if additional security measures are in place to ensure that users have been properly authenticated.

Digested passwords can be encoded via base64 or hex encoding, by setting the property passwords.digest.encoding. The default is base64.

The property passwords.encryption.algorithm sets the encryption algorithm to encrypt passwords. The default algorithm is SHA (SHA-1). If it is set to NONE, passwords are stored in the database as plain text. The supported algorithms are BCRYPT, UFC-CRYPT, MD2, MD5, SHA-256, SHA-384, and SSHA. Note that the SHA-512 algorithm is currently unsupported.

Digester encodingThe portal defines the interface Digester.

The interface Digester and its implementation gets specified in the following table:

Class Interface Utility Property Main methodsDigesterImpl Digester DigesterUtil passwords.

digest.encoding

digest, digestBase64, digestHex, digestRaw, and so on.

Base64 None None None decode, encode, fromURLSafe, objectToString, stringToObject, toURLSafe, and so on.

Page 8: Common API - Packt

Common API

[ 8 ]

Class Interface Utility Property Main methodsPwdEncryptor None None passwords.

encryption.algorithm

encrypt,

default types: MD2, MD5, NONE, SHA, SHA-256, SHA-384, SSHA, UFC-CRYPT, and so on .

Passwords toolkitThe portal has defined the following properties related to the passwords toolkit in portal.properties:

passwords.toolkit= com.liferay.portal.security.pwd.PasswordPolicyToolkitpasswords.passwordpolicytoolkit.generator=dynamicpasswords.passwordpolicytoolkit.static=iheartliferay

The property passwords.toolkit defines a class name that extends com.liferay.portal.security.pwd.BasicToolkit, which is called to generate and validate passwords.

If you choose to use com.liferay.portal.security.pwd.PasswordPolicyToolkit as your password toolkit, you can choose either static or dynamic password generation. Static is set through the property passwords.passwordpolicytoolkit.static and dynamic uses the class com.liferay.util.PwdGenerator to generate the password. If you are using LDAP password syntax checking, you will also have to use the static generator, so that you can guarantee that passwords obey their rules.

The passwords’ toolkits are addressed in detail in the following table:

Class Extension Involved properties Main MethodsPassword PolicyToolkit

BasicToolkit passwords.passwordpolicytoolkit.charset.lowercase, passwords.passwordpolicytoolkit.charset.numbers, passwords.passwordpolicytoolkit.charset.symbols, passwords.passwordpolicytoolkit.charset.uppercase, passwords.passwordpolicytoolkit.generator, passwords.passwordpolicytoolkit.static

generate, validate

Page 9: Common API - Packt

Chapter 11

[ 9 ]

Class Extension Involved properties Main MethodsRegExpToolkit BasicToolkit passwords.regexptoolkit.

pattern, passwords.regexptoolkit.charset, passwords.regexptoolkit.length

generate, validate

PwdToolkit Util

None passwords.toolkit Generate, validate

PwdGenerator None None getPassword. getPinNumber

AuthenticationAuthentication is the process of determining whether someone or something is, in fact, who or what it is declared to be. The portal defines the class called PwdAuthenticator for authentication, as shown in the following code:

public static boolean authenticate( String login, String clearTextPassword, String currentEncryptedPassword){ String encryptedPassword = PwdEncryptor.encrypt( clearTextPassword, currentEncryptedPassword); if (currentEncryptedPassword.equals(encryptedPassword)){ return true;}}

As you can see, it encrypts the clear text password first into the variable encryptedPassword. It then tests whether the variable currentEncryptedPassword has the same value as that of the variable encryptedPassword or not. The classes UserLocalServiceImpl (the method authenticate) and EditUserAction (the method updateUser) call the class PwdAuthenticator for authentication.

A Message Authentication Code (MAC) is a short piece of information used to authenticate a message. The portal supports MAC through the following properties:

auth.mac.allow=falseauth.mac.algorithm=MD5auth.mac.shared.key=

To use authentication with MAC, simply post to a URL as follows:

http://${domain.name}/c/portal/login?cmd=already-registered&login=<userId|emailAddress>&password=<MAC>

Page 10: Common API - Packt

Common API

[ 10 ]

It passes the MAC in the password field. Make sure that the MAC gets URL encoded, since it might contain characters not allowed in a URL. Authentication with MAC also requires that you set the following property in system-ext.properties:

com.liferay.util.servlet.SessionParameters=false

As shown in the previous code, it encrypts session parameters, so that browsers can’t remember them.

Authentication pipelineThe portal provides the authentication pipeline framework for authentication, as shown in the following code:

auth.pipeline.pre=com.liferay.portal.security.auth.LDAPAuth#auth.pipeline.post=auth.pipeline.enable.liferay.check=true

As you can see, the property auth.pipeline.enable.liferay.check is set to true to enable password checking by the internal portal authentication. If it is set to false, essentially, password checking is delegated to the authenticators configured in the auth.pipeline.pre and auth.pipeline.post settings.

The interface com.liferay.portal.security.auth.Authenticator defines the constant values that should be used as return code from the classes implementing the interface. If authentication is successful, it returns SUCCESS; if the user exists but the passwords doesn’t match, then it returns FAILURE. If the user doesn’t exist in the system, it returns DNE. Constants get defined in the interface Authenticator.

As shown in the following table, the available authenticator is com.liferay.portal.security.auth.LDAPAuth:

Class Interface Properties Main MethodsLDAPAuth Authenticator ldap.auth.method, ldap.

referral, ldap.auth.password.encryption.algorithm, ldap.base.dn, ldap.error.user.lockout, ldap.error.password.expired, ldap.import.user.password.enabled, ldap.base.provider.url, auth.pipeline.enable.liferay.check, ldap.auth.required

authenticateBy EmailAddress, authenticateBy ScreenName, authenticate ByUserId

Page 11: Common API - Packt

Chapter 11

[ 11 ]

Authentication tokenThe portal provides the interface com.liferay.portal.security.auth.AuthToken for the authentication token as follows:

auth.token.check.enabled=trueauth.token.impl= com.liferay.portal.security.auth.SessionAuthToken

As shown in the previous code, the property auth.token.check.enabled is set to true to enable authentication token security checks. The checks can be disabled for specific actions via the property auth.token.ignore.actions or for specific portlets via the init parameter check-auth-token in portlet.xml.

The property auth.token.impl is set to the authentication token class. This class must implement the interface AuthToken. The class SessionAuthToken is used to prevent CSRF (Cross-Site Request Forgery) attacks.

The following table shows the interface AuthToken and its implementation:

Class Interface Properties Main methodsAuthTokenImpl AuthToken auth.token.impl check, getTokenAuthTokenWrapper AuthToken None check, getTokenAuthTokenUtil None None check, getTokenSessionAuthToken AuthToken auth.token.shared.

secretcheck, getToken

JAASJava Authentication and Authorization Service (JAAS) is a Java security framework for user-centric security to augment the Java code-based security. The portal has specified a set of properties for JAAS as follows:

portal.jaas.enable=falseportal.jaas.auth.type=userIdportal.impersonation.enable=true

The property portal.jaas.enable is set to false to disable JAAS security checks. Disabling JAAS would speed up login. Note that JAAS must be disabled, if administrators are able to impersonate other users. JAAS can authenticate users based on their e-mail address, screen name, user ID, or login, as determined by the property company.security.auth.type. By default, the class com.liferay.portal.security.jaas.PortalLoginModule loads the correct JAAS login module, based on what application server or servlet container the portal is deployed on. You can set a JAAS implementation class to override this behavior.

Page 12: Common API - Packt

Common API

[ 12 ]

The following table shows this class and its associations:

Class Interface/Extension

Package Main methods

Protected Principal

Principal com.liferay.portal.kernel.servlet

getName, equals, hasCode, toString

Portal Principal

Protected Principal

com.liferay.portal.kernel.security.jaas

PortalPrincipal

PortalRole Portal Principal

com.liferay.portal.kernel.security.jaas

PortalRole

PortalGroup Portal Principal, java.security.acl.Group

com.liferay.portal.kernel.security.jaas

addMember, isMember, members, removeMember

Portal LoginModule

javax.security.auth.spi.LoginModule

com.liferay.portal.kernel.security.jaas, com.liferay.portal.security.jaas

abort, commit, initialize, login, logout

As you have noticed, the classes com.liferay.portal.kernel.security.jaas, PortalLoginModule, and com.liferay.portal.security.jaas.PortalLoginModule, implement the interface LoginModule, configured by the property portal.jaas.impl.

As shown in the following table, the portal has provided different login module implementation for different application servers or servlet containers:

Class Name Interface/Extension Server type Main methods

BasicLogin Module

LoginModule basic, at the package com.liferay.portal.security.jaas.ext

abort, commit, initiate, login, logout

PortalLoginModule BasicLoginModule jboss Commit

PortalLoginModule BasicLoginModule jetty Commit

Page 13: Common API - Packt

Chapter 11

[ 13 ]

Class Name Interface/Extension Server type Main methods

PortalLoginModule BasicLoginModule jonas, _JGROUP: org.objectweb.jonas.security.auth.JGroup; _JPRINCIPAL: org.objectweb.jonas.security.auth.JPrincipal; _JROLE: org.objectweb.jonas.security.auth.JRole;

Commit

PortalLoginModule BasicLoginModule Resin Commit

PortalLoginModule BasicLoginModule Tomcat Commit

PortalLoginModule BasicLoginModule Weblogic commit

LDAP and SSOThe portal supports integration of SSO (Single Sign-on), CAS, NTLM, OpenID, OpenSSO, Facebook, and SiteMinder. As shown in the following diagram, the portal also supports integration of LDAP (Lightweight Directory Access Protocol) authentication, import, and export. LDAP server, which can be integrated into the portal, includes Apache Directory Server, Fedora Directory Server, Microsoft Active Directory Server, Novell eDirectory, OpenLDAP, OpenDS, and so on:

User

Group

component

LDAF

User Group

importcomponent

User

Role

component

Liferay Portal

componentcomponentcomponent

component

authentication

import

password

*

*

password

temporal / secure

association

*

*

Page 14: Common API - Packt

Common API

[ 14 ]

LDAPAs shown in the previous diagram, the portal does have capabilities to synchronize user custom attributes between Liferay and LDAP, to implement LDAP pagination via SearchControls, to configure the portal to create a role for each LDAP group, to configure the portal to either import or not import each LDAP user’s password, to configure the portal to either export or not export each LDAP user’s password, to override LDAP import and export processes via Spring beans, and so on.

As mentioned earlier, the portal defined the class LDAPAuth, implemented the interface Authenticator and the class LDAPAuthResult, and checked the following related properties:

ldap.referral,ldap.auth.method,ldap.auth.password.encryption.algorithm,ldap.base.dn,ldap.import.user.password.enabled,ldap.error.user.lockout,ldap.error.password.expired,ldap.base.provider.url,auth.pipeline.enable.liferay.check,ldap.auth.required

The portal also defines a set of classes, such as LDAPUser, LDAPGroup, and Modifications, as shown in the following table:

Class Involved LDAP interfaces

Involved portal interface

Main methods

LDAPUser LDAP User Contact, User, UserGroupRole

getAimSn, getBirthday, getComments, getContact, and so on.

LDAPGroup LDAP Group UserGroup, Role

getCompanyId, getDescription, getGroupName, and so on.

Modifications BasicAttribute, DirContext, Modification Item

None addItem

Page 15: Common API - Packt

Chapter 11

[ 15 ]

LDAP import and exportLDAPUser will be mapped into the portal User, while LDAPGroup and LDAPUser membership will be mapped into the portal UserGroup, Role, and User’s membership. This process is called LDAP import. Meanwhile, the portal User, UserGroup, and User’s membership will be mapped back into LDAPUser, Group, and User’s membership, respectively. This process is called LDAP export.

The portal has defined a set of interfaces, utilities, and implementations for LDAP import and export, as shown in the following table:

Class Interfaces Properties Main methodsPortalLDAP Util

UserConverter Keys

GroupConverter Keys

ldap.range.size, ldap.base.dn, ldap.import.user.search.filter, company.security.auth.type, company.security.auth.type, users.screen.name.always.autogenerate, ldap.page.size

getContext, getGroup*, getLdapSerrverId, getUser*, hasUser, searchLDAP, and so on.

PortalLDAP Context

DummyDirContext extends DummyContext implements DirContext

None getAttributes, setAttributes

LDAPSettings Util

ldap.auth.search.filter, ldap.contact.custom.mappings, ldap.contact.mappings, ldap.group.mappings, ldap.user.custom.mappings, ldap.user.mappings, ldap.export.enabled, ldap.export.group.enabled, ldap.import.enabled, ldap.import.on.startup, ldap.password.policy.enabled

get*, is*

BasePortal ToLDAP Converter

PortalToLDAPConverter

ldap.group.default.object.classes, ldap.user.default.object.classes,

get*

Page 16: Common API - Packt

Common API

[ 16 ]

Class Interfaces Properties Main methodsBaseLDAPTo Portal Converter

LDAPToPortal Converter

users.screen.name.always.autogenerate, users.email.address.required

importLDAPGroup, importLDAPUser

PortalLDAP ImporterImpl

PortalLDAP Importer

ldap.base.provider.url, ldap.import.method, ldap.base.dn, ldap.auth.search.filter, company.security.auth.type, ldap.import.group.search.filter, ldap.import.group.search.filter.enabled, ldap.export.enabled

importFromLDAP, importFromLDAP User*

PortalLDAP ExporterImpl

PortalLDAP Exporter

ldap.auth.required exportToLDAP

PortalLDAP Exporter Util

Default Attributes Transformer

AttributesTransformer

None transformGroup, transformUser

Securing the LDAP user’s passwordWhen importing users from LDAP, the user’s info and password is imported by default. Of course, all passwords stored in the portal are secure. It is important to note that the LDAP password mapping field is optional. In some use cases, the fact that the portal stores users’ password is against a company’s security policy rules. Fortunately, the portal secures the LDAP user’s password via the following properties.

ldap.import.user.password.enabled=trueldap.import.user.password.autogenerated=falseldap.import.user.password.default=test

The property ldap.import.user.password.enabled is set to false when the LDAP user’s password shouldn’t be imported. The property ldap.import.user.password.autogenerated is set to true to auto-generate the password for the imported user from LDAP. This property is only in use if the property ldap.import.user.password.enabled is set to false.

Page 17: Common API - Packt

Chapter 11

[ 17 ]

The property ldap.import.user.password.default is set as either screenName or plain text for the default password of the imported LDAP user. Setting the value to screenName will use the user’s screen name as the password for the imported LDAP user. Setting the value to any other plain text value will use that value as the password for the imported LDAP user. This property is only in use if the properties ldap.import.user.password.enabled and ldap.import.user.password.autogenerated are both set to false.

When exporting the LDAP users’ information, you may not export an LDAP user’s password from the portal to the LDAP server. This feature can be implemented by setting the following property:

ldap.export.user.password.enabled=true

As you can see, the property ldap.export.user.password.enabled is set to false, when the LDAP user’s password shouldn’t be exported.

Speed-up search of users and groupsAs mentioned earlier, base DN (Distinguished Name) is used as a base to search both users and groups. When the number of users and groups is small, you wouldn’t meet any performance bottleneck. But if the number of users and groups is huge, for example 500K+ users and 50K+ groups in the LDAP server, you would meet with a performance bottleneck when searching users and groups, as each user may be part of 50+ groups.

The real use case is that there are 500K+ users and 50K+ groups. Each user may be part of 50+ groups. When logged in as a user from the LDAP server, it always takes 20-30 seconds by default. It should take less than one second in general.

As you can see, LDAP import process and authentication can be improved a lot by using the base DN as the users-base DN for users search, and the custom group base DN should be used as the groups-base DN for groups search. Ideally, we should divide base DN ldap.base.dn into ldap.users.base.dn and ldap.groups.base.dn for searching users and groups, respectively.

Page 18: Common API - Packt

Common API

[ 18 ]

Single Sign-OnThe SSO integration is achieved by the filters, servlets, and/or utility classes. The following table shows the filters and utility classes of CAS, NTLM, and OpenSSO:

SSO Filter Extension/Interface

Properties Main Methods

CASFilter BasePortal Filter, BaseFilter, LiferayFilter

cas.auth.enabled, cas.server.name, cas.server.url, cas.service.url, cas.login.url, cas.logout.url

reload,getLog, getTickicketValidator, isFilterEnabled, processFilter

NtlmFilter BasePortal Filter

ntlm.auth.enabled, ntlm.auth.domain, ntlm.auth.domain.controller, ntlm.auth.domain.controller.name, ntlm.auth.service.account, ntlm.auth.service.password

getLog, getNtmlManager, init, isFilterEnabled, processFilter

NtlmPost Filter

BasePortal Filter

None getLog, processFilter

OpenSSO Filter

BasePortal Filter

open.sso.auth.enabled, open.sso.login.url, open.sso.logout.url, open.sso.service.url,

isFilterEnabled, processFilter

OpenSSOU til

None None getAttributes, getSubjectId, isAuthenticated, isValidServiceUrl, isvalidUrl, isvalidaUrls

Page 19: Common API - Packt

Chapter 11

[ 19 ]

FacebookConnectThe portal comes with an additional Single Sign-On option—Facebook SSO using OAuth 2.0. Facebook connection got defined in the interface FacebookConnect and the servlet FacebookServlet, as shown in the following table:

Class Interface Properties/servlet mapping

Main methods

Facebook ConnectImpl

Facebook Connect

facebook.connect.app.id, facebook.connect.app.secret, facebook.connect.auth.enabled, facebook.connect.graph.url, facebook.connect.oauth.auth.url, facebook.connect.oauth.redirect.url, facebook.connect.oauth.token.url

getAccessToken, getAppId, getAppSecret, getAuthURL, getGraph Resources, getGraphUrl, and so on.

Facebook ConnectUtil

None None setFacbook Connet, and so on.

Facebook Servlet

HttpServlet <servlet-name>Facebook Servlet</servlet-name>

<url-pattern>/facebook/*</url-pattern>

fixFbm, service

Facebook ConnectAction

Portlet Action

None Render, strutsExecute

Page 20: Common API - Packt

Common API

[ 20 ]

OpenId and SiteMinderAs shown in the following table, the portal opens the door to integrate OpenId and SiteMinder:

Class Interface Properties Main methodsOpenIdUtil org.openid4java.

consumer.ConsumerManager, InMemoryConsumer AssociationStore, InMemoryNonce Verifier

open.id.auth.enabled

getConsumer Manager, getScreenName, isEnabled, normalize

OpenIdAutoLogin AutoLogin None login

OpenIdAction PortletAction None processAction, render

SiteMinder LogoutAction

Action siteminder.auth.enabled

run

SiteMinder AutoLogin

AutoLogin siteminder.user.header, siteminder.import.from.ldap

login

AutoLoginThe portal has specified the AutoLogin interface.

As you can see in the following table, you can set a request attribute with the variable AUTO_LOGIN_REDIRECT to tell the filter AutoLoginFilter to stop processing filters and redirect the user to a specified location. You can also set a request attribute with the variable AUTO_LOGIN_REDIRECT_AND_CONTINUE to tell the filter AutoLoginFilter to continue processing filters and then redirect the user to a specified location:

Class Interface/Extension

Properties Main methods

AutoLoginFilter BasePortal Filter

portal.jaas.enable, session.store.password, auto.login.hooks

register AutoLogin, unregister AutoLogin, getLogin RemoteUser, processFilter

Page 21: Common API - Packt

Chapter 11

[ 21 ]

Class Interface/Extension

Properties Main methods

BasicAuthHeader AutoLogin

AutoLogin None login

CASAutoLogin, FacebookAutoLogin, NtlmAutoLogin, OpenSSOAutoLogin, ParameterAutoLogin, RememberMeAuto Login, RequestHeader AutoLogin

AutoLogin request.header.auth.import.from.ldap, cas.import.from.ldap, cas.no.such.user.redirect.url, company.security.auth.type, and so on.

login

Tracking and auditingThe portal has specified a set of models and services to track and/or audit a user’s actions. The following section is going to address these models and services.

TrackingThe portal has defined a few entities to persist BrowserTracker, PasswordTracker, and UserTracker.

The portal has also defined a set of services for BrowserTracker and PasswordTracker, as shown in the following table:

Service Interface Extension Main methods Utility/WrapperBrowserTracker LocalService

PersistedModel LocalService

add*, create*, delete*, fetch*, get*, set*, update*

BrowserTrackerLocalServiceUtil(Wrapper)

PasswordTracker LocalService

PersistedModel LocalService

add*, create*, delete*, fetch*, get*, is*, set*, track*, update*

PasswordTrackerLocalServiceUtil(Wrapper)

Page 22: Common API - Packt

Common API

[ 22 ]

UserTrackerBesides the UserTracker models, such as UserTracker and UserTrackerPath, the portal also provides a set of UserTracker services, as shown in the following table:

Service Interface Extension Main methods Utility/WrapperUserTracker LocalService

PersistedModel LocalService

add*, create*, delete*, fetch*, get*, set*, update*

UserTrackerLocalServiceUtil(Wrapper)

UserTracker PathLocalService

PersistedModel LocalService

add*, create*, delete*, fetch*, get*, set*, update*

UserTrackerPathLocalServiceUtil(Wrapper)

In particular, the portal has specified the following tracking-related properties in portal.properties. Note that this is not a lightweight way to set up the portal.

live.users.enabled=falsesession.tracker.memory.enabled=truesession.tracker.ignore.paths=\ /portal/render_portlet,\ /document_library/get_file

As shown in the previous code, the property live.users.enabled is set to true to enable tracking via LiveUsers. The property session.tracker.memory.enabled is set to true to track user clicks in memory for the duration of the user’s session. Setting this to true allows you to view all live sessions via LiveUsers.

The property session.tracker.friendly.paths.enabled is set to true to convert the tracked paths to friendly URLs via PortalRequestProcessor. The property session.tracker.ignore.paths defines a list of comma-delimited paths that shouldn’t be tracked in the PortalRequestProcessor.

The property session.tracker.persistence.enabled is set to true to track user clicks in the database, after a user’s session is invalidated. Setting this to true will allow you to generate usage reports from the database via UserTrackerLocalServiceImpl (you can call UserTrackerLocalServiceUtil in the plugins). Use this cautiously, because this will store a lot of usage data.

Page 23: Common API - Packt

Chapter 11

[ 23 ]

The following table shows where the previous properties get checked:

Class Name Extension/Involved models

Involved properties Main methods

PortalRequest Processor

TilesRequest Processor

session.tracker.friendly.paths.enabled, session.tracker.ignore.paths

processPath

LiveUsers Company, UserTracker

live.users.enabled, session.tracker.memory.enabled

deleteGroup, getGroupUsers, getGroupUsers Count, getSessionUsers, getUserTracker, joinGroup, leaveGroup, signIn, signOut

UserTracker LocalService Impl

UserTrackerLocal ServiceBaseImpl

session.tracker.persistence.enabled

addUserTracker

AuditingAn audit trail of user actions is required by many organizations. Fortunately, the portal provides an audit service—a pluggable way of storing the audit trail from the portal and plugins. The information processed by the audit service plugin can be stored into a log file or database. Loosely speaking, audit services employ Liferay Lightweight Message Bus and Plugin architecture. The audit services handle the processing and logging of the audit messages, sent through the Message Bus. Therefore, any plugin can then produce audit messages to the audit Message Bus destination.

Audit servicesThe portal has provided a set of audit services interfaces, such as AuditMessage, AuditMessageFactory, AuditMessageProcessor, and AuditRouter, as shown in the following table:

Utility/Implementation Interface/Extension Involved classes DescriptionAuditMessageFactoryImpl AuditMessage

FactoryAuditMessage JSONObject

Audit message factory

AuditMessageFactoryUtil AuditMessage Factory

AuditMessage JSONObject

Audit message factory utility

Page 24: Common API - Packt

Common API

[ 24 ]

Utility/Implementation Interface/Extension Involved classes DescriptionAuditRouterProxyBean BaseProxyBean

implements AuditRouter

AuditMessage Audit router proxy bean

AuditRouterUtil AuditRouter AuditMessage Audit router utility

(available implementation in the plugins)

AuditMessage Processor

AuditMessage Audit message processor interface

The audit service beans are specified in audit-spring.xml.

Audit filterAn auditing framework has been added to the portal. The auditing framework will allow the system administrator to track a user’s action. The portal has the following settings for the auditing framework in portal.properties:

com.liferay.portal.servlet.filters.audit.AuditFilter=false

As you can see, the auditing framework has been disabled by default. This is helpful to speed up the portal. To enable the auditing framework, you can set the property to true in portal-ext.properties.

The audit filter populates AuditRequestThreadLocal with the appropriate request values to generate audit requests. Note that if an administrator is impersonating another user, the audit records look as if the actions are performed by the impersonated user. Ideally, the records should record the real user that performs an action:

Class name Interface/extension

Involved classes Description

AuditRequest ThreadLocal

None AutoResetThreadLocal<T> extends InitialThreadLocal<T>

Audit request local thread

AuditFilter BasePortal Filter implements TryFilter

HttpServletRequest; HttpServletResponse; HttpSession;

AuditRequestThreadLocal

Audit filter

As shown in the previous table, the interface TryFilter extends DirectCallFilter.

Page 25: Common API - Packt

Chapter 11

[ 25 ]

In addition, the interface InitialThreadLocal<T> extends CentralizedThreadLocal<T>. The interface CentralizedThreadLocal<T> extends ThreadLocal<T>.

Velocity variablesAs mentioned in Chapter 10, WAP and Portlet Bridges, the class VelocityVariablesImpl implements VelocityVariables. Two Velocity variables (auditMessageFactoryUtil and auditRouterUtil) get defined in the class VelocityVariablesImpl as follows:

// Audit message factoryvelocityContext.put(“auditMessageFactoryUtil”, AuditMessageFactoryUtil.getAuditMessageFactory());// Audit router utilvelocityContext.put(“auditRouterUtil”, AuditRouterUtil.getAuditRouter());

As shown in the previous code, Two Velocity variables, auditMessageFactoryUtil and auditRouterUtil get specified as AuditMessageFactoryUtil.getAuditMessageFactory() and AuditRouterUtil.getAuditRouter(), respectively.

Auditing in the portalThe class LayoutAction of the portal core has applied the classes AuditMessage and AuditRouterUtil.

It applies the audit framework on the object Layout (that is, the instance of a page) in the portal. You can leverage similar sample code and apply it on the other objects, such as users, groups, and so on. In fact, an audit message has been specified in the portal.properties as follows:

audit.message.com.liferay.portal.model.Layout.VIEW=false

Of course, you can override the same in the portal-ext.properties.

Page 26: Common API - Packt

Common API

[ 26 ]

Audit hookThe following events get audited in the plugin audit-hook: LOGIN, LOGOUT, LOGIN FAILURE, IMPERSONATION, ROLE CREATE, REMOVE, UPDATE, ROLE GRANT, REVOKE, USER CREATE, REMOVE, UPDATE, USER GROUP CREATE, REMOVE, UPDATE, USER GROUP ASSIGN, and REVOKE. How? The plugin audit-hook adds the following hooks in the liferay-hook.xml as follows:

<hook> <portal-properties>portal.properties</portal-properties></hook>

Furthermore, the audit-hook provides the hooks in the /WEB-INF/src/portal.properties as follows:

// see details in portal.propertiesvalue.object.listener.com.liferay.portal.model.UserGroupRole=com.liferay.portal.audit.hook.listeners.UserGroupRoleListener

The following table shows detailed information about these portal properties hooks:

Class Name Interface/Abstract Class Property DescriptionLoginFailure Audit

LoginFailure auth.failure This class will run when a user has a failed login or when a user has reached the maximum number of failed logins.

Impersonation Audit

Action servlet.service.events.pre

The pre-service events process before Struts processes the request.

LoginAudit Action login.events.post

The post-service events process after Struts processes the request.

LogoutAudit Action logout.events.post

The post-service events process after Struts processes the request.

Address Listener

BaseModelListener <Address>

value.object.listener.*

Model Address onBeforeUpdate

Contact Listener

BaseModelListener <Contact>

value.object.listener.*

Model Contact onBeforeUpdate

Page 27: Common API - Packt

Chapter 11

[ 27 ]

Class Name Interface/Abstract Class Property DescriptionRole Listener

BaseModelListener <Role>

value.object.listener.*

Model Role: onBeforeAdd Association, onBeforeCreate, onBeforeRemove, onBeforeRemove Association, onBeforeUpdate

UserGroup Listener

BaseModelListener <UserGroup>

value.object.listener.*

Model User Group: onBeforeAdd Association, onBeforeCreate, onBeforeRemove, onBeforeRemove Association, onBeforeUpdate

UserGroupRole Listener

BaseModelListener <UserGroupRole>

value.object.listener.*

Model User Group Role: onBeforeCreate, onBeforeRemove

UserListener BaseModelListener <User>

value.object.listener.*

Model User: onBeforeCreate, onBeforeRemove, onBeforeUpdate

Event types get defined in the interface EventTypes. EventTypes cover ADD, ASSIGN, DELETE, IMPERSONATE, LOGIN, LOGIN_FAILURE, LOGOUT, UNASSIGN, and UPDATE. Of course, you can add more event types in the plugin audit-hook.

Audit reportsThe plugin audit-portlet provides the ability to manage audit reports. The plugin stores the information processed by the audit service in a model called AuditEvent, with a package named com.liferay.portal.audit. The model is specified in detail in service.xml as follows:

<column name=”eventType” type=”String” /><column name=”className” type=”String” /><column name=”classPK” type=”String” /><column name=”additionalInfo” type=”String” />

Page 28: Common API - Packt

Common API

[ 28 ]

As you can see, the entry AuditEvent includes the following columns:

• event ID as primary key• Additional Info• Class Name• Class PK• Client Host• Client IP• Cmpany ID• Message• Server Name• Server Port• Session ID• Timestamp• User ID• User Name• Oiginal Message

The audit service beans have been overridden in audit-spring.xml, as shown in the following table:

Bean Interface Properties DescriptionJSONLogMessage Formatter

LogMessage Formatter

None JSON message formatters

CSVLogMessage Formatter

LogMessage Formatter

columns: additionalInfo,className,classPK,clientHost,clientIP,companyId,eventType,message,serverName,serverPort,sessionID,timestamp,userId,userName

CSV message formatters

DatabaseAudit RouterProcessor

AuditRouter Processor

None Database audit router processor

Page 29: Common API - Packt

Chapter 11

[ 29 ]

Bean Interface Properties DescriptionLogAuditRouter Processor

AuditRouter Processor

logMessageFormatter: CSVLogMessageFormatter

outputToConsole: false

Log audit router processor

DefaultAudit Router

AuditRouter globalAuditMessage Processors: list (AuditMessageProcessor) - DatabaseAuditRouter Processor, LogAuditRouterProcessor

Default audit router

As you can see, the audit message can be stored into a log file or a database. The audit log CSV (Comma Separated Values) is configured to be the properties, as shown in the previous table. In particular, you can find more details of the plugins audit-hook and audit-portlet in the attached code.

Web server servletThe portal has defined the downloading service, that is, the servlet class WebServerServlet. The servlet is specified in web.xml as follows:

<!-- see details in web.xml --><servlet-mapping> <servlet-name>Web Server Servlet</servlet-name> <url-pattern>/documents/*</url-pattern></servlet-mapping><servlet-mapping> <servlet-name>Web Server Servlet</servlet-name> <url-pattern>/image/*</url-pattern></servlet-mapping>

Therefore, documents (for example, basic documents, records, images, videos, and audios) have the following download file URL pattern:

String fileUrl = themeDisplay.getPortalURL() + themeDisplay.getPathContext() + “/documents/” + themeDisplay.getScopeGroupId() + StringPool.SLASH + folderId + StringPool.SLASH + HttpUtil.encodeURL(fileEntry.getTitle());

For more information, you can refer to the details at /portlet/document_library/view_file_entry.jsp.

Page 30: Common API - Packt

Common API

[ 30 ]

The following table shows a summary of the servlet class WebServerServlet:

Class name Interface Involved interfaces/classes

Description

WebServerServlet HttpServlet Company, Group, Image, User, DLFileEntry, DLFileShortcut

Web server servlet for the URL pattern: /documents/*, /image/*

WebServerEntry None Date Web server entryWebServerServlet TokenImpl

WebServer ServletToken

MultiVMPool, PortalCache, CacheUtil,

Web server servlet token implementation

As shown in the previous table, the interface WebServerServletToken has defined the following functions like getting and resetting a token using the image ID.

Document Library recordThe plugin Document Library record hook used to audit who downloaded a special resource like Document Library documents, images, records, audios, videos, and so on.

The plugin uses a set of models, namely, DLRecordDifinition and DLRecordLog. As you can see, the plugin document-library-record-portlet has specified services and models with a package named com.liferay.dlrecord. You will be able to find the details at /WEB-INF/service.xml. The entity DLRecordDifinition, which specifies the DLFileEntry definition, includes the following columns:

<column name=”name” type=”String” /><column name=”title” type=”String” /><column name=”signinRequired” type=”boolean” />

The entity DLRecordLog, which specifies who downloaded the document from the DLFileEntry definition, includes the following columns:

<column name=”definitionId” type=”long” /><column name=”documentType” type=”String” /><column name=”createDate” type=”Date” />

As shown in the previous code, it provides capabilities to regroup the logs by the definition ID, content type, user ID, group ID, company ID, and created date. Of course, you can customize this service model and use service builder in the SDK plugins to re-generate services.

Page 31: Common API - Packt

Chapter 11

[ 31 ]

In addition, the plugin document-library-record-portlet hooks the servlet WebServerServlet and traces the URL patterns such as /documents/* and /image/*. Of course, you can find details of the plugin document-library-record-portlet from the attached code.

Rule and reporting enginesLoosely speaking, a business rule is a statement that defines or constrains the business aspect. In general, a business rule is different from strategy. Business rules tell an organization what it can do in detail, while strategy tells an organization how to focus the business at a macro level to optimize results. And going further, a business rule engine is a software system that executes business rules in a runtime production environment. The portal provides capability to integrate the rule engine called Drools: a Business Rule Management System (BRMS) with a forward-chaining inference-based rules engine, using an enhanced implementation of the Rete algorithm. Refer to http://www.jboss.org/drools/ for more details.

The portal also provides capability to integrate the reporting engine called JasperReports. How is the integration being done? It is the report portlet that accesses JasperReport through web services. JasperReports is an open source Java reporting engine that uses data coming from any kind of data source, and produces pixel-perfect documents, viewed, printed, or exported in a variety of document formats, including HTML, PDF, Excel, OpenOffice, and Word. Refer to http://jasperforge.org/projects/jasperreports.

An alternative reporting engine is BIRT, which is an open source software project that provides reporting and business intelligence capabilities for rich client and web applications. Refer to http://www.eclipse.org/birt/phoenix/.

Rule engineThe portal has specified the rule engine interface called RuleEngine, where its methods include add, containsRuleDomain, execute, remove, and update. The following table shows the interface and its related objects and classes:

Interface/Class Utility/Interface Implementation DescriptionRulesEngine RulesEngine

UtilRulesEngine ProxyBean

Rule engine interface and implementation

Fact Serializable None Involved class: Fact<T>Query Serializable None Involved class: QueryTypeRulesResource Retriever

Serializable None Involved class: ResourceRetriever

Page 32: Common API - Packt

Common API

[ 32 ]

Interface/Class Utility/Interface Implementation DescriptionRulesLanguage None None DROOLS_BRL, DROOLS_

CHANGE_SET, DROOLS_DECISION_TABLE, DROOLS_DOMAIN_SPECIFIC, DROOLS_DOMAIN_SPECIFIC_RULE, DROOLS_PKG, DROOLS_RULE_FLOW, DROOLS_RULE_LANGUAGE, DROOLS_XML_LANGUAGE

The portal has specified the rule engine-related beans in the XML file rule-spring.xml at src/META-INF/rules-spring.xml:

Bean Id/Ref/Class Properties DescriptionAdvice messaging

ProxyAdviceNone AOP configuration:

<aop:around pointcut=”bean(com.liferay.portal.bi.rules.

RulesEngine ProxyBean)”

method=”invoke” />

Proxy com.liferay.portal.bi.rules.RulesEngine ProxyBean

singleDestination Synchronous MessageSender

singleDestination MessageSender

destinationName: “liferay/rules_engine”

Utility com.liferay.portal.kernel.bi.rules.Rules EngineUtil

rulesEngine Rules engine utility bean

Messaging destination.rules_engine

messaging Configurator .rules

name: liferay/rules_engine destinations messageBus

Classes: ParallelDestination, DefaultMessaging Configurator, and MessageBus

Page 33: Common API - Packt

Chapter 11

[ 33 ]

Drools webThe portal provides full integration of Drools within the rule engine framework—the plugin drools-web uses the Drools server as the rule engine in the portal. The rule Spring beans and its related messaging Spring beans is specified in the XML files drools-spring.xml and messaging-spring.xml in the folder /docroot/WEB-INF/src/META-INF, respectively. As shown in the following lines, the XML files drools-spring.xml and messaging-spring.xml are defined as the values of the parameter named portalContextConfigLocation in web.xml:

<context-param><param-name>portalContextConfigLocation</param-name> <param-value> /WEB-INF/classes/META-INF/drools-spring.xml, /WEB-INF/classes/META-INF/messaging-spring.xml </param-value></context-param>

The plugin drools-web implements the interface RulesEngine, as shown in the following table.

Implementation Interface Involved classes DescriptionRulesEngineImpl RulesEngine org.drools.*:

KnowledgeBase, KnowledgeBuilder, ResourceType, Command, Resource, QueryResults, QueryResultsRow

com.liferay.portal.kernel.bi.rules.*

Fact; Query; QueryType; RulesLanguage; RulesResource Retriever

ClassField AccessorCache

none ProtectionDomain; HashMap; Map; WeakHashMap; ConcurrentHashMap; ConcurrentMap;

org.drools.core. util.asm.ClassField Inspector

Class field Accessor cache

Page 34: Common API - Packt

Common API

[ 34 ]

Report engineThe portal has specified the interface called ReportEngine for the reporting engine, where its methods include compile, destroy, execute, init, setEngineParameters, and setReportFormatExporterRegistry. The following table shows the interface and its related objects and classes:

Interface/Class Utility/Interface Main involved classes

Description

ReportEngine ReportEngine Util

ServletContext Report engine interface

ReportRequest Serializable Map Report requestReportRequest Context

Serializable Map, HashMap Report request context

ReportFormat None None Report formats: CSV(“csv”), HTML(“html”), PDF(“pdf”), RTF(“rtf”), TXT(“txt”), XLS(“xls”), XML(“xml”)

ReportFormat Exporter

None reportRequest,ReportResultContainer

Report format exporter

ReportData SourceType

None None Report data source types: CSV(“csv”), EMPTY(“empty”), JDBC(“jdbc”), PORTAL(“portal”), XLS(“xls”), XML(“xml”)

JasperReports webThe portal provides full integration of the JasperReports with the reporting framework: the plugin jasperreports-web uses the JasperReports server as the reporting engine in the portal. The reporting Spring beans and its related messaging Spring beans get specified in the XML files jasperreports-spring.xml and messaging-spring.xml, respectively, at the folder /docroot/WEB-INF/src/META-INF. As shown in the following lines, the XML files jasperreports-spring.xml and messaging-spring.xml get defined as the value of the parameter name portalContextConfigLocation in web.xml:

<context-param> <param-name>portalContextConfigLocation</param-name>

Page 35: Common API - Packt

Chapter 11

[ 35 ]

<param-value> /WEB-INF/classes/META-INF/jasperreports-spring.xml, /WEB-INF/classes/META-INF/messaging-spring.xml </param-value></context-param>

The following table shows a summary of this report engine implementation:

Implementation Interface Involved classes DescriptionReportEngineImpl ReportEngine ReportRequest,

ReportFormat Exporter, ReportRequest Context, ReportResult Container

Jasper reports engine implementation

CachedReport Compiler,

DefaultReport Compiler

ReportCompiler ReportDesign Retriever, JasperCompile Manager, JasperReport

Cache report compiler, default report compiler

BaseReport FormatExporter, CsvReport FormatExporter, HtmlReport FormatExporter, PdfReport FormatExporter, RtfReport FormatExporter, TextFormat Exporter, XlsFormatExporter, XmlFormatExporter

ReportFormat Exporter

JRExporter, JRCsvExporter, JRHtmlExporter, JRPdfExporter, JRRtfExporter, JRTxtExporter, JRXlsExporter, JRXmlExporter

Report format exporter: CSV, HTML, PDF, RTF, TXT, XLS, and XML

Reports portletThe portal provides the plugin called reports-portlet, which has the ability to schedule reports and deliver them via Document Library and e-mail. The plugin defines two portlets: Reports Admin at the Control Panel and Reports Display. The portlet Reports Display is instanceable—that is, you can add more than one instance of the portlet to a page.

Page 36: Common API - Packt

Common API

[ 36 ]

As shown in the following diagram, the plugin reports-portlet defines three entities, namely, Entity, Definition, and Source. The entity Source may have many Definition instances, and the entity Definition may have many Entity instances, which are shown as follows:

Entry Definition Sourcec c c

* *

Based on service.xml, a set of reporting services are generated, as shown in the following table:

Interface Extension Main methods

Persistence Utility/Clp/Wrapper

Definition (Local) Service

Persisted ModelLocal Service

add*, delete*, get*, update*

Definition Persistence extends BasePersistence <Definition>, DefinitionUtil

Definition (Local)ServiceUtil (Clp)(Wrapper)

Entity (Local)Service

Persisted ModelLocal Service

add*, delete*, get*, unschedule

EntityPersistence extends BasePersistence <Entity>, EntityUtil

Entity(Local)ServiceUtil (Clp)(Wrapper)

Source (Local)Service

Persisted ModelLocal Service

add*, delete*, get*, updated*

SourcePersistence extends BasePersistence <Source>, SourceUtil

Source(Local)ServiceUtil (Clp)(Wrapper)

In particular, you can find more details about the plugin reports-portlet in the attached code.

Page 37: Common API - Packt

Chapter 11

[ 37 ]

Scripting engineThe scripting engine is a framework; providing the portal with a general, pluggable architecture. It provides scripting services to various areas of the portal such as Web Content, Workflow, plugin portlets, administration, and maintenance support. The supported scripting languages include BeanShell, Groovy, JavaScript, Python, and Ruby. BeanShell is a small and embeddable Java source interpreter with object scripting language features written in Java. For more details, refer to http://www.beanshell.org/.

The scripting engine gets defined by the interfaces Scripting and ScriptingExecutor, as shown in the following table:

Interface Utility/Abstract Implementation Main methodsScripting ScriptingUtil ScriptingImpl add*, set*, get*,

clearCache, eval, exec

Scripting Executor

BaseScripting Executor

BeanShellExecutor, GroovyExecutor, JavaScriptExecutor, PythonExecutor, RubyExecutor

clearCache, getLanguage, eval

By default, the scripting engine is available at the Control Panel, more precisely, at the section Server | Server Administration | Script. The user interface gets defined at /html/portlet/admin/server.jspf. The action Execute is defined in the class EditServerAction. More precisely, it defines a method named runScript to call ScriptingUtil.exec (null, portletObjects, language, script).

PollerThe Polling or polled operation refers to actively sampling the status of an external device by a client program as a synchronous activity. The portal has defined the poller Spring beans in the XML file poller-spring.xml at /portal-impl/src/META-INF/poller-spring.xml.

Page 38: Common API - Packt

Common API

[ 38 ]

The portal defines the poller utilities and messaging, as shown in the following table:

Type Class Property Ref/Id Descriptionutility PollerRequest

HandlerUtilpoller Request Handler

message Listener.poller Request Handle

PollerRequest HandlerImpl implements Poller Request Handler, Message Listener

utility PollerComet DelayedJob Util

poller Comet DelayedJob

message Listener.Poller CometDelayed Job

PollerComet DelayedJobImpl extends BaseMessage Listener implements PollerComet DelayedJob

messaging Parallel Destination

name:liferay/poller, workers coresize:25, workers maxsize:25

destination.poller

Poller destination

messaging Parallel Destination

name: liferay/poller_comet_response liferay/poller

workers coresize: 25, workersmax size: 25

destination.poller_comet_response

Poller comet response

messaging PollerRequest Message Listener

None message Listener.poller

Poller request message listener

messaging PollerComet DelayedJob Impl

None message Listener.PollerComet DelayedJob

Poller comet delayed job message listener

messaging Poller Notifications BridgeMessage Listener

None message Listener.poller Notifications Bridge

Poller notification bridge message listener

messaging PollerRequest HandlerImpl

None message Listener.pollerRequest Handler

Poller request handler message listener

Page 39: Common API - Packt

Chapter 11

[ 39 ]

In addition, the portal provides a set of poller interfaces and their implementation, as shown in the following table:

Interface Implementation Utility DescriptionPollerProcessor BasePoller

ProcessorPollerProcessor Util

Poller processor and involved classes: PollerSession

PollerResponse DefaultPoller Response

none Poller response

PollerRequest Handler

PollerRequest HandlerImpl

PollerRequest HandlerUtil

Poller request handler

None PollerHeader

PollerRequest

none Poller header and request

Integrating comet with pollerComet is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it. Other names are known as Ajax Push, Reverse Ajax, Two-way-web, HTTP Streaming, and HTTP server push, among others. The portal integrated Comet with Poller via the interface, CometHandler.

The following table shows the interface CometHandler, its related extension, and implementation:

Interface Abstract class/Implementation

Extension/Utility Description

Comet Handler

BaseCometHandler PollerComet Handler

Comet handler and its implementation: CatalinaCometProcessor extends HttpServlet implements org.apache.catalina.comet.CometProcessor

Comet Session

BaseCometSession CatalinaComet Session CatalinaComet SessionUtil

Comet session and Catalina implementation at /support-tomcat/src

Comet Request

BaseCometRequest CatalinaComet Request

Comet request and Catalina implementation

Comet Response

BaseCometResponse CatalinaComet Response

Comet response and Catalina implementation

Page 40: Common API - Packt

Common API

[ 40 ]

Interface Abstract class/Implementation

Extension/Utility Description

None CometHandlerPool CometHandler PoolUtil

Involved classes: java.util.concurrent.locks.Lock; ReadWriteLock; ReentrantReadWriteLock

Comet State

None None Comet state, called in the class BaseCometHandler;

States: STATE_CLOSED, STATE_OPEN, STATE_READY

Poller servletThe portal has specified a servlet called PollerServlet for the polling mechanism. The servlet extends the class HttpServlet. The involved classes are JSONObject, HttpServletRequest, HttpServletResponse, ServletResponseUtil, SynchronousPollerChannelListener, and so on. The polling URL pattern /poller/* is specified in the web.xml as follows:

<!-- see details in web.xml --><servlet-mapping> <servlet-name>Poller Servlet</servlet-name> <url-pattern>/poller/*</url-pattern></servlet-mapping>

Poller processorAs specified in the Liferay portlet app DTD (refer to /definitions/liferay-portlet-app_6_1_0.dtd), the poller-processor-class value must be a class that implements com.liferay.portal.kernel.poller.PollerProcessor, and it is triggered by the JavaScript class Liferay.Poller. It allows a portlet to use polling to be notified of data changes.

The JavaScript class, Liferay.Poller, is defined in the poller.js (refer to /html/js/liferay/poller.js).

The functions include _createRequestTimer, _processResponse, _receive, _releaseLock, _sendComplete, _send, Poller, and so on.

The portal has specified the interface PollerProcessor with the methods receive and send.

Page 41: Common API - Packt

Chapter 11

[ 41 ]

The plugin chat-portlet defines the class ChatPollerProcessor, extending the abstract class BasePollerProcessor, which implements the interface PollerPocessor. The class ChatPollerProcessor is specified in liferay-portlet.xml as follows:

<poller-processor-class> com.liferay.chat.poller.ChatPollerProcessor</poller-processor-class>

As you can see, the class ChatPollerProcessor implements the interface PollerProcessor.

JavaScript pollingYUI provides the DataTable to poll for data from its DataSource. The polling feature replaces existing data, rather than continuously adding data to the page. The following is the sample code. The DataTable polls for data from its DataSource every five seconds. For more details, refer to http://yuilibrary.com/:

<script type=”text/javascript”> YAHOO.util.Event.addListener(window, “load”, function() { YAHOO.example.Polling = function() { // ignore details myDataSource.setInterval(5000, null, myCallback); // ignore details }(); });</script>

The jQuery polling plugin, called Ajax Poll plugin for jQuery, allows us to check a URL for updated content at a regular interval. It has an increment in poll interval when there is no new content, has as many pollers as you want, changes all the Ajax settings for a Poller even after it is created, resets the poll interval to a specific value at any time, and uses a custom function to determine when the next poll should be. For more information, refer to http://plugins.jquery.com/project/poll.

Web servicesGenerally speaking, web services are resources that may be called over the HTTP(s) protocol to return data. They are platform-independent, allowing communication between applications on different operating systems and application servers. When the database entries are generated by the service builder, web services can be generated as well, based on Apache Axis. As a result, nearly all of the backend API calls can be made using web services.

Page 42: Common API - Packt

Common API

[ 42 ]

Java clients may be generated from Web Service Definition Language (WSDL) using any number of tools (Axis, Xfire-CXF, JAX-RPC, and so on). Apache Axis is essentially a Simple Object Access Protocol (SOAP) engine—a framework for constructing SOAP processors such as clients, servers, gateways, and so on. For more information, refer to http://ws.apache.org/axis/.

Built-in web servicesThe portal provides built-in web services for the portal core entities. The following table depicts an overview of these web services:

Locator class Web service name SOAP SOAP main methodsOrganization ServiceSoap ServiceLocator

Portal_Organization Service

Organization ServiceSoap

addOrganizations, addOrganization, addPasswordPolicy Organizations, deleteLogo, delete Organization, and so on.

RoleService SoapService Locator

Portal_Role Service

RoleService Soap

addUserRoles, deleteRole, getGroupRoles, getRole, hasUserRole, hasUserRoles, and so on.

JournalArticle ServiceSoap ServiceLocator

Portlet_Journal_Journal Article Service

JournalArticle ServiceSoap

copyArticle, deleteArticle, expireArticle, getArticle, subscribe, unsubscribe, searchCount, search, updateArticle, removeArticle Locale, and so on.

AssetEntry ServiceSoap ServiceLocator

AssetEntry ServiceSoap

Portlet_Asset_AssetEntry Service

getCompanyEntries Count, getCompanyEntries, getEntriesCount, getEntries, getEntry, incrementView Counter, and so on.

As shown in the previous table, only a few web services got addressed. For the entire set of web services, you can refer to the JAR file portal-client.jar at /portal-client/portal-client.jar.

Page 43: Common API - Packt

Chapter 11

[ 43 ]

Ant build-wsddHow to generate/update the WSDD (Web Service Deployment Descriptor) file server-config.wsdd? The portal has defined the Ant target build-wsdd to generate the WSDD file server-config.wsdd.

For more details, you can refer to the Ant target build-wsdd at /portal-impl/build.xml.

Ant build-clientThe portal has defined the Ant target build-client to generate the JAR file portal-client.jar. The following is the sample code for the Ant build-client. It uses server-config.wsdd and namespace-mapping.properties as parameters:

<target name=”build-client” depends=”clean”><!—- see details in build.xml --><arg value=”${project.dir}/tunnel-web/docroot/WEB-INF/server-config.wsdd” /><arg value=”src” /><arg value=”namespace-mapping.properties” /><arg value=”${client.url}” /><!-- see details in build.xml --></target>

For more details, you will be able to refer to the Ant target build-client at portal-client/build.xml.

Sample portal client portletThere is a sample portal client plugin called sample-portal-client-portlet, showing how to use web services in the plugins. The following lines are the sample code, calling web services OrganizationServiceSoap and JournalArticleServiceSoap:

OrganizationServiceSoapServiceLocator locator = new OrganizationServiceSoapServiceLocator();// ignore detailsJournalArticleServiceSoap journalSoap = journalLocator.getPortlet_Journal_JournalArticleService( _getURL(remoteUser, “Portlet_Journal_JournalArticleService”));

Fortunately, the plugin is available as references at /portlets/sample-portal-client-portlet.

Page 44: Common API - Packt

Common API

[ 44 ]

Axis servletThe portal specifies the servlet called AxisServlet and defines web services as non-secure and secure URLs. The following table shows the details of these servlets:

Servlet Extension Main methods Involved classescom.liferay.util.axis.AxisServlet

org.apache.axis.transport.http.AxisServlet

destroy, init, service

org.apache.axis.utils.cache.MethodCache; ServletConfig; HttpServletRequest; HttpServletResponse

com.liferay.portal.servlet.AxisServlet

com.liferay.util.axis.AxisServlet

init, service

User, PortletServlet, PrincipalThreadLocal, UserLocalServiceUtil, PermissionChecker, PermissionThreadLocal

The servlet com.liferay.portal.servlet.AxisServlet gets specified in web.xml (/tunnel-web/docroot/WEB-INF/web.xml), as shown in the following code:

<!—- see details in the web.xml --><servlet-mapping> <servlet-name>Axis Servlet</servlet-name> <url-pattern>/axis/*</url-pattern></servlet-mapping><servlet-mapping> <servlet-name>Axis Servlet</servlet-name> <url-pattern>/secure/axis/*</url-pattern></servlet-mapping>

As shown in the previous code, there are two URL patterns, namely, /axis/* and /secure/axis/*, for unauthenticated URLs and authenticated URLs, respectively. The following is the sample code for unauthenticated URLs and authenticated URLs:

String url = “http[s]://${domain.name}/tunnel-web/axis/” + serviceName;String url = “http[s]://” + remoteUser + “:” + password + “@${domain.name}/tunnel-web/secure/axis/” + serviceName;

Page 45: Common API - Packt

Chapter 11

[ 45 ]

Web services in pluginsThe Ant targets build-wsdd and build-client are available in the plugins. For example, in order to make Knowledge Base articles available through web services, you can use the plugin knowledge-base-portlet to generate the WSDD file server-config.xml and the JAR file knowledge-base-portlet-client.jar, inside the plugin knowledge-base-portlet.

In fact, the plugin SDK defines the Ant target build-wsdd.

Similarly, the Ant target build-client gets specified in the plugin SDK.

For more details on build-wsdd and build-client, you can refer to the build-common-plugin.xml at svn://svn.liferay.com/repos/public/plugins/trunk/build-common-plugin.xml.

What’s happening?The portal uses Apache Axis to generate web services. The default Axis configuration is specified in the server-config.wsdd file at /tunnel-web/docroot/WEB-INF/server-config.wsdd. When deploying the plugin, the file server-config.wsdd will be merged with the server-config.wsdd file from the plugin (for example, /portlets/knowledge-base-portlet/docroot/WEB-INF/server-config.wsdd). Therefore, when you type http://127.0.0.1:8080/tunnel-web/axis in your browser, you will see a list of SOAP services.

To access services remotely, the host must be allowed via the portal-ext.properties file. After that, the user must have the permission to access the portal resources. The default settings to access a service remotely are specified in the portal.properties file as follows:

axis.servlet.hosts.allowed=127.0.0.1,SERVER_IPaxis.servlet.https.required=false

The previous code shows the IPs to access the Axis servlet. You can input a blank list to allow any IP to access this servlet. SERVER_IP will be replaced with the IP of the host server. By default, 127.0.0.1 is the IP for local host. This is the reason that you can access web services with the IP 127.0.0.1. Of course, you can use a domain name like www.bookpub.com, if you had set the mapping between 127.0.0.1 and www.bookpub.com in the hosts file.

Page 46: Common API - Packt

Common API

[ 46 ]

WSRPWeb Services for Remote Portlets (WSRP) is a network protocol standard designed for communication with remote portlets. In general, WSRP defines a set of interfaces and related semantics. This standardizes the interactions with components that provide user-facing mark-up, including the processing of user interactions with that mark-up. It allows the portal to consume components, such as providing a portion of the overall custom application, without writing unique code for interacting with each component. Refer to http://docs.oasis-open.org/wsrp/v2/wsrp-2.0-spec.html for more details.

An overviewThe WSRP specification defines a web service interface for interacting with presentation-oriented web services. The portal provides an implementation for both WSRP 1.0 and WSRP 2.0 producers and consumers.

The specification (that is, WSRP 2.0) uses four roles: End-User, Consumer, Producer, and Portlet to help delineate responsibilities.

Portal P1

component

Portlet A

Portlet B

Portal P2

component

Portlet C

Portlet D

Portal C1

component

Portlet C’

Portlet B’WSRP

WSRP

component

WSRP Consumer

component

WSRP Producer

As shown in the previous diagram, the portal can act as a WSRP Producer, hosting portlets that will be consumed by other portals acting as WSRP Consumers. For example, the portal P1 hosts portlets like Portlet A and Portlet B; the portal P2 hosts the portlets Portal C and Portlet D. Both of them act as WSRP Producers. The portal C1 acts as a WSRP Consumer, using Portlet C as Portlet C’ and Portlet B as Portlet B’.

In particular, the portal can act as a WSRP Producer and a WSRP Consumer at the same time, all in one portal instance, and WSRP is implemented in the portal as a plugin called wsrp-portlet. Refer to /portlets/wsrp-portlet for more information.

Page 47: Common API - Packt

Chapter 11

[ 47 ]

Models and servicesThe plugin wsrp-portlet implements WSRP in a few entities with the namespaces called WSRPConsumer, WSRPConsumerPortlet, and WSRPProducer. The following table shows these entities as interfaces, their implementation, wrappers, SOAP, and Clp (Class Load Proxy). As a developer, you could be able to refer to the entities via these interfaces, and be able to override these interfaces through wrappers.

As you can see, the previous interfaces extend the interface com.liferay.portal.model.PersistedModel. The interface PersistedModel will update the previous model instances in the database, or it will add them if it doesn’t yet exist. It also notifies the related model listeners if they are overriding.

Generally speaking, end users can override the WSRP services through wrappers and call services via utilities. The following table shows WSRP service interfaces, their wrappers, utilities, and implementations:

Interface Utility Wrapper/Clp Extension Main methods

WSRPConsumer LocalService

WSRPConsumer LocalService Util

WSRPConsumer LocalService Wrapper; WSRPConsumer LocalServiceClp

Persisted ModelLocal Service

add*, delete*, get*, fetch, register, restart, set*, update*

WSRPConsumer PortletLocal Service

WSRPConsumer PortletLocal ServiceUtil

WSRPConsumer PortletLocal ServiceWrapper; WSRPConsumer PortletLocal ServiceClp

Persisted ModelLocal Service

add*, create*, delete*, destroy*, fetch, get*, init*, update*

WSRPProducer LocalService

WSRPProducer LocalService Util

WSRPProducer LocalService Wrapper; WSRPProducer LocalServiceClp

Persisted ModelLocal Service

add*, create*, delete*, fetch*, get*, update*, set*

Page 48: Common API - Packt

Common API

[ 48 ]

Web servicesThe web services get defined in the WSDD (Web Service Deployment Descriptor) file at /portlets/wsrp-portlet/docroot/WEB-INF/server-config.wsdd. The following table shows a summary of the WSRP portlet web services specifications and class names:

Web service name Provider Style/use Binding class nameWSRPPortlet ManagementService

java:RPC document/literal

oasis.names.tc.wsrp.v1.bind.WSRP_v1_PortletManagement_Binding_SOAPImpl

WSRPRegistration Service

java:RPC document/literal

oasis.names.tc.wsrp.v1.bind.WSRP_v1_Registration_Binding_SOAPImpl

WSRP_v2_Markup _Service

java:RPC document/literal

com.liferay.wsrp.bind.V2MarkupServiceImpl

WSRP_v2_Registration_Service

java:RPC document/literal

oasis.names.tc.wsrp.v2.bind.WSRP_v2_Registration_Binding_SOAPImpl

As you can see, both WSRP 1.0 and WSRP 2.0 get supported in the WSRP web services.

WSDLThe Web Services Description Language (WSDL) is an XML-based language that is used for describing the functionality offered by a web service. A WSDL description of a web service provides a machine-readable description of how the service can be called, what parameters it expects, and what data structures it returns. The WSRP plugin wsrp-portlet provides WSDL for both WSRP 1.0 and WSRP 2.0.

In addition, the plugin wsrp-portlet defines HTTP sender, password callback, and the JMX (Java Management Extensions) manager.

Portlets configurationThe plugin wsrp-portlet defines two portlets, namely, AdminPortlet and ConsumerPortlet, one to manage WSRP Producers and one to manage WSRP Consumers, and the other to display WSRP Consumer portlets.

Page 49: Common API - Packt

Chapter 11

[ 49 ]

In liferay-portlet-app_6_1_0.dtd, the portal has provided a tag called remoteable. Thus, you can set the remoteable value to true if the portlet can be used remotely through WSRP. If set to false, the portlet will not be available remotely. The default value is false, shown as follows:

<!ELEMENT remoteable (#PCDATA)>

For example, the plugin knowledge-base-portlet has specified the following portlets:

• 1 (Knowledge Base Admin)• 2 (Knowledge Base Display)• 3 (Knowledge Base Article)• 4 (Knowledge Base Section)• 5 (Knowledge Base Search)

Let’s say that you are going to make custom developed portlets like 3 (Knowledge Base Article) and 4 (Knowledge Base Section), which are remotely accessible; you can set the remotable tag to true in liferay-portlet.xml. The following sample code illustrates this:

<portlet><portlet-name>4</portlet-name><remoteable>true</remoteable></portlet>

As shown in the preceding code, custom portlets will appear in the list of portlets available, when creating WSRP Producers. Moreover, you will be able to expose all the custom developed portlets to be used by WSRP Consumers.

PortletsThe plugin wsrp-portlet defines two portlets: AdminPortlet and ConsumerPortlet and a consumer-friendly URL mapper called ConsumerFriendlyURLMapper.

The plugin wsrp-portlet also specifies a set of portlet properties as follows:

consumer.request.extensions=failed.consumers.check.interval=0proxy.url.ips.allowed=127.0.0.1,SERVER_IPsecure.resource.urls.enabled=truesecure.resource.urls.salt=salt

Page 50: Common API - Packt

Common API

[ 50 ]

As shown in the previous code, the property consumer.request.extensions allows us to input a list of comma-delimited class names that implement com.liferay.wsrp.util.ConsumerRequestExtension. These classes are used to provide additional client and profile attributes.

The property failed.consumers.check.interval sets the interval to check for failed consumers. The value is set in one second increments. The property allows us to input a list of comma-delimited IPs, which the proxy server is allowed to redirect to. You can input a blank list to allow any IP. SERVER_IP will be replaced with the IP of the host server.

The property secure.resource.urls.enabled is set to true to restrict access on resource URLs to authenticated users, while the property secure.resource.urls.salt sets the salt value used to secure resource URLs.

As mentioned previously, the plugin wsrp-portlet provides the interface ConsumerRequestExtension—any class that provides additional client and profile attributes should implement this interface. In fact, the plugin wsrp-portlet provides the helper method of the interface ConsumerRequestExtension.

LAR, messaging, and proxyAs shown in liferay-portlet.xml, the plugin specifies the tag scheduler-entry with the tag scheduler-event-listener-class, having the value WSRPConsumerPortletCheckEventMessageListener. It also defines the LAR import and export, based on the tag portlet-data-handler-class and the value AdminPortletDataHandlerImpl. In addition, a set of handlers get defined in the plugin wsrp-portlet.

Servlets, listeners, and filtersThe plugin wsrp-portlet also defines a set of servlets, listeners, and filters in web.xml, such as ProxyServlet, WSDLServlet, WSRPServletContextListener, WSRPSessionListener, and WSRPHTTPSenderFilter.

In addition, the plugin wsrp-portlet provides the class called PortalInitThread extending the class Thread. The method run specifies the process. It waits for four seconds before initializing consumer portlets, in case both the consumer and the producer are in the same machine. This class is called in the method doPortalInit() of the class WSRPServletContextListener.

In particular, you can find more details of the plugin wsrp-portlet at /portlets/wsrp-portlet.

Page 51: Common API - Packt

Chapter 11

[ 51 ]

OSGi integrationOSGi technology (Universal Middleware, the Dynamic Module System for Java), provides a service-oriented, component-based environment for developers, and offers standardized ways to manage the software lifecycle. Benefits of using OSGi include reduced complexity, reuse, real world, easy deployment, dynamic updates, adaptivity, transparency, versioning, security, and so on. For more information, refer to http://www.osgi.org/.

Apache Felix implements the OSGi R4 Service Platform and other interesting OSGi-related technologies under the Apache license. For more information, refer to http://felix.apache.org/site/index.html. While Eclipse Equinox implements the OSGi R4 core framework specification, a set of bundles implement various optional OSGi services and other infrastructure for running OSGi-based systems. For more information, refer to http://www.eclipse.org/equinox/. Bndtools. For an Eclipse-based development environment for OSGi, refer to http://bndtools.org/.

The portal integrates OSGi framework based on Eclipse Equinox in following aspects:

• Turn libraries into OSGi bundles• Deploy a portlet inside the portal as an OSGi bundle and create plugins

management around the framework for managing bundles• Support OSGi manifest attributes for providing information about plugins

SummaryIn this chapter, you learnt about user management, password policy, authentication and authorization, LDAP and SSO, tracking and auditing, rules engine and reporting engine, scripting engine, polling, web services, WSRP producers and consumers, and the OSGi framework.

In general, this book has introduced Liferay, including the portal, CMS, DDL and WCM, collaboration, social activities and social equity, workflow, rule engine, reporting engine, auditing, polling, indexing, caching, scripting engine, web services, WSRP, and various integrations. The book has addressed Liferay kernel features in depth. Therefore, you are ready to use these features as recipes, and going further to cook your own favorite dishes—building dynamic, content-rich, collaborative and social systems, fast and easily on top of Liferay portal.

Page 52: Common API - Packt

Common API

[ 52 ]

Of course, you would be ready to take on many challenges that Liferay may throw at you. The following is a list of some challenges that you may be interested in:

• Add full payment abilities and shipping capabilities in the shopping cart portlet

• Make the Document and Media Library being able to provide video/audio live streaming services

• Improve the calendar portlet as advanced calendar, and make it as enterprise-ready

• Build enterprise-ready records management systems• Build a unified, HTML5-based user interface system for all popular mobile

device platforms• Build enterprise-ready advertisements management system and make any

ads, which are published easily and simply