Liferay Objects with Message bus

Introduction
Liferay actions can be used for triggering message buses to enhance the functionality of Liferay Objects.
Prerequisites:
- Liferay DXP/Portal 7.4+
- Basic knowledge of Liferay
- Basics of Liferay Objects
- Basics of Message Bus
Environment Requirements :
- Liferay Portal or DXP
- Eclipse or LDS
Liferay Objects
Liferay Objects is one of the most powerful functions provided by Liferay 7.4. With the help of Liferay Objects, applications can be built or deployed without writing code or deploying modules.
They can also create and manage a schema without using a service builder.
When creating an Object, its data fields and relationships can be defined to other object entries, and actions can be triggered under some specific conditions.
Message Bus
Message buses can be used for sending messages from some source to the destination. A destination is a logical entity.
A sender class sends some messages to the destinations, while a listener class waits for the message at the destination. When a message is sent from the sender to the destination, the listener class receives the message and performs the operations associated with it. The sender and receiver are loosely coupled.
Triggering messages from object action requires the following steps:
- Register message bus:
- Create a message bus configuration class, and register it as an OSGI service.

- Under @Activate annotation, create a destination and register the message bus.

- Under @Deactivate annotation, unregister the message bus.

- Add these variables and references, and organize the imports.

2. Create an object with the sender:
- Create an object and add an object field, below blog can help in creating objects.
- Once the object is created, go to its action tab and add an action.

- In basic info, add ‘Action Name’, ‘Action Label’, and ‘Description’.

- At ‘Action builder’ select trigger type, in ‘On After Add’ then select ‘Groovy Script’.

- Add the groovy script of the sender class, i.e

Note: Here ‘entryId’ is the key and ‘id’ is the Object Entry ID. Similarly, we can add more keys and other object values.
3. Create an object with the sender:
- Create a Listener class extending ‘BaseMessageListener’ and add the unimplemented method. Add destination location in its component property. It should resemble below :
1// ObjectMessageBusListener.java
2@Component(immediate = true, property = { "destination.name=add/object/message" }, service = MessageListener.class)
3public class ObjectMessageBusListener extends BaseMessageListener {
4 @Override
5 protected void doReceive(Message message) throws Exception {
6
7 }
8}- Logic can be added here, which will trigger when it receives some message.
1// ObjectMessageBusListener.java
2package com.ignek.blog.portlet;
3
4import com.liferay.portal.kernel.log.Log;
5import com.liferay.portal.kernel.log.LogFactoryUtil;
6import com.liferay.portal.kernel.messaging.BaseMessageListener;
7import com.liferay.portal.kernel.messaging.Message;
8import com.liferay.portal.kernel.messaging.MessageListener;
9
10import org.osgi.service.component.annotations.Component;
11
12@Component(immediate = true, property = { "destination.name=add/object/message" }, service = MessageListener.class)
13public class ObjectMessageBusListener extends BaseMessageListener {
14 @Override
15 protected void doReceive(Message message) throws Exception {
16 _log.info("This is a destination class");
17 _log.info("Object entry Id" + message.getLong("entryId"));
18 }
19
20 private static final Log _log = LogFactoryUtil.getLog(ObjectMessageBusListener.class);
21
22}- Deploy the module, and add an object entry, the code from the receiver class will be called.
Configurator Class
1// ObjectMessageBusConfigurator.java
2
3package com.ignek.blog.portlet;
4
5import com.liferay.portal.kernel.messaging.Destination;
6import com.liferay.portal.kernel.messaging.DestinationConfiguration;
7import com.liferay.portal.kernel.messaging.DestinationFactory;
8import com.liferay.portal.kernel.util.HashMapDictionaryBuilder;
9import java.util.Dictionary;
10import org.osgi.framework.BundleContext;
11import org.osgi.framework.ServiceRegistration;
12import org.osgi.service.component.annotations.Activate;
13import org.osgi.service.component.annotations.Component;
14import org.osgi.service.component.annotations.Deactivate;
15import org.osgi.service.component.annotations.Reference;
16
17@Component(immediate = true, service = ObjectMessageBusConfigurator.class)
18public class ObjectMessageBusConfigurator {
19 @Activate
20 protected void activate(BundleContext bundleContext) {
21 _bundleContext = bundleContext;
22 DestinationConfiguration destinationConfiguration = DestinationConfiguration
23 .createSerialDestinationConfiguration("add/object/message");
24 Destination destination = _destinationFactory.createDestination(destinationConfiguration);
25 Dictionary<String, Object> dictionary = HashMapDictionaryBuilder
26 .<String, Object>put("destination.name", destination.getName()).build();
27 _serviceRegistration = bundleContext.registerService(Destination.class, destination, dictionary);
28 }
29
30 @Deactivate
31 protected void deactivate() {
32 if (_serviceRegistration != null) {
33 Destination destination = _bundleContext.getService(_serviceRegistration.getReference());
34 _serviceRegistration.unregister();
35 destination.destroy();
36 }
37 _bundleContext = null;
38 }
39
40 private volatile BundleContext _bundleContext;
41 @Reference
42 private DestinationFactory _destinationFactory;
43 private ServiceRegistration<Destination> _serviceRegistration;
44}Listener Class

1// ObjectMessageBusListener.java
2
3package com.ignek.blog.portlet;
4
5import com.liferay.portal.kernel.log.Log;
6import com.liferay.portal.kernel.log.LogFactoryUtil;
7import com.liferay.portal.kernel.messaging.BaseMessageListener;
8import com.liferay.portal.kernel.messaging.Message;
9import com.liferay.portal.kernel.messaging.MessageListener;
10
11import org.osgi.service.component.annotations.Component;
12
13@Component(immediate = true, property = { "destination.name=add/object/message" }, service = MessageListener.class)
14public class ObjectMessageBusListener extends BaseMessageListener {
15 @Override
16 protected void doReceive(Message message) throws Exception {
17 _log.info("This is a destination class");
18 _log.info("Object entry Id" + message.getLong("entryId"));
19 }
20
21 private static final Log _log = LogFactoryUtil.getLog(ObjectMessageBusListener.class);
22
23}Output :

