package org.dcm4chee.archive.processing.impl; import java.util.Arrays; import java.util.Collection; import java.util.List; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.dcm4che3.data.Attributes; import org.dcm4chee.archive.dto.ActiveService; import org.dcm4chee.archive.entity.ActiveProcessing; import org.dcm4chee.archive.processing.ActiveProcessingService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * API to Add, Remove and Query ActiveProcesses. * * @author Hesham Elbadawi <bsdreko@gmail.com> */ @EJB(name = ActiveProcessingService.JNDI_NAME, beanInterface = ActiveProcessingService.class) @Stateless public class ActiveProcessingServiceImpl implements ActiveProcessingService { private static final Logger LOG = LoggerFactory.getLogger(ActiveProcessingServiceImpl.class); @PersistenceContext(name = "dcm4chee-arc", unitName="dcm4chee-arc") private EntityManager em; @Override public boolean addActiveProcess(String studyIUID, String seriesIUID, String sopIUID, ActiveService service) { return addActiveProcess(sopIUID, sopIUID, sopIUID, service, null); } @Override public boolean addActiveProcess(String studyIUID, String seriesIUID, String sopIUID, ActiveService service, Attributes attrs) { ActiveProcessing activeProcess = new ActiveProcessing(); activeProcess.setStudyInstanceUID(studyIUID); activeProcess.setSeriesInstanceUID(seriesIUID); activeProcess.setSopInstanceUID(sopIUID); activeProcess.setActiveService(service); activeProcess.setAttributes(attrs); boolean persisted = false; try{ em.persist(activeProcess); persisted = true; } catch(Exception e) { LOG.error("Unable to persist Active Process with studyIUID = {}, " + "seriesIUID = {} and sopIUID = {} for service {} - " + "reason {}", studyIUID, seriesIUID, sopIUID, service, e); } return persisted; } @Override public boolean isStudyUnderProcessingByServices(String studyIUID, List<ActiveService> services) { Query query = em.createNamedQuery(ActiveProcessing.IS_STUDY_BEING_PROCESSED); query.setParameter("uid", studyIUID); query.setParameter("serviceList", services); try{ return (Long) query.getSingleResult() > 0; } catch (Exception e) { LOG.error("Unable to check active processing status for the provided" + " study {} - reason {}", studyIUID, e); return false; } } @Override public List<ActiveProcessing> getActiveProcessesByStudy(String studyIUID, ActiveService activeService) { return queryActiveProcesses(studyIUID, activeService, ActiveProcessing.FIND_BY_STUDY_IUID_AND_SERVICE, ActiveProcessing.FIND_BY_STUDY_IUID); } @Override public List<ActiveProcessing> getActiveProcessesBySeries(String seriesIUID, ActiveService activeService) { return queryActiveProcesses(seriesIUID, activeService, ActiveProcessing.FIND_BY_SERIES_IUID_AND_SERVICE, ActiveProcessing.FIND_BY_SERIES_IUID); } @Override public List<ActiveProcessing> getActiveProcessesBySOPInstanceUID(String sopIUID, ActiveService activeService) { return queryActiveProcesses(sopIUID, activeService, ActiveProcessing.FIND_BY_SOP_IUID_AND_SERVICE, ActiveProcessing.FIND_BY_SOP_IUID); } @SuppressWarnings("unchecked") @Override public List<ActiveProcessing> getActiveProcessesBySOPInstanceUIDs(List<String> sopIUIDs, ActiveService activeService) { Query query = em.createNamedQuery(activeService == null ? ActiveProcessing.FIND_BY_SOP_IUIDs : ActiveProcessing.FIND_BY_SOP_IUIDs_AND_SERVICE); query.setParameter("uidList", sopIUIDs); if (activeService != null) query.setParameter("service", activeService); try{ return query.getResultList(); } catch (Exception e) { LOG.error("Unable to get active processes for {} and the provided SOPIUIDs! reason {}, return null", activeService, e); return null; } } @SuppressWarnings("unchecked") private List<ActiveProcessing> queryActiveProcesses(String uid, ActiveService activeService, String queryNameWithService, String queryNameWithoutService) { String queryName = activeService == null ? queryNameWithoutService : queryNameWithService; Query query = em.createNamedQuery(queryName); query.setParameter("uid", uid); if (activeService != null) query.setParameter("service", activeService); try{ return query.getResultList(); } catch (Exception e) { LOG.error("Unable to get active processes for {}! service: {} uid: {} reason {}, return null", queryName, activeService, uid, e); return null; } } @Override public boolean deleteActiveProcessBySOPInstanceUIDandService(String sopIUID, ActiveService service) { return deleteActiveProcessesBySOPInstanceUIDsAndService(Arrays.asList(sopIUID), service); } @Override public boolean deleteActiveProcessesBySOPInstanceUIDsAndService(List<String> sopIUIDs, ActiveService service) { if(sopIUIDs.isEmpty()) { return true; } Query query = em.createNamedQuery(ActiveProcessing.DELETE_BY_SOP_IUIDs_AND_SERVICE); query.setParameter("uidList", sopIUIDs); query.setParameter("service", service); int result = 0; try { result = query.executeUpdate(); } catch (Exception e) { LOG.error("Unable to delete provided Active Process with SOP IUIDs " + "= {} for service {} - reason {}", sopIUIDs, service, e); } return result != 0; } @Override @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public boolean deleteActiveProcesses(Collection<ActiveProcessing> activeProcessings) { for(ActiveProcessing ap : activeProcessings) { // we are in a new transaction -> re-attach entity ap = em.merge(ap); em.remove(ap); } return true; } }