/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.workflow.kaleo.runtime.internal.messaging;
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.messaging.MessageBus;
import com.liferay.portal.kernel.messaging.MessageListener;
import com.liferay.portal.kernel.messaging.proxy.ProxyMessageListener;
import com.liferay.portal.kernel.scheduler.messaging.SchedulerEventMessageListenerWrapper;
import com.liferay.portal.kernel.util.HashMapDictionary;
import com.liferay.portal.kernel.workflow.WorkflowDefinitionManager;
import com.liferay.portal.kernel.workflow.WorkflowEngineManager;
import com.liferay.portal.kernel.workflow.WorkflowInstanceManager;
import com.liferay.portal.kernel.workflow.WorkflowLogManager;
import com.liferay.portal.kernel.workflow.WorkflowTaskManager;
import com.liferay.portal.kernel.workflow.comparator.WorkflowComparatorFactory;
import com.liferay.portal.kernel.workflow.messaging.DefaultWorkflowDestinationEventListener;
import com.liferay.portal.workflow.kaleo.runtime.constants.KaleoRuntimeDestinationNames;
import com.liferay.portal.workflow.kaleo.runtime.internal.timer.messaging.TimerMessageListener;
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;
/**
* @author Michael C. Han
*/
@Component(immediate = true, service = KaleoWorkflowMessagingConfigurator.class)
public class KaleoWorkflowMessagingConfigurator {
@Activate
protected void activate(BundleContext bundleContext) {
_bundleContext = bundleContext;
registerKaleoGraphWalkerDestination();
registerWorkflowDefinitionLinkDestination();
registerWorkflowMessageListeners();
registerWorkflowTimerDestination();
registerSchedulerEventMessageListener();
}
@Deactivate
protected void deactivate() {
unregisterKaleoWorkflowDestinations();
unregisterWorkflowEngineDestinationListener();
unregisterWorkflowMessageListeners();
unregisterSchedulerEventMessageListener();
_bundleContext = null;
}
protected void registerDestination(
DestinationConfiguration kaleoGraphWalkerDestinationConfiguration) {
Destination destination = _destinationFactory.createDestination(
kaleoGraphWalkerDestinationConfiguration);
Dictionary<String, Object> properties = new HashMapDictionary<>();
properties.put("destination.name", destination.getName());
ServiceRegistration<Destination> serviceRegistration =
_bundleContext.registerService(
Destination.class, destination, properties);
_serviceRegistrations.put(destination.getName(), serviceRegistration);
}
protected void registerKaleoGraphWalkerDestination() {
DestinationConfiguration destinationConfiguration =
new DestinationConfiguration(
DestinationConfiguration.DESTINATION_TYPE_PARALLEL,
KaleoRuntimeDestinationNames.KALEO_GRAPH_WALKER);
destinationConfiguration.setMaximumQueueSize(_MAXIMUM_QUEUE_SIZE);
RejectedExecutionHandler rejectedExecutionHandler =
new CallerRunsPolicy() {
@Override
public void rejectedExecution(
Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {
if (_log.isWarnEnabled()) {
_log.warn(
"The current thread will handle the request " +
"because the graph walker's task queue is at " +
"its maximum capacity");
}
super.rejectedExecution(runnable, threadPoolExecutor);
}
};
destinationConfiguration.setRejectedExecutionHandler(
rejectedExecutionHandler);
registerDestination(destinationConfiguration);
}
protected MessageListener registerProxyMessageListener(
Object manager, String destinationName) {
ProxyMessageListener proxyMessageListener = new ProxyMessageListener();
proxyMessageListener.setManager(manager);
proxyMessageListener.setMessageBus(_messageBus);
_messageBus.registerMessageListener(
destinationName, proxyMessageListener);
_proxyMessageListeners.put(destinationName, proxyMessageListener);
return proxyMessageListener;
}
protected void registerSchedulerEventMessageListener() {
SchedulerEventMessageListenerWrapper
schedulerEventMessageListenerWrapper =
new SchedulerEventMessageListenerWrapper();
schedulerEventMessageListenerWrapper.setMessageListener(
_timerMessageListener);
Dictionary<String, Object> properties = new HashMapDictionary<>();
properties.put(
"destination.name", KaleoRuntimeDestinationNames.WORKFLOW_TIMER);
_schedulerEventMessageListenerServiceRegistration =
_bundleContext.registerService(
MessageListener.class, schedulerEventMessageListenerWrapper,
properties);
}
protected void registerWorkflowDefinitionLinkDestination() {
DestinationConfiguration destinationConfiguration =
new DestinationConfiguration(
DestinationConfiguration.DESTINATION_TYPE_SYNCHRONOUS,
KaleoRuntimeDestinationNames.WORKFLOW_DEFINITION_LINK);
registerDestination(destinationConfiguration);
}
protected void registerWorkflowMessageListeners() {
_defaultWorkflowDestinationEventListener =
new DefaultWorkflowDestinationEventListener();
_defaultWorkflowDestinationEventListener.setWorkflowEngineName(
"Liferay Kaleo Workflow Engine");
MessageListener workflowComparatorMessageListener =
registerProxyMessageListener(
_workflowComparatorFactory,
com.liferay.portal.kernel.messaging.DestinationNames.
WORKFLOW_COMPARATOR);
_defaultWorkflowDestinationEventListener.
setWorkflowComparatorFactoryListener(
workflowComparatorMessageListener);
MessageListener workflowDefinitionManagerProxyMessageListener =
registerProxyMessageListener(
_workflowDefinitionManager,
com.liferay.portal.kernel.messaging.DestinationNames.
WORKFLOW_DEFINITION);
_defaultWorkflowDestinationEventListener.
setWorkflowDefinitionManagerListener(
workflowDefinitionManagerProxyMessageListener);
MessageListener workflowEngineManagerProxyMessageListener =
registerProxyMessageListener(
_workflowEngineManager,
com.liferay.portal.kernel.messaging.DestinationNames.
WORKFLOW_ENGINE);
_defaultWorkflowDestinationEventListener.
setWorkflowEngineManagerListener(
workflowEngineManagerProxyMessageListener);
MessageListener workflowInstanceManagerProxyMessageListener =
registerProxyMessageListener(
_workflowInstanceManager,
com.liferay.portal.kernel.messaging.DestinationNames.
WORKFLOW_INSTANCE);
_defaultWorkflowDestinationEventListener.
setWorkflowInstanceManagerListener(
workflowInstanceManagerProxyMessageListener);
MessageListener workflowLogManagerProxyMessageListener =
registerProxyMessageListener(
_workflowLogManagerk,
com.liferay.portal.kernel.messaging.DestinationNames.
WORKFLOW_LOG);
_defaultWorkflowDestinationEventListener.setWorkflowLogManagerListener(
workflowLogManagerProxyMessageListener);
MessageListener workflowTaskManagerProxyMessageListener =
registerProxyMessageListener(
_workflowTaskManager,
com.liferay.portal.kernel.messaging.DestinationNames.
WORKFLOW_TASK);
_defaultWorkflowDestinationEventListener.setWorkflowTaskManagerListener(
workflowTaskManagerProxyMessageListener);
_workflowEngineDestination.addDestinationEventListener(
_defaultWorkflowDestinationEventListener);
}
protected void registerWorkflowTimerDestination() {
DestinationConfiguration destinationConfiguration =
new DestinationConfiguration(
DestinationConfiguration.DESTINATION_TYPE_PARALLEL,
KaleoRuntimeDestinationNames.WORKFLOW_TIMER);
destinationConfiguration.setMaximumQueueSize(_MAXIMUM_QUEUE_SIZE);
RejectedExecutionHandler rejectedExecutionHandler =
new CallerRunsPolicy() {
@Override
public void rejectedExecution(
Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {
if (_log.isWarnEnabled()) {
_log.warn(
"The current thread will handle the request " +
"because the workflow timer task queue is at " +
"its maximum capacity");
}
super.rejectedExecution(runnable, threadPoolExecutor);
}
};
destinationConfiguration.setRejectedExecutionHandler(
rejectedExecutionHandler);
registerDestination(destinationConfiguration);
}
protected void unregisterKaleoWorkflowDestinations() {
for (ServiceRegistration<Destination> serviceRegistration :
_serviceRegistrations.values()) {
Destination destination = _bundleContext.getService(
serviceRegistration.getReference());
serviceRegistration.unregister();
destination.destroy();
}
_serviceRegistrations.clear();
}
protected void unregisterSchedulerEventMessageListener() {
if (_schedulerEventMessageListenerServiceRegistration == null) {
return;
}
_schedulerEventMessageListenerServiceRegistration.unregister();
_schedulerEventMessageListenerServiceRegistration = null;
}
protected void unregisterWorkflowEngineDestinationListener() {
_workflowEngineDestination.removeDestinationEventListener(
_defaultWorkflowDestinationEventListener);
}
protected void unregisterWorkflowMessageListeners() {
for (Map.Entry<String, MessageListener> entry :
_proxyMessageListeners.entrySet()) {
_messageBus.unregisterMessageListener(
entry.getKey(), entry.getValue());
}
_proxyMessageListeners.clear();
}
private static final int _MAXIMUM_QUEUE_SIZE = 200;
private static final Log _log = LogFactoryUtil.getLog(
KaleoWorkflowMessagingConfigurator.class);
private BundleContext _bundleContext;
private DefaultWorkflowDestinationEventListener
_defaultWorkflowDestinationEventListener;
@Reference
private DestinationFactory _destinationFactory;
@Reference
private MessageBus _messageBus;
private final Map<String, MessageListener> _proxyMessageListeners =
new HashMap<>();
private ServiceRegistration<MessageListener>
_schedulerEventMessageListenerServiceRegistration;
private final Map<String, ServiceRegistration<Destination>>
_serviceRegistrations = new HashMap<>();
@Reference
private TimerMessageListener _timerMessageListener;
@Reference(target = "(proxy.bean=false)")
private WorkflowComparatorFactory _workflowComparatorFactory;
@Reference(target = "(proxy.bean=false)")
private WorkflowDefinitionManager _workflowDefinitionManager;
@Reference(
target = "(destination.name=" + com.liferay.portal.kernel.messaging.DestinationNames.WORKFLOW_ENGINE + ")"
)
private Destination _workflowEngineDestination;
@Reference(target = "(proxy.bean=false)")
private WorkflowEngineManager _workflowEngineManager;
@Reference(target = "(proxy.bean=false)")
private WorkflowInstanceManager _workflowInstanceManager;
@Reference(target = "(proxy.bean=false)")
private WorkflowLogManager _workflowLogManagerk;
@Reference(target = "(proxy.bean=false)")
private WorkflowTaskManager _workflowTaskManager;
}