55

Liferay (DXP) 7 Tech Meetup for Developers

Embed Size (px)

Citation preview

Page 1: Liferay (DXP) 7 Tech Meetup for Developers
Page 2: Liferay (DXP) 7 Tech Meetup for Developers

OSGi Overview

Portlets as Modules

Services as Modules

Extending Liferay DXP

Page 3: Liferay (DXP) 7 Tech Meetup for Developers

What

Why

How

Page 4: Liferay (DXP) 7 Tech Meetup for Developers

Why OSGi

Page 5: Liferay (DXP) 7 Tech Meetup for Developers

Benefits of OSGi

• Reduced complexity• Reuse• Easy deployment• Dyanmic updates

Page 6: Liferay (DXP) 7 Tech Meetup for Developers

What is OSGi

Page 7: Liferay (DXP) 7 Tech Meetup for Developers

What is OSGi

OSGi (Open Service Gateway Initiative) is a Java framework for developing and deploying modular software programs and libraries. Each bundle is a tightly coupled, dynamically loadable collection of classes, jars, and configuration files that explicitly declare their external dependencies (if any).

Niket Kapadia
need to simplify.
Page 8: Liferay (DXP) 7 Tech Meetup for Developers

How OSGi Works

Page 9: Liferay (DXP) 7 Tech Meetup for Developers

Application / Bundles

Operating SystemHardware

JVMModules

Life cycleService Registry

Services

Secu

rity

How OSGi Works

Page 10: Liferay (DXP) 7 Tech Meetup for Developers

How OSGi Works• Bundle• Bundle fragments• Bundle context

Page 11: Liferay (DXP) 7 Tech Meetup for Developers

Sample Config. of bundleManifest-Version: 1.0 Bundle-Name: SimpleTestBundle Bundle-Activator: SimpleTestActivator Bundle-SymbolicName: SimpleTestBundle Bundle-Version: 1.0.0 Import-Package: org.azilen.framework; version=”1.3.1”

Page 12: Liferay (DXP) 7 Tech Meetup for Developers

How OSGi Works• Bundles - static entities• Services - dynamics in OSGi

– Can appear, disappear at runtime according to a condition

• Service – Object, registered by a bundle

• BundleContext.registerService(iface, implementation, properties);

Page 13: Liferay (DXP) 7 Tech Meetup for Developers

OSGi in Liferay

Page 14: Liferay (DXP) 7 Tech Meetup for Developers

• Blade– JAVA Package manager– jpm install -f

https://releases.liferay.com/tools/blade-cli/latest/blade.jar

• Liferay workspace with Blade– blade init [WORKSPACE_NAME]

OSGi in Liferay

Page 15: Liferay (DXP) 7 Tech Meetup for Developers

OSGi Overview

Portlets as Modules

Services as Modules

Extending Liferay DXP

Page 16: Liferay (DXP) 7 Tech Meetup for Developers

Portlets as Modules

Page 17: Liferay (DXP) 7 Tech Meetup for Developers

Modules as Portlets

MVC Portlet

Customize Portlet Configuration

Portlet Provider Template

Page 18: Liferay (DXP) 7 Tech Meetup for Developers

MVC Portlet

• Create portlet structure using blade– blade create -t mvc-portlet -p com.azilen.app.mvcportlet -c SampleMvcPortlet sample-mvc-portlet-project

Page 19: Liferay (DXP) 7 Tech Meetup for Developers

MVC Portlet

MVC Action Command@Component( immediate = true, property = { "javax.portlet.name=com_azilen_liferay_portlet_SampleMVCPortlet", "mvc.command.name=actionCommand1", "mvc.command.name=actionCommand2" }, service = MVCActionCommand.class ) public class DemoMVCActionCommand extends BaseMVCActionCommand { @Override protected void doProcessAction(ActionRequest req,

ActionResponse res) throws Exception { } }

Page 20: Liferay (DXP) 7 Tech Meetup for Developers

MVC Portlet

