From f74a8e399d8dbe2b00d50ff2be23df6766f59c39 Mon Sep 17 00:00:00 2001 From: Francisco Javier Tirado Sarti Date: Fri, 15 Sep 2023 14:29:44 +0200 Subject: [PATCH] [JBPM-10197] Handle TimerMappingInfo in error scenarios --- .../ejb/timer/EjbSchedulerService.java | 93 ++++++++++++------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EjbSchedulerService.java b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EjbSchedulerService.java index 2ad481713a..4db84a3edd 100644 --- a/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EjbSchedulerService.java +++ b/jbpm-services/jbpm-services-ejb/jbpm-services-ejb-timer/src/main/java/org/jbpm/services/ejb/timer/EjbSchedulerService.java @@ -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; @@ -129,27 +131,49 @@ 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) { @@ -157,15 +181,24 @@ private TimerMappingInfo getTimerMappinInfo(String uuid) { } 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> func) { + try { + List 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 executeDBOperation (Function func) { InternalRuntimeManager manager = ((GlobalTimerService) globalTimerService).getRuntimeManager(); String pu = ((InternalRuntimeManager) manager).getDeploymentDescriptor().getPersistenceUnit(); EntityManagerFactory emf = EntityManagerFactoryManager.get().getOrCreate(pu); @@ -176,16 +209,7 @@ private TimerMappingInfo getTimerMappingInfo(Function 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); @@ -194,18 +218,15 @@ private TimerMappingInfo getTimerMappingInfo(Function