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.
- 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.
- 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
// 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
// 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