@Component(

immediate = true,

property = {

"javax.portlet.name=com_azilen_liferay_portlet_SampleMVCPortlet",

"mvc.command.name=renderCommand1",

"mvc.command.name=renderCommand2"

},

service = MVCRenderCommand.class

)

public class DemoRenderCommand implements MVCRenderCommand {

@Override

public String render(RenderRequest req, RenderResponse res)

throws PortletException {

}

}

MVC Render Command

Page 21: Liferay (DXP) 7 Tech Meetup for Developers

MVC Portlet

MVC Resource Command@Component( immediate = true, property = { "javax.portlet.name=com_azilen_liferay_portlet_SampleMVCPortlet", "mvc.command.name=ajax1", }, service = MVCResourceCommand.class ) public class DemoMVCResourceCommand extends BaseMVCResourceCommand { @Override protected void doServeResource(ResourceRequest res, ResourceResponse

res) throws Exception { } }

Page 22: Liferay (DXP) 7 Tech Meetup for Developers

Customize Portlet Configuration

Create an interface to represent your config.

@Meta.OCD(id = "com.azilen.liferay.config.ChartConfig") public interface ChartConfig { public static final String FIELD_CHART_TITLE = "chartTitle";

@Meta.AD(required = false) public String getChartTitle(); }

Page 23: Liferay (DXP) 7 Tech Meetup for Developers

Customize Portlet Configuration

Implement your configuration action class and add a reference to your configuration

@Component(

configurationPid = "com.azilen.liferay.config.ChartConfig",

configurationPolicy = ConfigurationPolicy.OPTIONAL,

immediate = true,

property = {

"javax.portlet.name=com_azilen_liferay_portlet_DemoConfigurationScreenPortlet"

},

service = ConfigurationAction.class

)

public class ChartConfigAction extends DefaultConfigurationAction {

}

Page 24: Liferay (DXP) 7 Tech Meetup for Developers

Customize Portlet Configuration

• Implement the user interface for configuring your application

• -metatype: * in project bnd.bnd file– generate an XML configuration file

Page 25: Liferay (DXP) 7 Tech Meetup for Developers

Portlet Provider Template

• Provide mechanism to customize existing entity behavior.– Portlet should be added in hidden category.

• Create a Java class – Extend BasePortletProvider class – Implement the appropriate portlet provider

interface– e.g. AddPortletProvider,ViewPortletProvider, BrowsePortletProvider.

Page 26: Liferay (DXP) 7 Tech Meetup for Developers

Portlet Provider Template• Naming conventions

– Make sure that class name has suffix PortletProvider

• To override the default portlet with a custom portlet– Assign your portlet a higher service ranking. – Add in @Component declaration

• property= {"service.ranking:Integer=Integer.MAX_VALUE"}

Page 27: Liferay (DXP) 7 Tech Meetup for Developers

Portlet Provider Template

Specify the methods you’d like to implement @Component( property = { "mod-el.class.name=com.liferay.document.library.kernel.model.DLFileEntry", "service.ranking:Integer=" + Integer.MAX_VALUE }, service = AddPortletProvider.class ) public class ProviderTemplateAddPortletProvider extends BasePortletProvider

implements AddPortletProvider { }

Page 28: Liferay (DXP) 7 Tech Meetup for Developers

OSGi Overview

Portlets as Modules

Services as Modules

Extending Liferay DXP

Page 29: Liferay (DXP) 7 Tech Meetup for Developers

Services as modules

Page 30: Liferay (DXP) 7 Tech Meetup for Developers

Using Service Builder

Creating Service Wrappers

OSGi Services

Page 31: Liferay (DXP) 7 Tech Meetup for Developers

Using Service Builder

• To create service builder modules :– blade create -t service-builder [-p packageName] projectName

e.g. blade create -t service-builder -p com.azilen.service.book book

– Above command will create two modules : book-api and book-service.

• To run service builder:– blade gw buildService

Page 32: Liferay (DXP) 7 Tech Meetup for Developers

