/**
* 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.scheduler.internal;
import com.liferay.osgi.util.ServiceTrackerFactory;
import com.liferay.portal.configuration.metatype.bnd.util.ConfigurableUtil;
import com.liferay.portal.kernel.audit.AuditMessage;
import com.liferay.portal.kernel.audit.AuditRouter;
import com.liferay.portal.kernel.cal.DayAndPosition;
import com.liferay.portal.kernel.cal.Duration;
import com.liferay.portal.kernel.cal.Recurrence;
import com.liferay.portal.kernel.cal.RecurrenceSerializer;
import com.liferay.portal.kernel.json.JSONFactory;
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.DestinationNames;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageListener;
import com.liferay.portal.kernel.model.CompanyConstants;
import com.liferay.portal.kernel.scheduler.JobState;
import com.liferay.portal.kernel.scheduler.SchedulerEngine;
import com.liferay.portal.kernel.scheduler.SchedulerEngineHelper;
import com.liferay.portal.kernel.scheduler.SchedulerEntry;
import com.liferay.portal.kernel.scheduler.SchedulerException;
import com.liferay.portal.kernel.scheduler.StorageType;
import com.liferay.portal.kernel.scheduler.StorageTypeAware;
import com.liferay.portal.kernel.scheduler.Trigger;
import com.liferay.portal.kernel.scheduler.TriggerState;
import com.liferay.portal.kernel.scheduler.messaging.SchedulerEventMessageListener;
import com.liferay.portal.kernel.scheduler.messaging.SchedulerEventMessageListenerWrapper;
import com.liferay.portal.kernel.scheduler.messaging.SchedulerResponse;
import com.liferay.portal.kernel.util.CalendarFactoryUtil;
import com.liferay.portal.kernel.util.HashMapDictionary;
import com.liferay.portal.kernel.util.InetAddressUtil;
import com.liferay.portal.kernel.util.ObjectValuePair;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.scheduler.SchedulerClusterInvokingThreadLocal;
import com.liferay.portal.scheduler.configuration.SchedulerEngineHelperConfiguration;
import com.liferay.portal.scheduler.internal.messaging.config.SchedulerProxyMessagingConfigurator;
import com.liferay.portal.scheduler.internal.messaging.config.ScriptingMessageListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.portlet.PortletRequest;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
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.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* @author Michael C. Han
*/
@Component(
configurationPid = "com.liferay.portal.scheduler.configuration.SchedulerEngineHelperConfiguration",
enabled = false, immediate = true, service = SchedulerEngineHelper.class
)
public class SchedulerEngineHelperImpl implements SchedulerEngineHelper {
@Override
public void addScriptingJob(
Trigger trigger, StorageType storageType, String description,
String language, String script, int exceptionsMaxSize)
throws SchedulerException {
Message message = new Message();
message.put(SchedulerEngine.LANGUAGE, language);
message.put(SchedulerEngine.SCRIPT, script);
schedule(
trigger, storageType, description,
DestinationNames.SCHEDULER_SCRIPTING, message, exceptionsMaxSize);
}
@Override
public void auditSchedulerJobs(Message message, TriggerState triggerState)
throws SchedulerException {
if (!_schedulerEngineHelperConfiguration.auditSchedulerJobEnabled() ||
(_auditRouter == null)) {
return;
}
try {
AuditMessage auditMessage = new AuditMessage(
SchedulerEngine.SCHEDULER, CompanyConstants.SYSTEM, 0,
StringPool.BLANK, SchedulerEngine.class.getName(), "0",
triggerState.toString(), new Date(),
_jsonFactory.createJSONObject(_jsonFactory.serialize(message)));
auditMessage.setServerName(InetAddressUtil.getLocalHostName());
auditMessage.setServerPort(_portal.getPortalLocalPort(false));
_auditRouter.route(auditMessage);
}
catch (Exception e) {
throw new SchedulerException(e);
}
}
@Override
public void delete(SchedulerEntry schedulerEntry, StorageType storageType)
throws SchedulerException {
Trigger trigger = schedulerEntry.getTrigger();
delete(trigger.getJobName(), trigger.getGroupName(), storageType);
}
@Override
public void delete(String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.delete(groupName, storageType);
}
@Override
public void delete(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.delete(jobName, groupName, storageType);
}
@Override
public String getCronText(Calendar calendar, boolean timeZoneSensitive) {
return getCronText(
null, calendar, timeZoneSensitive, Recurrence.NO_RECURRENCE);
}
@Override
public String getCronText(
PortletRequest portletRequest, Calendar calendar,
boolean timeZoneSensitive, int recurrenceType) {
Calendar recurrenceCalendar = null;
if (timeZoneSensitive) {
recurrenceCalendar = CalendarFactoryUtil.getCalendar();
recurrenceCalendar.setTime(calendar.getTime());
}
else {
recurrenceCalendar = (Calendar)calendar.clone();
}
Recurrence recurrence = new Recurrence(
recurrenceCalendar, new Duration(1, 0, 0, 0), recurrenceType);
recurrence.setWeekStart(Calendar.SUNDAY);
if (recurrenceType == Recurrence.DAILY) {
int dailyType = ParamUtil.getInteger(portletRequest, "dailyType");
if (dailyType == 0) {
int dailyInterval = ParamUtil.getInteger(
portletRequest, "dailyInterval", 1);
recurrence.setInterval(dailyInterval);
}
else {
DayAndPosition[] dayPos = {
new DayAndPosition(Calendar.MONDAY, 0),
new DayAndPosition(Calendar.TUESDAY, 0),
new DayAndPosition(Calendar.WEDNESDAY, 0),
new DayAndPosition(Calendar.THURSDAY, 0),
new DayAndPosition(Calendar.FRIDAY, 0)
};
recurrence.setByDay(dayPos);
}
}
else if (recurrenceType == Recurrence.WEEKLY) {
int weeklyInterval = ParamUtil.getInteger(
portletRequest, "weeklyInterval");
recurrence.setInterval(weeklyInterval);
List<DayAndPosition> dayPos = new ArrayList<>();
addWeeklyDayPos(portletRequest, dayPos, Calendar.SUNDAY);
addWeeklyDayPos(portletRequest, dayPos, Calendar.MONDAY);
addWeeklyDayPos(portletRequest, dayPos, Calendar.TUESDAY);
addWeeklyDayPos(portletRequest, dayPos, Calendar.WEDNESDAY);
addWeeklyDayPos(portletRequest, dayPos, Calendar.THURSDAY);
addWeeklyDayPos(portletRequest, dayPos, Calendar.FRIDAY);
addWeeklyDayPos(portletRequest, dayPos, Calendar.SATURDAY);
if (dayPos.isEmpty()) {
dayPos.add(new DayAndPosition(Calendar.MONDAY, 0));
}
recurrence.setByDay(dayPos.toArray(new DayAndPosition[0]));
}
else if (recurrenceType == Recurrence.MONTHLY) {
int monthlyType = ParamUtil.getInteger(
portletRequest, "monthlyType");
if (monthlyType == 0) {
int monthlyDay = ParamUtil.getInteger(
portletRequest, "monthlyDay0", 1);
recurrence.setByMonthDay(new int[] {monthlyDay});
int monthlyInterval = ParamUtil.getInteger(
portletRequest, "monthlyInterval0", 1);
recurrence.setInterval(monthlyInterval);
}
else {
int monthlyPos = ParamUtil.getInteger(
portletRequest, "monthlyPos");
int monthlyDay = ParamUtil.getInteger(
portletRequest, "monthlyDay1");
DayAndPosition[] dayPos = {
new DayAndPosition(monthlyDay, monthlyPos)
};
recurrence.setByDay(dayPos);
int monthlyInterval = ParamUtil.getInteger(
portletRequest, "monthlyInterval1", 1);
recurrence.setInterval(monthlyInterval);
}
}
else if (recurrenceType == Recurrence.YEARLY) {
int yearlyType = ParamUtil.getInteger(portletRequest, "yearlyType");
if (yearlyType == 0) {
int yearlyMonth = ParamUtil.getInteger(
portletRequest, "yearlyMonth0");
int yearlyDay = ParamUtil.getInteger(
portletRequest, "yearlyDay0", 1);
recurrence.setByMonth(new int[] {yearlyMonth});
recurrence.setByMonthDay(new int[] {yearlyDay});
int yearlyInterval = ParamUtil.getInteger(
portletRequest, "yearlyInterval0", 1);
recurrence.setInterval(yearlyInterval);
}
else {
int yearlyPos = ParamUtil.getInteger(
portletRequest, "yearlyPos");
int yearlyDay = ParamUtil.getInteger(
portletRequest, "yearlyDay1");
int yearlyMonth = ParamUtil.getInteger(
portletRequest, "yearlyMonth1");
DayAndPosition[] dayPos = {
new DayAndPosition(yearlyDay, yearlyPos)
};
recurrence.setByDay(dayPos);
recurrence.setByMonth(new int[] {yearlyMonth});
int yearlyInterval = ParamUtil.getInteger(
portletRequest, "yearlyInterval1", 1);
recurrence.setInterval(yearlyInterval);
}
}
return RecurrenceSerializer.toCronText(recurrence);
}
@Override
public Date getEndTime(SchedulerResponse schedulerResponse) {
Message message = schedulerResponse.getMessage();
JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
TriggerState triggerState = jobState.getTriggerState();
if (triggerState.equals(TriggerState.NORMAL) ||
triggerState.equals(TriggerState.PAUSED)) {
return (Date)message.get(SchedulerEngine.END_TIME);
}
else {
return jobState.getTriggerDate(SchedulerEngine.END_TIME);
}
}
@Override
public Date getEndTime(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
SchedulerResponse schedulerResponse = getScheduledJob(
jobName, groupName, storageType);
if (schedulerResponse != null) {
return getEndTime(schedulerResponse);
}
return null;
}
@Override
public Date getFinalFireTime(SchedulerResponse schedulerResponse) {
Message message = schedulerResponse.getMessage();
JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
TriggerState triggerState = jobState.getTriggerState();
if (triggerState.equals(TriggerState.NORMAL) ||
triggerState.equals(TriggerState.PAUSED)) {
return (Date)message.get(SchedulerEngine.FINAL_FIRE_TIME);
}
else {
return jobState.getTriggerDate(SchedulerEngine.FINAL_FIRE_TIME);
}
}
@Override
public Date getFinalFireTime(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
SchedulerResponse schedulerResponse = getScheduledJob(
jobName, groupName, storageType);
if (schedulerResponse != null) {
return getFinalFireTime(schedulerResponse);
}
return null;
}
@Override
public ObjectValuePair<Exception, Date>[] getJobExceptions(
SchedulerResponse schedulerResponse) {
Message message = schedulerResponse.getMessage();
JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
return jobState.getExceptions();
}
@Override
public ObjectValuePair<Exception, Date>[] getJobExceptions(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
SchedulerResponse schedulerResponse = getScheduledJob(
jobName, groupName, storageType);
if (schedulerResponse != null) {
return getJobExceptions(schedulerResponse);
}
return null;
}
@Override
public TriggerState getJobState(SchedulerResponse schedulerResponse) {
Message message = schedulerResponse.getMessage();
JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
return jobState.getTriggerState();
}
@Override
public TriggerState getJobState(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
SchedulerResponse schedulerResponse = getScheduledJob(
jobName, groupName, storageType);
if (schedulerResponse != null) {
return getJobState(schedulerResponse);
}
return null;
}
@Override
public Date getNextFireTime(SchedulerResponse schedulerResponse) {
Message message = schedulerResponse.getMessage();
JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
TriggerState triggerState = jobState.getTriggerState();
if (triggerState.equals(TriggerState.NORMAL) ||
triggerState.equals(TriggerState.PAUSED)) {
return (Date)message.get(SchedulerEngine.NEXT_FIRE_TIME);
}
else {
return jobState.getTriggerDate(SchedulerEngine.NEXT_FIRE_TIME);
}
}
@Override
public Date getNextFireTime(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
SchedulerResponse schedulerResponse = getScheduledJob(
jobName, groupName, storageType);
if (schedulerResponse != null) {
return getNextFireTime(schedulerResponse);
}
return null;
}
@Override
public Date getPreviousFireTime(SchedulerResponse schedulerResponse) {
Message message = schedulerResponse.getMessage();
JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
TriggerState triggerState = jobState.getTriggerState();
if (triggerState.equals(TriggerState.NORMAL) ||
triggerState.equals(TriggerState.PAUSED)) {
return (Date)message.get(SchedulerEngine.PREVIOUS_FIRE_TIME);
}
else {
return jobState.getTriggerDate(SchedulerEngine.PREVIOUS_FIRE_TIME);
}
}
@Override
public Date getPreviousFireTime(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
SchedulerResponse schedulerResponse = getScheduledJob(
jobName, groupName, storageType);
if (schedulerResponse != null) {
return getPreviousFireTime(schedulerResponse);
}
return null;
}
@Override
public SchedulerResponse getScheduledJob(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
return _schedulerEngine.getScheduledJob(
jobName, groupName, storageType);
}
@Override
public List<SchedulerResponse> getScheduledJobs()
throws SchedulerException {
return _schedulerEngine.getScheduledJobs();
}
@Override
public List<SchedulerResponse> getScheduledJobs(StorageType storageType)
throws SchedulerException {
return _schedulerEngine.getScheduledJobs(storageType);
}
@Override
public List<SchedulerResponse> getScheduledJobs(
String groupName, StorageType storageType)
throws SchedulerException {
return _schedulerEngine.getScheduledJobs(groupName, storageType);
}
@Override
public Date getStartTime(SchedulerResponse schedulerResponse) {
Message message = schedulerResponse.getMessage();
JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
TriggerState triggerState = jobState.getTriggerState();
if (triggerState.equals(TriggerState.NORMAL) ||
triggerState.equals(TriggerState.PAUSED)) {
return (Date)message.get(SchedulerEngine.START_TIME);
}
else {
return jobState.getTriggerDate(SchedulerEngine.START_TIME);
}
}
@Override
public Date getStartTime(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
SchedulerResponse schedulerResponse = getScheduledJob(
jobName, groupName, storageType);
if (schedulerResponse != null) {
return getStartTime(schedulerResponse);
}
return null;
}
@Override
public void pause(String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.pause(groupName, storageType);
}
@Override
public void pause(String jobName, String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.pause(jobName, groupName, storageType);
}
@Override
public void register(
MessageListener messageListener, SchedulerEntry schedulerEntry,
String destinationName) {
SchedulerEventMessageListenerWrapper
schedulerEventMessageListenerWrapper =
new SchedulerEventMessageListenerWrapper();
schedulerEventMessageListenerWrapper.setMessageListener(
messageListener);
schedulerEventMessageListenerWrapper.setSchedulerEntry(schedulerEntry);
Dictionary<String, Object> properties = new HashMapDictionary<>();
properties.put("destination.name", destinationName);
ServiceRegistration<SchedulerEventMessageListener> serviceRegistration =
_bundleContext.registerService(
SchedulerEventMessageListener.class,
schedulerEventMessageListenerWrapper, properties);
_serviceRegistrations.put(messageListener, serviceRegistration);
}
@Override
public void resume(String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.resume(groupName, storageType);
}
@Override
public void resume(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.resume(jobName, groupName, storageType);
}
@Override
public void schedule(
Trigger trigger, StorageType storageType, String description,
String destinationName, Message message, int exceptionsMaxSize)
throws SchedulerException {
if (message == null) {
message = new Message();
}
message.put(SchedulerEngine.EXCEPTIONS_MAX_SIZE, exceptionsMaxSize);
_schedulerEngine.schedule(
trigger, description, destinationName, message, storageType);
}
@Override
public void schedule(
Trigger trigger, StorageType storageType, String description,
String destinationName, Object payload, int exceptionsMaxSize)
throws SchedulerException {
Message message = new Message();
message.setPayload(payload);
schedule(
trigger, storageType, description, destinationName, message,
exceptionsMaxSize);
}
@Override
public void shutdown() throws SchedulerException {
_schedulerEngine.shutdown();
}
@Override
public void start() throws SchedulerException {
_schedulerEngine.start();
}
@Override
public void suppressError(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.suppressError(jobName, groupName, storageType);
}
@Override
public void unregister(MessageListener messageListener) {
_serviceRegistrations.compute(
messageListener,
(key, value) -> {
value.unregister();
return null;
});
}
@Override
public void unschedule(
SchedulerEntry schedulerEntry, StorageType storageType)
throws SchedulerException {
Trigger trigger = schedulerEntry.getTrigger();
unschedule(trigger.getJobName(), trigger.getGroupName(), storageType);
}
@Override
public void unschedule(String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.unschedule(groupName, storageType);
}
@Override
public void unschedule(
String jobName, String groupName, StorageType storageType)
throws SchedulerException {
_schedulerEngine.unschedule(jobName, groupName, storageType);
}
@Override
public void update(
String jobName, String groupName, StorageType storageType,
String description, String language, String script,
int exceptionsMaxSize)
throws SchedulerException {
SchedulerResponse schedulerResponse = getScheduledJob(
jobName, groupName, storageType);
if (schedulerResponse == null) {
return;
}
Trigger trigger = schedulerResponse.getTrigger();
if (trigger == null) {
return;
}
Message message = schedulerResponse.getMessage();
if (message == null) {
return;
}
addScriptingJob(
trigger, storageType, description, language, script,
exceptionsMaxSize);
}
@Override
public void update(Trigger trigger, StorageType storageType)
throws SchedulerException {
_schedulerEngine.update(trigger, storageType);
}
@Activate
protected void activate(ComponentContext componentContext)
throws Exception {
Dictionary<String, Object> properties =
componentContext.getProperties();
_schedulerEngineHelperConfiguration =
ConfigurableUtil.createConfigurable(
SchedulerEngineHelperConfiguration.class, properties);
_bundleContext = componentContext.getBundleContext();
registerDestination(
_bundleContext, DestinationConfiguration.DESTINATION_TYPE_PARALLEL,
DestinationNames.SCHEDULER_DISPATCH);
Destination scriptingDestination = registerDestination(
_bundleContext, DestinationConfiguration.DESTINATION_TYPE_PARALLEL,
DestinationNames.SCHEDULER_SCRIPTING);
SchedulerEventMessageListenerWrapper
schedulerEventMessageListenerWrapper =
new SchedulerEventMessageListenerWrapper();
schedulerEventMessageListenerWrapper.setMessageListener(
new ScriptingMessageListener());
scriptingDestination.register(schedulerEventMessageListenerWrapper);
_serviceTracker = ServiceTrackerFactory.open(
_bundleContext,
"(objectClass=" + SchedulerEventMessageListener.class.getName() +
")",
new SchedulerEventMessageListenerServiceTrackerCustomizer());
}
protected void addWeeklyDayPos(
PortletRequest portletRequest, List<DayAndPosition> list, int day) {
if (ParamUtil.getBoolean(portletRequest, "weeklyDayPos" + day)) {
list.add(new DayAndPosition(day, 0));
}
}
@Deactivate
protected void deactivate() {
if (_bundleContext == null) {
return;
}
if (_serviceTracker != null) {
_serviceTracker.close();
}
try {
shutdown();
}
catch (SchedulerException se) {
if (_log.isWarnEnabled()) {
_log.warn("Unable to shutdown scheduler", se);
}
}
for (ServiceRegistration<Destination> serviceRegistration :
_destinationServiceRegistrations) {
Destination destination = _bundleContext.getService(
serviceRegistration.getReference());
serviceRegistration.unregister();
destination.destroy();
}
for (ServiceRegistration<SchedulerEventMessageListener>
serviceRegistration : _serviceRegistrations.values()) {
serviceRegistration.unregister();
}
_bundleContext = null;
}
protected SchedulerEngine getSchedulerEngine() {
return _schedulerEngine;
}
@Modified
protected void modified(Map<String, Object> properties) throws Exception {
_schedulerEngineHelperConfiguration =
ConfigurableUtil.createConfigurable(
SchedulerEngineHelperConfiguration.class, properties);
}
protected Destination registerDestination(
BundleContext bundleContext, String destinationType,
String destinationName) {
DestinationConfiguration destinationConfiguration =
new DestinationConfiguration(destinationType, destinationName);
Destination destination = _destinationFactory.createDestination(
destinationConfiguration);
Dictionary<String, Object> dictionary = new HashMapDictionary<>();
dictionary.put("destination.name", destination.getName());
ServiceRegistration<Destination> serviceRegistration =
bundleContext.registerService(
Destination.class, destination, dictionary);
_destinationServiceRegistrations.add(serviceRegistration);
return destination;
}
@Reference(
cardinality = ReferenceCardinality.OPTIONAL,
policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY
)
protected void setAuditRouter(AuditRouter auditRouter) {
_auditRouter = auditRouter;
}
@Reference(unbind = "-")
protected void setDestinationFactory(
DestinationFactory destinationFactory) {
_destinationFactory = destinationFactory;
}
@Reference(unbind = "-")
protected void setJsonFactory(JSONFactory jsonFactory) {
_jsonFactory = jsonFactory;
}
@Reference(target = "(scheduler.engine.proxy=true)", unbind = "-")
protected void setSchedulerEngine(SchedulerEngine schedulerEngine) {
_schedulerEngine = schedulerEngine;
}
@Reference(unbind = "-")
protected void setSchedulerProxyMessagingConfigurator(
SchedulerProxyMessagingConfigurator
schedulerProxyMessagingConfigurator) {
}
protected void unsetAuditRouter(AuditRouter auditRouter) {
_auditRouter = null;
}
private static final Log _log = LogFactoryUtil.getLog(
SchedulerEngineHelperImpl.class);
private AuditRouter _auditRouter;
private volatile BundleContext _bundleContext;
private DestinationFactory _destinationFactory;
private final Set<ServiceRegistration<Destination>>
_destinationServiceRegistrations = new HashSet<>();
private JSONFactory _jsonFactory;
private final Map<String, ServiceRegistration<MessageListener>>
_messageListenerServiceRegistrations = new ConcurrentHashMap<>();
@Reference
private Portal _portal;
private SchedulerEngine _schedulerEngine;
private volatile SchedulerEngineHelperConfiguration
_schedulerEngineHelperConfiguration;
private final Map
<MessageListener, ServiceRegistration<SchedulerEventMessageListener>>
_serviceRegistrations = new ConcurrentHashMap<>();
private volatile ServiceTracker
<SchedulerEventMessageListener, SchedulerEventMessageListener>
_serviceTracker;
private class SchedulerEventMessageListenerServiceTrackerCustomizer
implements ServiceTrackerCustomizer
<SchedulerEventMessageListener, SchedulerEventMessageListener> {
@Override
public SchedulerEventMessageListener addingService(
ServiceReference<SchedulerEventMessageListener> serviceReference) {
Bundle bundle = serviceReference.getBundle();
BundleContext bundleContext = bundle.getBundleContext();
SchedulerEventMessageListener schedulerEventMessageListener =
bundleContext.getService(serviceReference);
SchedulerEntry schedulerEntry =
schedulerEventMessageListener.getSchedulerEntry();
StorageType storageType = StorageType.MEMORY_CLUSTERED;
if ((schedulerEntry == null) ||
(schedulerEntry.getTrigger() == null)) {
return null;
}
if (schedulerEntry instanceof StorageTypeAware) {
StorageTypeAware storageTypeAware =
(StorageTypeAware)schedulerEntry;
storageType = storageTypeAware.getStorageType();
}
String destinationName = (String)serviceReference.getProperty(
"destination.name");
if (Validator.isNull(destinationName)) {
destinationName = DestinationNames.SCHEDULER_DISPATCH;
}
SchedulerClusterInvokingThreadLocal.setEnabled(false);
try {
schedule(
schedulerEntry.getTrigger(), storageType,
schedulerEntry.getDescription(), destinationName, null, 0);
ServiceRegistration<MessageListener> serviceRegistration =
_messageListenerServiceRegistrations.get(
schedulerEntry.getEventListenerClass());
if (serviceRegistration != null) {
ServiceReference<MessageListener> oldServiceReference =
serviceRegistration.getReference();
MessageListener messageListener = bundleContext.getService(
oldServiceReference);
SchedulerEventMessageListenerWrapper
schedulerEventMessageListenerWrapper =
(SchedulerEventMessageListenerWrapper)
messageListener;
schedulerEventMessageListenerWrapper.setSchedulerEntry(
schedulerEntry);
return null;
}
Dictionary<String, Object> properties =
new HashMapDictionary<>();
properties.put("destination.name", destinationName);
serviceRegistration = bundleContext.registerService(
MessageListener.class, schedulerEventMessageListener,
properties);
_messageListenerServiceRegistrations.put(
schedulerEntry.getEventListenerClass(),
serviceRegistration);
return schedulerEventMessageListener;
}
catch (SchedulerException se) {
_log.error(se, se);
}
finally {
SchedulerClusterInvokingThreadLocal.setEnabled(true);
}
return null;
}
@Override
public void modifiedService(
ServiceReference<SchedulerEventMessageListener> serviceReference,
SchedulerEventMessageListener schedulerEventMessageListener) {
}
@Override
public void removedService(
ServiceReference<SchedulerEventMessageListener> serviceReference,
SchedulerEventMessageListener schedulerEntryMessageListener) {
Bundle bundle = serviceReference.getBundle();
BundleContext bundleContext = bundle.getBundleContext();
bundleContext.ungetService(serviceReference);
StorageType storageType = StorageType.MEMORY_CLUSTERED;
SchedulerEntry schedulerEntry =
schedulerEntryMessageListener.getSchedulerEntry();
if (schedulerEntry == null) {
return;
}
if (schedulerEntry instanceof StorageTypeAware) {
StorageTypeAware storageTypeAware =
(StorageTypeAware)schedulerEntry;
storageType = storageTypeAware.getStorageType();
}
SchedulerClusterInvokingThreadLocal.setEnabled(false);
try {
unschedule(schedulerEntry, storageType);
}
catch (SchedulerException se) {
_log.error(se, se);
}
finally {
SchedulerClusterInvokingThreadLocal.setEnabled(true);
}
ServiceRegistration<MessageListener>
messageListenerServiceRegistration =
_messageListenerServiceRegistrations.remove(
schedulerEntry.getEventListenerClass());
messageListenerServiceRegistration.unregister();
}
}
}