Liferay 7 сообщение Автобус
В Liferay 6.2 мы настраивали пользовательскую почту в messaging-spring.xml и выполняли entery в service.properties. Чтобы добиться того же в портлете модуля Liferay 7 OSGI, кто-нибудь может подсказать мне, как я могу настроить в нем шину сообщений?
1 ответ
Я делюсь с вами рабочим примером конфигурации шины сообщений в Liferay 7+
Попробуйте этот код, который у меня работает нормально.
AuditMessageBusConfigurator.java
package com.xyz.audit.listner.configurator;
import com.liferay.portal.kernel.concurrent.CallerRunsPolicy;
import com.liferay.portal.kernel.concurrent.RejectedExecutionHandler;
import com.liferay.portal.kernel.concurrent.ThreadPoolExecutor;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
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.HashMapDictionary;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Map;
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 = AuditMessageBusConfigurator.class)
public class AuditMessageBusConfigurator {
public final Log LOGGER = LogFactoryUtil.getLog(AuditMessageBusConfigurator.class);
private final int _MAXIMUM_QUEUE_SIZE = 1000;
private volatile BundleContext _bundleContext;
@Reference
private DestinationFactory _destinationFactory;
private final Map<String, ServiceRegistration<Destination>> _serviceRegistrations = new HashMap<>();
@Activate
protected void activate(BundleContext context) {
_bundleContext = context;
startMessageBus("audit.ptob.destination");
}
@Deactivate
protected void deactivate() {
for (ServiceRegistration<Destination> serviceRegistration : _serviceRegistrations.values()) {
destroyMessageBus(serviceRegistration);
}
_serviceRegistrations.clear();
}
private void destroyMessageBus(ServiceRegistration<Destination> serviceRegistration) {
Destination destination = _bundleContext.getService(serviceRegistration.getReference());
serviceRegistration.unregister();
destination.destroy();
}
private void startMessageBus(String busName) {
Destination destination = createDestination(busName);
Dictionary<String, Object> propeties = createDictionary(destination);
createServiceRegistration(destination, propeties);
}
private void createServiceRegistration(Destination destination, Dictionary<String, Object> propeties) {
ServiceRegistration<Destination> messageServiceRegistration = _bundleContext.registerService(Destination.class,
destination, propeties);
_serviceRegistrations.put(destination.getName(), messageServiceRegistration);
}
private Dictionary<String, Object> createDictionary(Destination destination) {
Dictionary<String, Object> properties = new HashMapDictionary<>();
properties.put("destination.name", destination.getName());
return properties;
}
private Destination createDestination(String destinationName) {
DestinationConfiguration destinationConfiguration = new DestinationConfiguration(
DestinationConfiguration.DESTINATION_TYPE_PARALLEL, destinationName);
destinationConfiguration.setMaximumQueueSize(_MAXIMUM_QUEUE_SIZE);
RejectedExecutionHandler rejectedExecutionHandler = new CallerRunsPolicy() {
@Override
public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("The current thread will handle the request "
+ "because the audit router's task queue is at " + "its maximum capacity");
}
super.rejectedExecution(runnable, threadPoolExecutor);
}
};
destinationConfiguration.setRejectedExecutionHandler(rejectedExecutionHandler);
return _destinationFactory.createDestination(destinationConfiguration);
}
}
AuditListnerImpl.java
package com.xyz.audit.listner.impl;
import com.liferay.counter.kernel.service.CounterLocalService;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageListener;
import com.liferay.portal.kernel.messaging.MessageListenerException;
import com.liferay.portal.kernel.util.GetterUtil;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component(immediate = true, property = { "destination.name=audit.ptob.destination" }, service = MessageListener.class)
public class AuditListnerImpl implements MessageListener {
public final Log LOGGER = LogFactoryUtil.getLog(AuditListnerImpl.class);
@Override
public void receive(Message message) throws MessageListenerException {
doReceive(message);
}
private void doReceive(Message message) {
try {
//DO YOU BUSINESS LOGIC
} catch (SystemException e) {
LOGGER.error("SystemException : while audit entry");
}
}
}
build.gradle
dependencies {
compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel"
compileOnly group: "com.liferay.portal", name: "com.liferay.util.taglib"
compileOnly group: "javax.portlet", name: "portlet-api"
compileOnly group: "javax.servlet", name: "javax.servlet-api"
compileOnly group: "jstl", name: "jstl"
compileOnly group: "org.osgi", name: "osgi.cmpn", version: "6.0.0"
compileOnly group: "com.liferay", name: "com.liferay.petra.string"
compileOnly group: "com.liferay", name: "com.liferay.petra.lang"
compileOnly group: 'org.osgi', name: 'org.osgi.core', version: '6.0.0'
compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations", version: "1.3.0"
compileOnly group: "com.liferay", name: "com.liferay.osgi.service.tracker.collections", version: "2.0.0"
}
Я нашел решение. Избежать java.lang.IllegalStateException: No servlet context name specified
вам нужно изменить реализацию конфигурации обмена сообщениями в вашем messaging-spring.xml
файл.
замещать com.liferay.portal.kernel.messaging.config.PluginMessagingConfigurator
с com.liferay.portal.kernel.messaging.config.DefaultMessagingConfigurator
,
Это работает для меня. Мне удалось отправить сообщение из одного модуля и получить его двумя другими модулями.