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.
![Register OSGI message bus configuration class | Liferay Objects with Message bus Register OSGI message bus configuration class](https://www.ignek.com/wp-content/uploads/2024/03/Register-OSGI-message-bus-configuration-class.webp)
- Under @Activate annotation, create a destination and register the message bus.
![Create destination and register message bus | Liferay Objects with Message bus Create destination and register message bus](https://www.ignek.com/wp-content/uploads/2024/03/Create-destination-and-register-message-bus.webp)
- Under @Deactivate annotation, unregister the message bus.
![Unregister message bus under Deactivate annotation | Liferay Objects with Message bus Unregister message bus under Deactivate annotation](https://www.ignek.com/wp-content/uploads/2024/03/Unregister-message-bus-under-Deactivate-annotation.webp)
- Add these variables and references, and organize the imports.
![Optimize manufacturing with streamlined variables | Liferay Objects with Message bus Optimize manufacturing with streamlined variables](https://www.ignek.com/wp-content/uploads/2024/03/Optimize-manufacturing-with-streamlined-variables.webp)
- 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.
![Object creation and action in Liferay | Liferay Objects with Message bus Object creation and action in Liferay](https://www.ignek.com/wp-content/uploads/2024/03/Object-creation-and-action-in-Liferay-1024x188.webp)
- In basic info, add ‘Action Name’, ‘Action Label’, and ‘Description’.
![Filling basic details of action | Liferay Objects with Message bus Filling basic details of action](https://www.ignek.com/wp-content/uploads/2024/03/Filling-basic-details-of-action.webp)
- At ‘Action builder’ select trigger type, in ‘On After Add’ then select ‘Groovy Script’.
![Select trigger type in Action Builder | Liferay Objects with Message bus Select trigger type in Action Builder](https://www.ignek.com/wp-content/uploads/2024/03/Select-trigger-type-in-Action-Builder.webp)
- Add the groovy script of the sender class, i.e
![Include sender class groovy script | Liferay Objects with Message bus Include sender class groovy script](https://www.ignek.com/wp-content/uploads/2024/03/Include-sender-class-groovy-script.webp)
Note: Here ‘entryId’ is the key and ‘id’ is the Object Entry ID. Similarly, we can add more keys and other object values.
- 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:
// ObjectMessageBusListener.java
@Component(immediate = true, property = { "destination.name=add/object/message" }, service = MessageListener.class)
public class ObjectMessageBusListener extends BaseMessageListener {
@Override
protected void doReceive(Message message) throws Exception {
}
}
- Logic can be added here, which will trigger when it receives some message.
// ObjectMessageBusListener.java
package com.ignek.blog.portlet;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.BaseMessageListener;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageListener;
import org.osgi.service.component.annotations.Component;
@Component(immediate = true, property = { "destination.name=add/object/message" }, service = MessageListener.class)
public class ObjectMessageBusListener extends BaseMessageListener {
@Override
protected void doReceive(Message message) throws Exception {
_log.info("This is a destination class");
_log.info("Object entry Id" + message.getLong("entryId"));
}
private static final Log _log = LogFactoryUtil.getLog(ObjectMessageBusListener.class);
}
- Deploy the module, and add an object entry, the code from the receiver class will be called.
Configurator Class
![Class for configuration tool of object message bus | Liferay Objects with Message bus Class for configuration tool of object message bus](https://www.ignek.com/wp-content/uploads/2024/03/Class-for-configuration-tool-of-object-message-bus.webp)
// ObjectMessageBusConfigurator.java
package com.ignek.blog.portlet;
import com.liferay.portal.kernel.messaging.Destination;
import com.liferay.portal.kernel.messaging.DestinationConfiguration;
import com.liferay.portal.kernel.messaging.DestinationFactory;
import com.liferay.portal.kernel.util.HashMapDictionaryBuilder;
import java.util.Dictionary;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
@Component(immediate = true, service = ObjectMessageBusConfigurator.class)
public class ObjectMessageBusConfigurator {
@Activate
protected void activate(BundleContext bundleContext) {
_bundleContext = bundleContext;
DestinationConfiguration destinationConfiguration = DestinationConfiguration
.createSerialDestinationConfiguration("add/object/message");
Destination destination = _destinationFactory.createDestination(destinationConfiguration);
Dictionary dictionary = HashMapDictionaryBuilder
.put("destination.name", destination.getName()).build();
_serviceRegistration = bundleContext.registerService(Destination.class, destination, dictionary);
}
@Deactivate
protected void deactivate() {
if (_serviceRegistration != null) {
Destination destination = _bundleContext.getService(_serviceRegistration.getReference());
_serviceRegistration.unregister();
destination.destroy();
}
_bundleContext = null;
}
private volatile BundleContext _bundleContext;
@Reference
private DestinationFactory _destinationFactory;
private ServiceRegistration _serviceRegistration;
}
Listener Class
![Listener class of object message bus | Liferay Objects with Message bus Listener class of object message bus](https://www.ignek.com/wp-content/uploads/2024/03/Listener-class-of-object-message-bus.webp)
// ObjectMessageBusListener.java
package com.ignek.blog.portlet;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.BaseMessageListener;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageListener;
import org.osgi.service.component.annotations.Component;
@Component(immediate = true, property = { "destination.name=add/object/message" }, service = MessageListener.class)
public class ObjectMessageBusListener extends BaseMessageListener {
@Override
protected void doReceive(Message message) throws Exception {
_log.info("This is a destination class");
_log.info("Object entry Id" + message.getLong("entryId"));
}
private static final Log _log = LogFactoryUtil.getLog(ObjectMessageBusListener.class);
}
Output
![Creating data in object | Liferay Objects with Message bus Creating data in object](https://www.ignek.com/wp-content/uploads/2024/03/Creating-data-in-object.webp)
![Checking desired logs in the terminal | Liferay Objects with Message bus Checking desired logs in the terminal](https://www.ignek.com/wp-content/uploads/2024/03/Checking-desired-logs-in-the-terminal.webp)