Using Service Builder

Page 33: Liferay (DXP) 7 Tech Meetup for Developers

• Things Unchanged:– service.xml– Custom SQL– Dynamic Query– Finder methods– Model Hints– Adding new methods into EntityServiceImpl, EntityLocalServiceImpl,

EntityImpl

Page 34: Liferay (DXP) 7 Tech Meetup for Developers

Using Service Builder

• Using service objects in portlet– @Reference– OSGi Injection

public class BookPortlet extends MVCPortlet { private BookLocalService bookLocalService; @Reference public void setBookLocalService(BookLocalService bookLocalService) { this.bookLocalService = bookLocalService; } … }

Page 35: Liferay (DXP) 7 Tech Meetup for Developers

Creating Service Wrappers

• Override Liferay’s OOTB services• Service wrapper hooks in LR 6.2.• To create service wrapper module :

– blade create -t service-wrapper [-p packageName] [-c className] [-s serviceWrapperToExtend] projectName

– e.g. blade create -t service-wrapper -p com.azilen.serviceoverride -c CustomUserLocalService -s com.liferay.portal.kernel.service.UserLocalServiceWrapper service-override

Page 36: Liferay (DXP) 7 Tech Meetup for Developers

Creating Service Wrappers@Component( immediate = true, property = { }, service = ServiceWrapper.class ) public class CustomUserLocalService extends UserLocalServiceWrapper { private static final Log _log =

LogFactoryUtil.getLog(CustomUserLocalService.class); public CustomUserLocalService() { super(null); } }

Page 37: Liferay (DXP) 7 Tech Meetup for Developers

Creating Service Wrappers

• Override methods as required.@Override public int authenticateByEmailAddress(long companyId, String emailAddress,

String password, Map<String, String[]> headerMap, Map<String, String[]> parameterMap, Map<String, Object> resultsMap)

throws PortalException { // Custom logic _log.info("Custom Implementation of authenticateByEmailAddress()"); // Calling Liferay's default implementation of service return super.authenticateByEmailAddress(companyId, emailAddress,

password, headerMap, parameterMap, resultsMap); }

Page 38: Liferay (DXP) 7 Tech Meetup for Developers

OSGi services

• OSGi Services can be registered with Activatorpublic class CalcServiceActivator implements BundleActivator { private ServiceRegistration<CalcService> reg; @Override public void start(BundleContext bundleContext) throws Exception {

reg = bundleContext.registerService(CalcService.class, new CalcServiceImpl(), null);

} @Override public void stop(BundleContext bundleContext) throws Exception { reg.unregister(); } }

Page 39: Liferay (DXP) 7 Tech Meetup for Developers

OSGi services

• Injecting OSGi Services in portlets

• Null check before using service object

public class CalcPortlet extends MVCPortlet {

private CalcService _calcService;

@Reference

public void setCalcService(CalcService calcService) {

this._calcService = calcService;

} …

}

Page 40: Liferay (DXP) 7 Tech Meetup for Developers

OSGi Overview

Portlets as Modules

Services as Modules

Extending Liferay DXP

Page 41: Liferay (DXP) 7 Tech Meetup for Developers

Extending Liferay DXP

Page 42: Liferay (DXP) 7 Tech Meetup for Developers

Fragments

• Extension of host module• Uses same classloader as host module• Extending out of box modules based on

requirements• Earlier versions used Hook plugins• Create a Liferay fragment

– blade create -t fragment [-h hostBundleName] [-H hostBundleVersion] projectName

Page 43: Liferay (DXP) 7 Tech Meetup for Developers

Customize Existing JSP

Override Language properties

Add Servlet Filter

Add Custom event

Page 44: Liferay (DXP) 7 Tech Meetup for Developers

Customize Existing JSP• Override Liferay Login module

– blade create -t fragment -h com.liferay.login.web -H 1.0.7 login-fragment-module

• Find host module symbolic name and version – Connect to gogo shell using

