package org.molgenis.gavin.job; import org.molgenis.data.DataService; import org.molgenis.data.annotation.core.EffectBasedAnnotator; import org.molgenis.data.annotation.core.RepositoryAnnotator; import org.molgenis.data.jobs.JobExecutionUpdater; import org.molgenis.data.jobs.ProgressImpl; import org.molgenis.file.FileStore; import org.molgenis.gavin.job.input.Parser; import org.molgenis.security.core.runas.RunAsSystem; import org.molgenis.ui.menu.MenuReaderService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.MailSender; import org.springframework.security.access.intercept.RunAsUserToken; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Component; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.support.TransactionTemplate; import java.util.List; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; import static java.util.stream.Stream.of; import static org.molgenis.gavin.job.meta.GavinJobExecutionMetaData.GAVIN_JOB_EXECUTION; @Component public class GavinJobFactory { private static final Logger LOG = LoggerFactory.getLogger(GavinJobFactory.class); private final Parser parser; private DataService dataService; private PlatformTransactionManager transactionManager; private UserDetailsService userDetailsService; private JobExecutionUpdater jobExecutionUpdater; private MailSender mailSender; private FileStore fileStore; private RepositoryAnnotator cadd; private RepositoryAnnotator exac; private RepositoryAnnotator snpEff; private EffectBasedAnnotator gavin; private MenuReaderService menuReaderService; private AnnotatorRunner annotatorRunner; @Autowired public GavinJobFactory(DataService dataService, PlatformTransactionManager transactionManager, UserDetailsService userDetailsService, JobExecutionUpdater jobExecutionUpdater, MailSender mailSender, FileStore fileStore, RepositoryAnnotator cadd, RepositoryAnnotator exac, RepositoryAnnotator snpEff, EffectBasedAnnotator gavin, MenuReaderService menuReaderService, Parser parser, AnnotatorRunner annotatorRunner) { this.dataService = requireNonNull(dataService); this.transactionManager = requireNonNull(transactionManager); this.userDetailsService = requireNonNull(userDetailsService); this.jobExecutionUpdater = requireNonNull(jobExecutionUpdater); this.mailSender = requireNonNull(mailSender); this.fileStore = requireNonNull(fileStore); this.cadd = requireNonNull(cadd); this.exac = requireNonNull(exac); this.snpEff = requireNonNull(snpEff); this.gavin = requireNonNull(gavin); this.menuReaderService = requireNonNull(menuReaderService); this.parser = requireNonNull(parser); this.annotatorRunner = requireNonNull(annotatorRunner); } @RunAsSystem public GavinJob createJob(GavinJobExecution gavinJobExecution) { dataService.add(gavinJobExecution.getEntityType().getName(), gavinJobExecution); String username = gavinJobExecution.getUser(); // create an authentication to run as the user that is listed as the owner of the job RunAsUserToken runAsAuthentication = new RunAsUserToken("Job Execution", username, null, userDetailsService.loadUserByUsername(username).getAuthorities(), null); return new GavinJob(new ProgressImpl(gavinJobExecution, jobExecutionUpdater, mailSender), new TransactionTemplate(transactionManager), runAsAuthentication, gavinJobExecution.getIdentifier(), fileStore, menuReaderService, cadd, exac, snpEff, gavin, parser, annotatorRunner, gavinJobExecution); } public List<String> getAnnotatorsWithMissingResources() { return of(cadd, exac, snpEff, gavin).filter(annotator -> !annotator.annotationDataExists()) .map(RepositoryAnnotator::getSimpleName).collect(toList()); } /** * Retrieves a {@link GavinJobExecution} for anyone who has the identifier, without checking their permissions. * * @param jobIdentifier the identifier of the {@link GavinJobExecution} * @return GavinJobExecution with the specified identifier, if it exists * @throws JobNotFoundException if no GavinJobExecution with the specified identifier exists. */ @RunAsSystem public GavinJobExecution findGavinJobExecution(String jobIdentifier) throws JobNotFoundException { GavinJobExecution result = dataService.findOneById(GAVIN_JOB_EXECUTION, jobIdentifier, GavinJobExecution.class); if (result == null) { throw new JobNotFoundException("Job not found."); } return result; } }