package edu.unc.lib.dl.cdr.services.processing; import static edu.unc.lib.dl.util.JMSMessageUtil.servicesMessageNamespace; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import edu.unc.lib.dl.cdr.services.ObjectEnhancementService; import edu.unc.lib.dl.cdr.services.exception.EnhancementException; import edu.unc.lib.dl.cdr.services.model.EnhancementMessage; import edu.unc.lib.dl.reporting.ActivityMetricsClient; import edu.unc.lib.dl.util.JMSMessageUtil.ServicesActions; public class ApplyEnhancementServicesJob implements Runnable { private static final Logger LOG = LoggerFactory.getLogger(ApplyEnhancementServicesJob.class); private List<ObjectEnhancementService> services; private long recoverableDelay = 0; private final EnhancementMessage message; private ActivityMetricsClient metricsClient; public ApplyEnhancementServicesJob(String pidString, boolean force) { this.message = new EnhancementMessage(pidString, servicesMessageNamespace, ServicesActions.APPLY_SERVICE_STACK.getName()); this.message.setCompletedServices(new ArrayList<String>()); this.message.setForce(force); } public ApplyEnhancementServicesJob(String messagePid, String messageNamespace, String messageAction, String messageServiceName, List<String> filteredServices) { this.message = new EnhancementMessage(messagePid, messageNamespace, messageAction, messageServiceName); this.message.setFilteredServices(filteredServices); this.message.setCompletedServices(new ArrayList<String>()); } public void setServices(List<ObjectEnhancementService> services) { this.services = services; } public void setRecoverableDelay(long recoverableDelay) { this.recoverableDelay = recoverableDelay; } public void setMetricsClient(ActivityMetricsClient operationMetricsClient) { this.metricsClient = operationMetricsClient; } @Override public void run() { for (ObjectEnhancementService service : services) { if (message.getFilteredServices() != null && !message.getFilteredServices().contains(service.getClass().getName())) { continue; } try { if (!service.isApplicable(message)) { continue; } } catch (EnhancementException e) { LOG.error("Error determining applicability for service " + service.getClass().getName() + " and object " + message.getTargetID(), e); } try { applyService(service); metricsClient.incrFinishedEnhancement(service.getClass().getName()); } catch (EnhancementException e) { LOG.error("Error applying service " + service.getClass().getName() + " to object " + message.getTargetID(), e); metricsClient.incrFailedEnhancement(service.getClass().getName()); } catch (Throwable t) { metricsClient.incrFailedEnhancement(service.getClass().getName()); throw t; } } } private void applyService(ObjectEnhancementService service) throws EnhancementException { while (true) { LOG.info("Applying service {} to object {}", service.getClass().getName(), message.getTargetID()); try { service.getEnhancement(message).call(); message.getCompletedServices().add(service.getClass().getName()); break; } catch (EnhancementException e) { if (e.getSeverity() == EnhancementException.Severity.RECOVERABLE) { LOG.error("Retrying service for recoverable exception: " + service.getClass().getName(), e); } else { throw e; } } try { Thread.sleep(recoverableDelay); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } }