/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jbpm.services.ejb.timer;
import org.drools.core.time.InternalSchedulerService;
import org.drools.core.time.Job;
import org.drools.core.time.JobContext;
import org.drools.core.time.JobHandle;
import org.drools.core.time.TimerService;
import org.drools.core.time.Trigger;
import org.drools.core.time.impl.TimerJobInstance;
import org.jbpm.process.core.timer.GlobalSchedulerService;
import org.jbpm.process.core.timer.NamedJobContext;
import org.jbpm.process.core.timer.SchedulerServiceInterceptor;
import org.jbpm.process.core.timer.impl.DelegateSchedulerServiceInterceptor;
import org.jbpm.process.core.timer.impl.GlobalTimerService;
import org.jbpm.process.core.timer.impl.GlobalTimerService.GlobalJobHandle;
import org.jbpm.process.instance.timer.TimerManager.ProcessJobContext;
import org.jbpm.process.instance.timer.TimerManager.StartProcessJobContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.concurrent.atomic.AtomicLong;
public class EjbSchedulerService implements GlobalSchedulerService {
private static final Boolean TRANSACTIONAL = Boolean.parseBoolean(System.getProperty("org.jbpm.ejb.timer.tx", "false"));
private AtomicLong idCounter = new AtomicLong();
private TimerService globalTimerService;
private EJBTimerScheduler scheduler;
private SchedulerServiceInterceptor interceptor = new DelegateSchedulerServiceInterceptor(this);
@Override
public JobHandle scheduleJob(Job job, JobContext ctx, Trigger trigger) {
Long id = idCounter.getAndIncrement();
String jobName = getJobName(ctx, id);
EjbGlobalJobHandle jobHandle = new EjbGlobalJobHandle(id, jobName, ((GlobalTimerService) globalTimerService).getTimerServiceId());
TimerJobInstance jobInstance = scheduler.getTimerByName(jobName);
if (jobInstance != null) {
return jobInstance.getJobHandle();
}
jobInstance = globalTimerService.getTimerJobFactoryManager().createTimerJobInstance(
job,
ctx,
trigger,
jobHandle,
(InternalSchedulerService) globalTimerService);
jobHandle.setTimerJobInstance((TimerJobInstance) jobInstance);
interceptor.internalSchedule(jobInstance);
return jobHandle;
}
@Override
public boolean removeJob(JobHandle jobHandle) {
boolean result = scheduler.removeJob(jobHandle);
return result;
}
@Override
public void internalSchedule(TimerJobInstance timerJobInstance) {
scheduler.internalSchedule(timerJobInstance);
}
@Override
public void initScheduler(TimerService timerService) {
this.globalTimerService = timerService;
try {
this.scheduler = InitialContext.doLookup("java:module/EJBTimerScheduler");
} catch (NamingException e) {
throw new RuntimeException("Unable to find EJB scheduler for jBPM timer service", e);
}
}
@Override
public void shutdown() {
// managed by container - no op
}
@Override
public JobHandle buildJobHandleForContext(NamedJobContext ctx) {
return new EjbGlobalJobHandle(-1, getJobName(ctx, -1l), ((GlobalTimerService) globalTimerService).getTimerServiceId());
}
@Override
public boolean isTransactional() {
return TRANSACTIONAL;
}
@Override
public boolean retryEnabled() {
return false;
}
@Override
public void setInterceptor(SchedulerServiceInterceptor interceptor) {
this.interceptor = interceptor;
}
@Override
public boolean isValid(GlobalJobHandle jobHandle) {
return true;
}
private String getJobName(JobContext ctx, Long id) {
String jobname = null;
if (ctx instanceof ProcessJobContext) {
ProcessJobContext processCtx = (ProcessJobContext) ctx;
jobname = processCtx.getSessionId() + "-" + processCtx.getProcessInstanceId() + "-" + processCtx.getTimer().getId();
if (processCtx instanceof StartProcessJobContext) {
jobname = "StartProcess-"+((StartProcessJobContext) processCtx).getProcessId()+ "-" + processCtx.getTimer().getId();
}
} else if (ctx instanceof NamedJobContext) {
jobname = ((NamedJobContext) ctx).getJobName();
} else {
jobname = "Timer-"+ctx.getClass().getSimpleName()+ "-" + id;
}
return jobname;
}
}