Skip to content

Commit

Permalink
[JBPM-10197] Handle TimerMappingInfo in error scenarios
Browse files Browse the repository at this point in the history
  • Loading branch information
fjtirado committed Sep 15, 2023
1 parent 711e13b commit f74a8e3
Showing 1 changed file with 57 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
package org.jbpm.services.ejb.timer;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;

import javax.ejb.EJBException;
import javax.ejb.Timer;
import javax.ejb.TimerHandle;
import javax.naming.InitialContext;
Expand Down Expand Up @@ -129,43 +131,74 @@ public void afterCompletion(int status) {
}
}

private TimerJobInstance getTimerJobInstance (String uuid) {
private TimerJobInstance getTimerJobInstance(String uuid) {
return unwrapTimerJobInstance(getEjbTimer(getTimerMappinInfo(uuid)));
}


@Override
public TimerJobInstance getTimerJobInstance(long processInstanceId, long timerId) {
return unwrapTimerJobInstance(getEjbTimer(getTimerMappinInfo(processInstanceId, timerId)));
try {
return unwrapTimerJobInstance(getEjbTimer(getTimerMappinInfo(processInstanceId, timerId)));
} catch (Exception e) {
logger.warn("Problem retrieving timer for processInstance Id {}, returning null", timerId,
processInstanceId,
e);
return null;
}
}

private Timer getEjbTimer(TimerMappingInfo timerMappingInfo) {
try {
if(timerMappingInfo == null || timerMappingInfo.getInfo() == null) {
return null;
}
byte[] data = timerMappingInfo.getInfo();
return ((TimerHandle) new ObjectInputStream(new ByteArrayInputStream(data)).readObject()).getTimer();
} catch (Exception e) {
logger.warn("wast not able to deserialize info field from timer info for uuid");
if (timerMappingInfo == null || timerMappingInfo.getInfo() == null) {
return null;
}
try {
return ((TimerHandle) new ObjectInputStream(
new ByteArrayInputStream(timerMappingInfo.getInfo()))
.readObject()).getTimer();

} catch (ClassNotFoundException | IOException e) {
logger.warn("Error {} deserializing the timer handle for timermappinginfo {}", e.getMessage(),
timerMappingInfo);
deleteTimerMapping(timerMappingInfo);
throw new RuntimeException(e);
} catch (EJBException e) {
logger.warn("Error {} retrieving the EJB timer from timermappinginfo {}", e.getMessage(), timerMappingInfo);
deleteTimerMapping(timerMappingInfo);
throw e;
}
}

private int deleteTimerMapping(TimerMappingInfo timerMappingInfo) {
return executeDBOperation(em -> em
.createQuery("DELETE FROM TimerMappingInfo o WHERE o.kieSessionId = :kieSessionId AND o.uuid = :uuid")
.setParameter("kieSessionId", timerMappingInfo.getKieSessionId())
.setParameter("uuid", timerMappingInfo.getUuid())
.executeUpdate());
}

private TimerMappingInfo getTimerMappinInfo(String uuid) {
return getTimerMappingInfo(em -> em.createQuery("SELECT o FROM TimerMappingInfo o WHERE o.uuid = :uuid", TimerMappingInfo.class).setParameter("uuid", uuid).getResultList());
}

private TimerMappingInfo getTimerMappinInfo(long processInstanceId, long timerId) {
return getTimerMappingInfo(em ->
em.createQuery("SELECT o FROM TimerMappingInfo o WHERE o.timerId = :timerId AND o.processInstanceId = :processInstanceId", TimerMappingInfo.class)
.setParameter("processInstanceId", processInstanceId)
.setParameter("timerId", timerId)
.getResultList()
);
return getTimerMappingInfo(em -> em.createQuery(
"SELECT o FROM TimerMappingInfo o WHERE o.timerId = :timerId AND o.processInstanceId = :processInstanceId",
TimerMappingInfo.class).setParameter("processInstanceId", processInstanceId)
.setParameter("timerId", timerId).getResultList());
}

private TimerMappingInfo getTimerMappingInfo(Function<EntityManager, List<TimerMappingInfo>> func) {
try {
List<TimerMappingInfo> info = executeDBOperation(func);
return !info.isEmpty() ? info.get(0) : null;
} catch (Exception ex) {
logger.info("Error {} retrieving timer mapping info", ex.getMessage());
return null;
}
}


private <T> T executeDBOperation (Function<EntityManager,T> func) {
InternalRuntimeManager manager = ((GlobalTimerService) globalTimerService).getRuntimeManager();
String pu = ((InternalRuntimeManager) manager).getDeploymentDescriptor().getPersistenceUnit();
EntityManagerFactory emf = EntityManagerFactoryManager.get().getOrCreate(pu);
Expand All @@ -176,16 +209,7 @@ private TimerMappingInfo getTimerMappingInfo(Function<EntityManager, List<TimerM
if (tm != null && tm.getStatus() == TransactionManager.STATUS_ROLLEDBACK) {
txOwner = tm.begin();
}
List<TimerMappingInfo> info = func.apply(em);
if (!info.isEmpty()) {
return info.get(0);
} else {
return null;
}

} catch (Exception ex) {
logger.warn("Error getting mapping info ",ex);
return null;
return func.apply(em);
} finally {
if (tm != null) {
tm.commit(txOwner);
Expand All @@ -194,18 +218,15 @@ private TimerMappingInfo getTimerMappingInfo(Function<EntityManager, List<TimerM
}
}


private TimerJobInstance unwrapTimerJobInstance(Timer timer) {
try {
if (timer == null) {
return null;
}
Serializable info = timer.getInfo();
EjbTimerJob job = (EjbTimerJob) info;
TimerJobInstance handle = job.getTimerJobInstance();
return handle;
} catch (Exception e) {
if (timer == null) {
return null;
}
Serializable info = timer.getInfo();
EjbTimerJob job = (EjbTimerJob) info;
TimerJobInstance handle = job.getTimerJobInstance();
return handle;
}

@Override
Expand Down

0 comments on commit f74a8e3

Please sign in to comment.