• telnet localhost 11311– 219 ACTIVE com.liferay.login.web_1.0.7

Page 45: Liferay (DXP) 7 Tech Meetup for Developers

Customizing existing JSP

• copy jsp from Liferay-src/modules/apps/foundation/login/login-web/src/main/resources/META-INF/resources/login.jsp

and paste it in login-fragment-

src/main/resources/META-INF/resources/.

Page 46: Liferay (DXP) 7 Tech Meetup for Developers

Override Language Properties

• Want to change Login portlet authentication failed message– authentication-failed key

• blade create -t mvc-portlet -p com.azilen.fragment.language -c CustomLanguageComponent language-fragment-module

Page 47: Liferay (DXP) 7 Tech Meetup for Developers

Override Language Properties @Component( property = { "language.id=en_US" }, service = ResourceBundle.class ) public class CustomLanguageComponent extends ResourceBundle { ResourceBundle bundle = ResourceBundle.getBundle("content.Language", UTF8Control.INSTANCE); @Override protected Object handleGetObject(String key) { return bundle.getObject(key); } @Override public Enumeration<String> getKeys() { return bundle.getKeys(); } }

Page 48: Liferay (DXP) 7 Tech Meetup for Developers

Override Language Properties

• Create Language_en.properties under /language-fragment-module/src/main/resources/content

• Add authentication-failed language key with custom message.– authentication-failed=Authentication failed. Make sure you entered correct username and password.

Page 49: Liferay (DXP) 7 Tech Meetup for Developers

Add Servlet Filter

• Used for intercepting http request• Extend BaseFilter class• e.g. Intercept every request and print log

Page 50: Liferay (DXP) 7 Tech Meetup for Developers

Add Servlet Filter

@Component(

immediate = true,

property = {

"dispatcher=REQUEST", "dispatcher=FORWARD",

"servlet-context-name=",

"servlet-filter-name=Custom Filter",

"url-pattern=/*"

},

service = Filter.class

)

public class CustomFilter extends BaseFilter {

private static final Log _log = LogFactoryUtil.getLog(CustomFilter.class);

@Override

protected void processFilter(HttpServletRequest request,

HttpServletResponse response, FilterChain filterChain)

throws Exception {

_log.info("Intercepted request : " + request);

filterChain.doFilter(request, response);

}

}

Page 51: Liferay (DXP) 7 Tech Meetup for Developers

Add Custom Event

• com.liferay.portal.kernel.events.LifecycleAction is one of the extension points that can be leveraged by service template

• Create a new module using “service” template– e.g., blade create –t service –p com.azilen.training.lifecycle.loginpostaction –c CustomLoginPostAction –s com.liferay.portal.kernel.events.LifecycleAction login-post-action

Page 52: Liferay (DXP) 7 Tech Meetup for Developers

Add Custom Event

@Component( property = { "key=login.events.post" }, service = LifecycleAction.class ) public class CustomLoginPostAction implements LifecycleAction { private static final Log _log =

LogFactoryUtil.getLog(CustomLoginPostAction.class); @Override public void processLifecycleEvent(LifecycleEvent lifecycleEvent)

throws ActionException { HttpServletRequest request = lifecycleEvent.getRequest(); User user = null; try { user = PortalUtil.getUser(request); } catch (PortalException e) { _log.error(e); } … } }

Page 53: Liferay (DXP) 7 Tech Meetup for Developers

Add Custom Event

• Apart from this lifecycle event, there are many other such portal lifecycle events supported like:login.events.post, logout.events.post, logout.events.pre, global.shutdown.events, global.startup.events, application.shutdown.events, application.startup.events

Page 54: Liferay (DXP) 7 Tech Meetup for Developers

OSGi Overview

Portlets as Modules

Services as Modules

Extending Liferay DXP

Page 55: Liferay (DXP) 7 Tech Meetup for Developers

Thank You

Q&A

@AzilenTech #AzilenTechMeetup

www.azilen.com/kb/liferay-dxp/