3821 term code system batch jobs (#3826)

* step one

* blah

* no working test

* updated existing tests

* delete code system version and code system jobs

* trying to get terminology fixed

* updating tests

* need to have some movement

* added completion handler

* added clearing code for failsafe

* review points

* fixing tests

* fixing tests

* more test fixes

* fixing more tests

* review fixes

* todo

Co-authored-by: leif stawnyczy <leifstawnyczy@leifs-MacBook-Pro.local>
This commit is contained in:
TipzCM 2022-07-27 14:50:42 -04:00 committed by GitHub
parent d405fa1f32
commit 9a1d6f3172
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 1072 additions and 1043 deletions

View File

@ -52,19 +52,11 @@ public final class BatchConstants {
* TermCodeSystem delete
*/
public static final String TERM_CODE_SYSTEM_DELETE_JOB_NAME = "termCodeSystemDeleteJob";
public static final String TERM_CONCEPT_RELATIONS_DELETE_STEP_NAME = "termConceptRelationsDeleteStep";
public static final String TERM_CONCEPTS_DELETE_STEP_NAME = "termConceptsDeleteStep";
public static final String TERM_CODE_SYSTEM_VERSION_DELETE_STEP_NAME = "termCodeSystemVersionDeleteStep";
public static final String TERM_CODE_SYSTEM_DELETE_STEP_NAME = "termCodeSystemDeleteStep";
public static final String JOB_PARAM_CODE_SYSTEM_ID = "termCodeSystemPid";
/**
* TermCodeSystemVersion delete
*/
public static final String TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME = "termCodeSystemVersionDeleteJob";
public static final String TERM_CONCEPT_RELATIONS_UNIQUE_VERSION_DELETE_STEP_NAME = "termConceptRelationsUniqueVersionDeleteStep";
public static final String TERM_CONCEPTS_UNIQUE_VERSION_DELETE_STEP_NAME = "termConceptsUniqueVersionDeleteStep";
public static final String TERM_CODE_SYSTEM_UNIQUE_VERSION_DELETE_STEP_NAME = "termCodeSystemUniqueVersionDeleteStep";
/**
* Both: TermCodeSystem delete and TermCodeSystemVersion delete

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 3821
title: "Migrate existing Term Code System Delete and Term Code System Delete Version jobs to
batch 2 framework"

View File

@ -25,8 +25,6 @@ import ca.uhn.fhir.jpa.batch.svc.BatchJobSubmitterImpl;
import ca.uhn.fhir.jpa.bulk.export.job.BulkExportJobConfig;
import ca.uhn.fhir.jpa.bulk.imprt.job.BulkImportJobConfig;
import ca.uhn.fhir.jpa.config.BatchJobRegisterer;
import ca.uhn.fhir.jpa.term.job.TermCodeSystemDeleteJobConfig;
import ca.uhn.fhir.jpa.term.job.TermCodeSystemVersionDeleteJobConfig;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.explore.JobExplorer;
@ -42,9 +40,7 @@ import org.springframework.context.annotation.Import;
@Import({
CommonBatchJobConfig.class,
BulkExportJobConfig.class,
BulkImportJobConfig.class,
TermCodeSystemDeleteJobConfig.class,
TermCodeSystemVersionDeleteJobConfig.class
BulkImportJobConfig.class
// When you define a new batch job, add it here.
})
@Deprecated

View File

@ -117,7 +117,10 @@ import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
import ca.uhn.fhir.jpa.term.TermDeferredStorageSvcImpl;
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig;
import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.jpa.validation.JpaResourceLoader;
import ca.uhn.fhir.jpa.validation.ValidationSettings;
@ -176,6 +179,7 @@ import java.util.Date;
@Import({
BeanPostProcessorConfig.class,
BatchJobsConfig.class,
TermCodeSystemConfig.class,
SearchParamConfig.class,
ValidationSupportConfig.class,
Batch2SupportConfig.class,

View File

@ -5,7 +5,9 @@ import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.TransactionProcessorVersionAdapterDstu2;
import ca.uhn.fhir.jpa.term.TermReadSvcDstu2;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcDstu2;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import org.springframework.context.annotation.Bean;
@ -46,6 +48,11 @@ public class JpaDstu2Config {
return new TransactionProcessorVersionAdapterDstu2();
}
@Bean
public ITermVersionAdapterSvc translationAdaptorVersion() {
return new TermVersionAdapterSvcDstu2();
}
@Bean(name = "mySystemDaoDstu2")
public IFhirSystemDao<Bundle, MetaDt> systemDaoDstu2() {
ca.uhn.fhir.jpa.dao.FhirSystemDaoDstu2 retVal = new ca.uhn.fhir.jpa.dao.FhirSystemDaoDstu2();

View File

@ -39,15 +39,7 @@ public class SharedConfigDstu3Plus {
return new TermCodeSystemStorageSvcImpl();
}
@Bean
public TermConceptDaoSvc termConceptDaoSvc() {
return new TermConceptDaoSvc();
}
@Bean
public ITermDeferredStorageSvc termDeferredStorageSvc() {
return new TermDeferredStorageSvcImpl();
}
@Bean
public ITermReindexingSvc termReindexingSvc() {

View File

@ -58,6 +58,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
JpaConfig.class
})
public class JpaR5Config {
@Bean
public ITermVersionAdapterSvc terminologyVersionAdapterSvc() {
return new TermVersionAdapterSvcR5();

View File

@ -184,7 +184,6 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
} finally {
endRequest(theServletRequest);
}
}

View File

@ -20,8 +20,11 @@ package ca.uhn.fhir.jpa.term;
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter;
import ca.uhn.fhir.batch2.api.IJobCoordinator;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
import ca.uhn.fhir.batch2.model.StatusEnum;
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
@ -36,7 +39,8 @@ import ca.uhn.fhir.jpa.model.sched.ISchedulerService;
import ca.uhn.fhir.jpa.model.sched.ScheduledJobDefinition;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteVersionJobParameters;
import ca.uhn.fhir.util.StopWatch;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang3.Validate;
@ -45,13 +49,7 @@ import org.hl7.fhir.r4.model.ValueSet;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobOperator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@ -68,22 +66,25 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_ID;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_VERSION_ID;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_DELETE_JOB_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME;
public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
private static final Logger ourLog = LoggerFactory.getLogger(TermDeferredStorageSvcImpl.class);
final private List<TermCodeSystem> myDeferredCodeSystemsDeletions = Collections.synchronizedList(new ArrayList<>());
final private Queue<TermCodeSystemVersion> myDeferredCodeSystemVersionsDeletions = new ConcurrentLinkedQueue<>();
final private List<TermConcept> myDeferredConcepts = Collections.synchronizedList(new ArrayList<>());
final private List<ValueSet> myDeferredValueSets = Collections.synchronizedList(new ArrayList<>());
final private List<ConceptMap> myDeferredConceptMaps = Collections.synchronizedList(new ArrayList<>());
final private List<TermConceptParentChildLink> myConceptLinksToSaveLater = Collections.synchronizedList(new ArrayList<>());
final private List<JobExecution> myCurrentJobExecutions = Collections.synchronizedList(new ArrayList<>());
private final List<TermCodeSystem> myDeferredCodeSystemsDeletions = Collections.synchronizedList(new ArrayList<>());
private final Queue<TermCodeSystemVersion> myDeferredCodeSystemVersionsDeletions = new ConcurrentLinkedQueue<>();
private final List<TermConcept> myDeferredConcepts = Collections.synchronizedList(new ArrayList<>());
private final List<ValueSet> myDeferredValueSets = Collections.synchronizedList(new ArrayList<>());
private final List<ConceptMap> myDeferredConceptMaps = Collections.synchronizedList(new ArrayList<>());
private final List<TermConceptParentChildLink> myConceptLinksToSaveLater = Collections.synchronizedList(new ArrayList<>());
// TODO - why is this needed? it's cumbersome to maintain; consider removing it
/**
* A list of job ids for CodeSydstemDelete and CodeSystemVersionDelete jobs that
* have been scheduled (but not completed)
*/
private final List<String> myJobExecutions = Collections.synchronizedList(new ArrayList<>());
@Autowired
protected ITermConceptDao myConceptDao;
@ -105,19 +106,7 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
private TermConceptDaoSvc myTermConceptDaoSvc;
@Autowired
private IBatchJobSubmitter myJobSubmitter;
@Autowired
private JobOperator myJobOperator;
@Autowired
@Qualifier(TERM_CODE_SYSTEM_DELETE_JOB_NAME)
private org.springframework.batch.core.Job myTermCodeSystemDeleteJob;
@Autowired
@Qualifier(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME)
private org.springframework.batch.core.Job myTermCodeSystemVersionDeleteJob;
private IJobCoordinator myJobCoordinator;
@Override
public void addConceptToStorageQueue(TermConcept theConcept) {
@ -259,23 +248,17 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
clearJobExecutions();
}
private void clearJobExecutions() {
for (JobExecution jobExecution : myCurrentJobExecutions) {
if (!jobExecution.isRunning()) {
continue;
}
try {
myJobOperator.stop(jobExecution.getId());
} catch (Exception e) {
ourLog.error("Couldn't stop job execution {}: {}", jobExecution.getId(), e);
}
for (String id : myJobExecutions) {
myJobCoordinator.cancelInstance(id);
}
myCurrentJobExecutions.clear();
myJobExecutions.clear();
}
@Override
public void notifyJobEnded(String theId) {
myJobExecutions.remove(theId);
}
private <T> T runInTransaction(Supplier<T> theRunnable) {
assert !TransactionSynchronizationManager.isActualTransactionActive();
@ -298,7 +281,6 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
}
for (int i = 0; i < 10; i++) {
if (!isDeferredConcepts() &&
!isConceptLinksToSaveLater() &&
!isDeferredValueSets() &&
@ -348,7 +330,6 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
return !myDeferredCodeSystemVersionsDeletions.isEmpty();
}
private void processDeferredCodeSystemDeletions() {
for (TermCodeSystem next : myDeferredCodeSystemsDeletions) {
deleteTermCodeSystemOffline(next.getPid());
@ -366,36 +347,25 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
private void deleteTermCodeSystemVersionOffline(Long theCodeSystemVersionPid) {
JobParameters jobParameters = new JobParameters(
Collections.singletonMap(
JOB_PARAM_CODE_SYSTEM_VERSION_ID, new JobParameter(theCodeSystemVersionPid, true)));
JobInstanceStartRequest request = new JobInstanceStartRequest();
request.setJobDefinitionId(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
try {
JobExecution jobExecution = myJobSubmitter.runJob(myTermCodeSystemVersionDeleteJob, jobParameters);
myCurrentJobExecutions.add(jobExecution);
} catch (JobParametersInvalidException theE) {
throw new InternalErrorException(Msg.code(850) + "Offline job submission for TermCodeSystemVersion: " +
theCodeSystemVersionPid + " failed: " + theE);
}
TermCodeSystemDeleteVersionJobParameters parameters = new TermCodeSystemDeleteVersionJobParameters();
parameters.setCodeSystemVersionPid(theCodeSystemVersionPid);
request.setParameters(parameters);
Batch2JobStartResponse response = myJobCoordinator.startInstance(request);
myJobExecutions.add(response.getJobId());
}
private void deleteTermCodeSystemOffline(Long theCodeSystemPid) {
JobParameters jobParameters = new JobParameters(
Collections.singletonMap(
JOB_PARAM_CODE_SYSTEM_ID, new JobParameter(theCodeSystemPid, true)));
try {
JobExecution jobExecution = myJobSubmitter.runJob(myTermCodeSystemDeleteJob, jobParameters);
myCurrentJobExecutions.add(jobExecution);
} catch (JobParametersInvalidException theE) {
throw new InternalErrorException(Msg.code(851) + "Offline job submission for TermCodeSystem: " +
theCodeSystemPid + " failed: " + theE);
}
TermCodeSystemDeleteJobParameters parameters = new TermCodeSystemDeleteJobParameters();
parameters.setTermPid(theCodeSystemPid);
JobInstanceStartRequest request = new JobInstanceStartRequest();
request.setParameters(parameters);
request.setJobDefinitionId(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
Batch2JobStartResponse response = myJobCoordinator.startInstance(request);
myJobExecutions.add(response.getJobId());
}
@ -412,9 +382,30 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
}
private boolean isJobsExecuting() {
return myCurrentJobExecutions.stream().anyMatch(JobExecution::isRunning);
cleanseEndedJobs();
return !myJobExecutions.isEmpty();
}
private void cleanseEndedJobs() {
/*
* Cleanse the list of completed jobs.
* This is mostly a fail-safe
* because "cancelled" jobs are never removed.
*/
List<String> executions = new ArrayList<>(myJobExecutions);
List<String> idsToDelete = new ArrayList<>();
for (String id : executions) {
// TODO - might want to consider a "fetch all instances"
JobInstance instance = myJobCoordinator.getInstance(id);
if (StatusEnum.getEndedStatuses().contains(instance.getStatus())) {
idsToDelete.add(instance.getInstanceId());
}
}
for (String id : idsToDelete) {
myJobExecutions.remove(id);
}
}
private void saveConceptLink(TermConceptParentChildLink next) {
if (next.getId() == null) {
@ -459,6 +450,7 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
jobDefinition.setId(Job.class.getName());
jobDefinition.setJobClass(Job.class);
mySchedulerService.scheduleLocalJob(5000, jobDefinition);
}
@VisibleForTesting

View File

@ -57,11 +57,12 @@ public interface ITermDeferredStorageSvc {
void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion);
void notifyJobEnded(String theId);
/**
* This is mostly here for unit tests - Saves any and all deferred concepts and links
*/
void saveAllDeferred();
void logQueueForUnitTest();
}

View File

@ -0,0 +1,137 @@
package ca.uhn.fhir.jpa.term.api;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDesignationDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptParentChildLinkDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptPropertyDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.term.models.CodeSystemConceptsDeleteResult;
import com.fasterxml.jackson.databind.util.ArrayIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.text.DecimalFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
@Transactional
public class TermCodeSystemDeleteJobSvc implements ITermCodeSystemDeleteJobSvc {
private static final Logger ourLog = LoggerFactory.getLogger(TermCodeSystemDeleteJobSvc.class);
private static final DecimalFormat ourDecimalFormat = new DecimalFormat("#,###");
@Autowired
private ITermConceptDao myConceptDao;
@Autowired
private ITermCodeSystemDao myCodeSystemDao;
@Autowired
private ITermCodeSystemVersionDao myTermCodeSystemVersionDao;
@Autowired
private ITermConceptParentChildLinkDao myConceptParentChildLinkDao;
@Autowired
private ITermConceptPropertyDao myConceptPropertyDao;
@Autowired
private ITermConceptDesignationDao myConceptDesignationDao;
@Autowired
private ITermCodeSystemDao myTermCodeSystemDao;
@Autowired
private ITermDeferredStorageSvc myDeferredStorageSvc;
@Override
public Iterator<Long> getAllCodeSystemVersionForCodeSystemPid(long thePid) {
// TODO - make this a pageable iterator
List<Long> pids = myTermCodeSystemVersionDao.findSortedPidsByCodeSystemPid(thePid);
if (pids == null) {
return new ArrayIterator<>(new Long[0]);
}
return pids.iterator();
}
@Override
public CodeSystemConceptsDeleteResult deleteCodeSystemConceptsByCodeSystemVersionPid(long theCodeSystemVersionPid) {
CodeSystemConceptsDeleteResult result = new CodeSystemConceptsDeleteResult();
// code system links delete
ourLog.info("Deleting term code links");
int deletedLinks = myConceptParentChildLinkDao.deleteByCodeSystemVersion(theCodeSystemVersionPid);
ourLog.info("Deleted {} term code links", ourDecimalFormat.format(deletedLinks));
result.setDeletedLinks(deletedLinks);
// code system concept properties
ourLog.info("Deleting term code properties");
int deletedProperties = myConceptPropertyDao.deleteByCodeSystemVersion(theCodeSystemVersionPid);
ourLog.info("Deleted {} term code properties", ourDecimalFormat.format(deletedProperties));
result.setDeletedProperties(deletedProperties);
// code system concept designations
ourLog.info("Deleting concept designations");
int deletedDesignations = myConceptDesignationDao.deleteByCodeSystemVersion(theCodeSystemVersionPid);
ourLog.info("Deleted {} concept designations", ourDecimalFormat.format(deletedDesignations));
result.setDeletedDesignations(deletedDesignations);
// code system concept
ourLog.info("Deleting concepts");
int deletedConcepts = myConceptDao.deleteByCodeSystemVersion(theCodeSystemVersionPid);
ourLog.info("Deleted {} concepts", ourDecimalFormat.format(deletedConcepts));
result.setCodeSystemConceptDelete(deletedConcepts);
return result;
}
@Override
public void deleteCodeSystemVersion(long theVersionPid) {
ourLog.debug("Executing for codeSystemVersionId: {}", theVersionPid);
// if TermCodeSystemVersion being deleted is current, disconnect it form TermCodeSystem
Optional<TermCodeSystem> codeSystemOpt = myCodeSystemDao.findWithCodeSystemVersionAsCurrentVersion(theVersionPid);
if (codeSystemOpt.isPresent()) {
TermCodeSystem codeSystem = codeSystemOpt.get();
ourLog.info("Removing code system version: {} as current version of code system: {}", theVersionPid, codeSystem.getPid());
codeSystem.setCurrentVersion(null);
myCodeSystemDao.save(codeSystem);
}
ourLog.info("Deleting code system version: {}", theVersionPid);
Optional<TermCodeSystemVersion> csv = myTermCodeSystemVersionDao.findById(theVersionPid);
csv.ifPresent(theTermCodeSystemVersion -> {
myTermCodeSystemVersionDao.delete(theTermCodeSystemVersion);
ourLog.info("Code system version: {} deleted", theVersionPid);
});
}
@Override
public void deleteCodeSystem(long thePid) {
ourLog.info("Deleting code system by id : {}", thePid);
Optional<TermCodeSystem> csop = myTermCodeSystemDao.findById(thePid);
if (csop.isPresent()) {
TermCodeSystem cs = csop.get();
ourLog.info("Deleting code system {} / {}", thePid, cs.getCodeSystemUri());
myTermCodeSystemDao.deleteById(thePid);
ourLog.info("Code system {} deleted", thePid);
}
}
@Override
public void notifyJobComplete(String theJobId) {
myDeferredStorageSvc.notifyJobEnded(theJobId);
}
}

View File

@ -0,0 +1,28 @@
package ca.uhn.fhir.jpa.term.config;
import ca.uhn.fhir.jpa.term.TermConceptDaoSvc;
import ca.uhn.fhir.jpa.term.TermDeferredStorageSvcImpl;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.TermCodeSystemDeleteJobSvc;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TermCodeSystemConfig {
@Bean
public ITermCodeSystemDeleteJobSvc termCodeSystemService() {
return new TermCodeSystemDeleteJobSvc();
}
@Bean
public ITermDeferredStorageSvc termDeferredStorageSvc() {
return new TermDeferredStorageSvcImpl();
}
@Bean
public TermConceptDaoSvc termConceptDaoSvc() {
return new TermConceptDaoSvc();
}
}

View File

@ -1,62 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration artifacts common to TermCodeSystemDeleteJobConfig and TermCodeSystemVersionDeleteJobConfig
**/
@Configuration
public class BaseTermCodeSystemDeleteJobConfig {
protected static final int TERM_CONCEPT_DELETE_TIMEOUT = 60 * 2; // two minutes
@Autowired
protected JobBuilderFactory myJobBuilderFactory;
@Autowired
protected StepBuilderFactory myStepBuilderFactory;
@Bean
public BatchTermCodeSystemVersionDeleteWriter batchTermCodeSystemVersionDeleteWriter() {
return new BatchTermCodeSystemVersionDeleteWriter();
}
@Bean
public BatchConceptRelationsDeleteWriter batchConceptRelationsDeleteWriter() {
return new BatchConceptRelationsDeleteWriter();
}
@Bean
public BatchTermConceptsDeleteWriter batchTermConceptsDeleteWriter() {
return new BatchTermConceptsDeleteWriter();
}
}

View File

@ -1,66 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.dao.data.ITermConceptDesignationDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptParentChildLinkDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptPropertyDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import java.text.DecimalFormat;
import java.util.List;
public class BatchConceptRelationsDeleteWriter implements ItemWriter<Long> {
private static final Logger ourLog = LoggerFactory.getLogger(BatchConceptRelationsDeleteWriter.class);
private static final DecimalFormat ourDecimalFormat = new DecimalFormat("#,###");
@Autowired
private ITermConceptParentChildLinkDao myConceptParentChildLinkDao;
@Autowired
private ITermConceptPropertyDao myConceptPropertyDao;
@Autowired
private ITermConceptDesignationDao myConceptDesignationDao;
@Override
public void write(List<? extends Long> theTermCodeSystemVersionPidList) throws Exception {
// receives input in chunks of size one
long codeSystemVersionId = theTermCodeSystemVersionPidList.get(0);
ourLog.info("Deleting term code links");
int deletedLinks = myConceptParentChildLinkDao.deleteByCodeSystemVersion(codeSystemVersionId);
ourLog.info("Deleted {} term code links", ourDecimalFormat.format(deletedLinks));
ourLog.info("Deleting term code properties");
int deletedProperties = myConceptPropertyDao.deleteByCodeSystemVersion(codeSystemVersionId);
ourLog.info("Deleted {} term code properties", ourDecimalFormat.format(deletedProperties));
ourLog.info("Deleting concept designations");
int deletedDesignations = myConceptDesignationDao.deleteByCodeSystemVersion(codeSystemVersionId);
ourLog.info("Deleted {} concept designations", ourDecimalFormat.format(deletedDesignations));
}
}

View File

@ -1,54 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Value;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_VERSION_ID;
/**
* This reader works as a pass-through by passing the received parameter once to the writer,
* in order to share the writer functionality between two jobs
*/
public class BatchTermCodeSystemUniqueVersionDeleteReader implements ItemReader<Long> {
private static final Logger ourLog = LoggerFactory.getLogger(BatchTermCodeSystemUniqueVersionDeleteReader.class);
@Value("#{jobParameters['" + JOB_PARAM_CODE_SYSTEM_VERSION_ID + "']}")
private Long myTermCodeSystemVersionPid;
// indicates if the parameter was already passed once to the writer, which indicates end of task
private boolean myParameterPassed;
@Override
public Long read() throws Exception {
if ( ! myParameterPassed) {
myParameterPassed = true;
return myTermCodeSystemVersionPid;
}
return null;
}
}

View File

@ -1,75 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import java.util.List;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_ID;
/**
*
*/
public class BatchTermCodeSystemVersionDeleteReader implements ItemReader<Long> {
private static final Logger ourLog = LoggerFactory.getLogger(BatchTermCodeSystemVersionDeleteReader.class);
@Autowired
private ITermCodeSystemVersionDao myTermCodeSystemVersionDao;
@Value("#{jobParameters['" + JOB_PARAM_CODE_SYSTEM_ID + "']}")
private Long myTermCodeSystemPid;
private List<Long> myTermCodeSystemVersionPidList;
private int myCurrentIdx = 0;
@Override
public Long read() throws Exception {
if (myTermCodeSystemVersionPidList == null) {
myTermCodeSystemVersionPidList = myTermCodeSystemVersionDao.findSortedPidsByCodeSystemPid(myTermCodeSystemPid);
}
if (myTermCodeSystemVersionPidList.isEmpty()) {
// nothing to process
ourLog.info("Nothing to process");
return null;
}
if (myCurrentIdx >= myTermCodeSystemVersionPidList.size()) {
// nothing else to process
ourLog.info("No more versions to process");
return null;
}
// still processing elements
long TermCodeSystemVersionPid = myTermCodeSystemVersionPidList.get(myCurrentIdx++);
ourLog.info("Passing termCodeSystemVersionPid: {} to writer", TermCodeSystemVersionPid);
return TermCodeSystemVersionPid;
}
}

View File

@ -1,72 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
@Component
public class BatchTermCodeSystemVersionDeleteWriter implements ItemWriter<Long> {
private static final Logger ourLog = LoggerFactory.getLogger(BatchTermCodeSystemVersionDeleteWriter.class);
@Autowired
private ITermCodeSystemDao myCodeSystemDao;
@Autowired
private ITermCodeSystemVersionDao myTermCodeSystemVersionDao;
@Override
public void write(List<? extends Long> theTermCodeSystemVersionPidList) throws Exception {
// receives input in chunks of size one
long codeSystemVersionId = theTermCodeSystemVersionPidList.get(0);
ourLog.debug("Executing for codeSystemVersionId: {}", codeSystemVersionId);
// if TermCodeSystemVersion being deleted is current, disconnect it form TermCodeSystem
Optional<TermCodeSystem> codeSystemOpt = myCodeSystemDao.findWithCodeSystemVersionAsCurrentVersion(codeSystemVersionId);
if (codeSystemOpt.isPresent()) {
TermCodeSystem codeSystem = codeSystemOpt.get();
ourLog.info("Removing code system version: {} as current version of code system: {}", codeSystemVersionId, codeSystem.getPid());
codeSystem.setCurrentVersion(null);
myCodeSystemDao.save(codeSystem);
}
ourLog.info("Deleting code system version: {}", codeSystemVersionId);
Optional<TermCodeSystemVersion> csv = myTermCodeSystemVersionDao.findById(codeSystemVersionId);
csv.ifPresent(theTermCodeSystemVersion -> {
myTermCodeSystemVersionDao.delete(theTermCodeSystemVersion);
ourLog.info("Code system version: {} deleted", codeSystemVersionId);
});
}
}

View File

@ -1,51 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import java.text.DecimalFormat;
import java.util.List;
public class BatchTermConceptsDeleteWriter implements ItemWriter<Long> {
private static final Logger ourLog = LoggerFactory.getLogger(BatchTermConceptsDeleteWriter.class);
private static final DecimalFormat ourDecimalFormat = new DecimalFormat("#,###");
@Autowired
private ITermConceptDao myConceptDao;
@Override
public void write(List<? extends Long> theTermCodeSystemVersionPidList) throws Exception {
// receives input in chunks of size one
long codeSystemVersionId = theTermCodeSystemVersionPidList.get(0);
ourLog.info("Deleting concepts");
int deletedConcepts = myConceptDao.deleteByCodeSystemVersion(codeSystemVersionId);
ourLog.info("Deleted {} concepts", ourDecimalFormat.format(deletedConcepts));
}
}

View File

@ -1,122 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParametersValidator;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_DELETE_JOB_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_DELETE_STEP_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_VERSION_DELETE_STEP_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CONCEPTS_DELETE_STEP_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CONCEPT_RELATIONS_DELETE_STEP_NAME;
/**
* Configuration for batch job which deletes a TermCodeSystem and its related TermCodeSystemVersion(s),
* TermConceptProperty(es), TermConceptDesignation(s), and TermConceptParentChildLink(s)
**/
@Configuration
public class TermCodeSystemDeleteJobConfig extends BaseTermCodeSystemDeleteJobConfig {
@Bean(name = TERM_CODE_SYSTEM_DELETE_JOB_NAME)
@Lazy
public Job termCodeSystemDeleteJob() {
return myJobBuilderFactory.get(TERM_CODE_SYSTEM_DELETE_JOB_NAME)
.validator(termCodeSystemDeleteJobParameterValidator())
.start(termConceptRelationsDeleteStep())
.next(termConceptsDeleteStep())
.next(termCodeSystemVersionDeleteStep())
.next(termCodeSystemDeleteStep())
.build();
}
@Bean
public JobParametersValidator termCodeSystemDeleteJobParameterValidator() {
return new TermCodeSystemDeleteJobParameterValidator();
}
/**
* This steps deletes TermConceptParentChildLink(s), TermConceptProperty(es) and TermConceptDesignation(s)
* related to TermConcept(s) of the TermCodeSystemVersion being deleted
*/
@Bean(name = TERM_CONCEPT_RELATIONS_DELETE_STEP_NAME)
public Step termConceptRelationsDeleteStep() {
return myStepBuilderFactory.get(TERM_CONCEPT_RELATIONS_DELETE_STEP_NAME)
.<Long, Long>chunk(1)
.reader(batchTermCodeSystemVersionDeleteReader())
.writer(batchConceptRelationsDeleteWriter())
.build();
}
/**
* This steps deletes TermConcept(s) of the TermCodeSystemVersion being deleted
*/
@Bean(name = TERM_CONCEPTS_DELETE_STEP_NAME)
public Step termConceptsDeleteStep() {
DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
attribute.setTimeout(TERM_CONCEPT_DELETE_TIMEOUT);
return myStepBuilderFactory.get(TERM_CONCEPTS_DELETE_STEP_NAME)
.<Long, Long>chunk(1)
.reader(batchTermCodeSystemVersionDeleteReader())
.writer(batchTermConceptsDeleteWriter())
.transactionAttribute(attribute)
.build();
}
/**
* This steps deletes the TermCodeSystemVersion
*/
@Bean(name = TERM_CODE_SYSTEM_VERSION_DELETE_STEP_NAME)
public Step termCodeSystemVersionDeleteStep() {
return myStepBuilderFactory.get(TERM_CODE_SYSTEM_VERSION_DELETE_STEP_NAME)
.<Long, Long>chunk(1)
.reader(batchTermCodeSystemVersionDeleteReader())
.writer(batchTermCodeSystemVersionDeleteWriter())
.build();
}
@Bean(name = TERM_CODE_SYSTEM_DELETE_STEP_NAME)
public Step termCodeSystemDeleteStep() {
return myStepBuilderFactory.get(TERM_CODE_SYSTEM_DELETE_STEP_NAME)
.tasklet(termCodeSystemDeleteTasklet())
.build();
}
@Bean
@StepScope
public BatchTermCodeSystemVersionDeleteReader batchTermCodeSystemVersionDeleteReader() {
return new BatchTermCodeSystemVersionDeleteReader();
}
@Bean
public TermCodeSystemDeleteTasklet termCodeSystemDeleteTasklet() {
return new TermCodeSystemDeleteTasklet();
}
}

View File

@ -1,54 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.JobParametersValidator;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_ID;
/**
* Validates that a TermCodeSystem parameter is present
*/
public class TermCodeSystemDeleteJobParameterValidator implements JobParametersValidator {
@Override
public void validate(JobParameters theJobParameters) throws JobParametersInvalidException {
if (theJobParameters == null) {
throw new JobParametersInvalidException(Msg.code(922) + "This job needs Parameter: '" + JOB_PARAM_CODE_SYSTEM_ID + "'");
}
if ( ! theJobParameters.getParameters().containsKey(JOB_PARAM_CODE_SYSTEM_ID)) {
throw new JobParametersInvalidException(Msg.code(923) + "This job needs Parameter: '" + JOB_PARAM_CODE_SYSTEM_ID + "'");
}
Long termCodeSystemPid = theJobParameters.getLong(JOB_PARAM_CODE_SYSTEM_ID);
if (termCodeSystemPid == null) {
throw new JobParametersInvalidException(Msg.code(924) + "'" + JOB_PARAM_CODE_SYSTEM_ID + "' parameter is null");
}
if (termCodeSystemPid <= 0) {
throw new JobParametersInvalidException(Msg.code(925) + "Invalid parameter '" + JOB_PARAM_CODE_SYSTEM_ID + "' value: " + termCodeSystemPid);
}
}
}

View File

@ -1,58 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Nonnull;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_ID;
@Component
public class TermCodeSystemDeleteTasklet implements Tasklet {
private static final Logger ourLog = LoggerFactory.getLogger(TermCodeSystemDeleteTasklet.class);
@Autowired
private ITermCodeSystemDao myTermCodeSystemDao;
@Override
public RepeatStatus execute(@Nonnull StepContribution contribution, ChunkContext context) throws Exception {
long codeSystemPid = (Long) context.getStepContext().getJobParameters().get(JOB_PARAM_CODE_SYSTEM_ID);
TermCodeSystem cs = myTermCodeSystemDao.findById(codeSystemPid).orElseThrow(IllegalStateException::new);
ourLog.info("Deleting code system {} / {}", codeSystemPid, cs.getCodeSystemUri());
myTermCodeSystemDao.deleteById(codeSystemPid);
ourLog.info("Code system {} deleted", codeSystemPid);
return RepeatStatus.FINISHED;
}
}

View File

@ -1,105 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParametersValidator;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_UNIQUE_VERSION_DELETE_STEP_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CONCEPTS_UNIQUE_VERSION_DELETE_STEP_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CONCEPT_RELATIONS_UNIQUE_VERSION_DELETE_STEP_NAME;
/**
* Configuration for batch job which deletes a specific TermCodeSystemVersion and its related,
* TermConceptProperty(es), TermConceptDesignation(s), and TermConceptParentChildLink(s)
**/
@Configuration
public class TermCodeSystemVersionDeleteJobConfig extends BaseTermCodeSystemDeleteJobConfig {
@Bean(name = TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME)
@Lazy
public Job termCodeSystemVersionDeleteJob() {
return myJobBuilderFactory.get(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME)
.validator(termCodeSystemVersionDeleteJobParameterValidator())
.start(termConceptRelationsUniqueVersionDeleteStep())
.next(termConceptsUniqueVersionDeleteStep())
.next(termCodeSystemUniqueVersionDeleteStep())
.build();
}
@Bean
public JobParametersValidator termCodeSystemVersionDeleteJobParameterValidator() {
return new TermCodeSystemVersionDeleteJobParameterValidator();
}
@Bean(name = TERM_CONCEPT_RELATIONS_UNIQUE_VERSION_DELETE_STEP_NAME)
public Step termConceptRelationsUniqueVersionDeleteStep() {
return myStepBuilderFactory.get(TERM_CONCEPT_RELATIONS_UNIQUE_VERSION_DELETE_STEP_NAME)
.<Long, Long>chunk(1)
.reader(batchTermCodeSystemUniqueVersionDeleteReader())
.writer(batchConceptRelationsDeleteWriter())
.build();
}
@Bean(name = TERM_CONCEPTS_UNIQUE_VERSION_DELETE_STEP_NAME)
public Step termConceptsUniqueVersionDeleteStep() {
DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
attribute.setTimeout(TERM_CONCEPT_DELETE_TIMEOUT);
return myStepBuilderFactory.get(TERM_CONCEPTS_UNIQUE_VERSION_DELETE_STEP_NAME)
.<Long, Long>chunk(1)
.reader(batchTermCodeSystemUniqueVersionDeleteReader())
.writer(batchTermConceptsDeleteWriter())
.transactionAttribute(attribute)
.build();
}
@Bean(name = TERM_CODE_SYSTEM_UNIQUE_VERSION_DELETE_STEP_NAME)
public Step termCodeSystemUniqueVersionDeleteStep() {
return myStepBuilderFactory.get(TERM_CODE_SYSTEM_UNIQUE_VERSION_DELETE_STEP_NAME)
.<Long, Long>chunk(1)
.reader(batchTermCodeSystemUniqueVersionDeleteReader())
.writer(batchTermCodeSystemVersionDeleteWriter())
.build();
}
@Bean
@StepScope
public BatchTermCodeSystemUniqueVersionDeleteReader batchTermCodeSystemUniqueVersionDeleteReader() {
return new BatchTermCodeSystemUniqueVersionDeleteReader();
}
}

View File

@ -1,54 +0,0 @@
package ca.uhn.fhir.jpa.term.job;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.JobParametersValidator;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_VERSION_ID;
/**
* Validates that a TermCodeSystem parameter is present
*/
public class TermCodeSystemVersionDeleteJobParameterValidator implements JobParametersValidator {
@Override
public void validate(JobParameters theJobParameters) throws JobParametersInvalidException {
if (theJobParameters == null) {
throw new JobParametersInvalidException(Msg.code(918) + "This job needs Parameter: '" + JOB_PARAM_CODE_SYSTEM_VERSION_ID + "'");
}
if ( ! theJobParameters.getParameters().containsKey(JOB_PARAM_CODE_SYSTEM_VERSION_ID)) {
throw new JobParametersInvalidException(Msg.code(919) + "This job needs Parameter: '" + JOB_PARAM_CODE_SYSTEM_VERSION_ID + "'");
}
Long termCodeSystemPid = theJobParameters.getLong(JOB_PARAM_CODE_SYSTEM_VERSION_ID);
if (termCodeSystemPid == null) {
throw new JobParametersInvalidException(Msg.code(920) + "'" + JOB_PARAM_CODE_SYSTEM_VERSION_ID + "' parameter is null");
}
if (termCodeSystemPid <= 0) {
throw new JobParametersInvalidException(Msg.code(921) + "Invalid parameter '" + JOB_PARAM_CODE_SYSTEM_VERSION_ID + "' value: " + termCodeSystemPid);
}
}
}

View File

@ -30,7 +30,10 @@ import org.hamcrest.Matchers;
import org.springframework.beans.factory.annotation.Autowired;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -41,6 +44,8 @@ import static org.junit.jupiter.api.Assertions.fail;
public class Batch2JobHelper {
private static final int BATCH_SIZE = 100;
@Autowired
private IJobMaintenanceService myJobMaintenanceService;
@ -52,7 +57,8 @@ public class Batch2JobHelper {
}
public JobInstance awaitJobCompletion(String theId) {
await().until(() -> {
await()
.until(() -> {
myJobMaintenanceService.runMaintenancePass();
return myJobCoordinator.getInstance(theId).getStatus();
}, equalTo(StatusEnum.COMPLETED));
@ -118,9 +124,13 @@ public class Batch2JobHelper {
}
// TODO KHS I don't think this works yet
public void awaitAllCompletions(String theJobDefinitionId) {
List<JobInstance> instances = myJobCoordinator.getInstancesbyJobDefinitionIdAndEndedStatus(theJobDefinitionId, false, 100, 0);
public void awaitAllJobsOfJobDefinitionIdToComplete(String theJobDefinitionId) {
// fetch all jobs of any status type
List<JobInstance> instances = myJobCoordinator.getJobInstancesByJobDefinitionId(
theJobDefinitionId,
BATCH_SIZE,
0);
// then await completion status
awaitJobCompletions(instances);
}

View File

@ -653,7 +653,7 @@ public class FhirResourceDaoDstu2SearchCustomSearchParamTest extends BaseJpaDstu
}
@Test
public void testSearchForExtensionTwoDeepDecimal() {
public void testSearchForExtensionTwoDeepDecimalDstu2() {
SearchParameter siblingSp = new SearchParameter();
siblingSp.setBase(ResourceTypeEnum.PATIENT);
siblingSp.setCode("foobar");

View File

@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
import ca.uhn.fhir.jpa.test.BaseJpaDstu3Test;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.Enumerations;
@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.fail;
public class FhirResourceDaoDstu3CodeSystemTest extends BaseJpaDstu3Test {
@Autowired private BatchJobHelper myBatchJobHelper;
@Autowired private Batch2JobHelper myBatchJobHelper;
@AfterAll
public static void afterClassClearContext() {
@ -72,7 +72,7 @@ public class FhirResourceDaoDstu3CodeSystemTest extends BaseJpaDstu3Test {
cs.addConcept().setCode("B");
myCodeSystemDao.update(cs, mySrd);
myTerminologyDeferredStorageSvc.saveAllDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
runInTransaction(()->{
assertEquals(2, myConceptDao.count());
});
@ -86,7 +86,7 @@ public class FhirResourceDaoDstu3CodeSystemTest extends BaseJpaDstu3Test {
cs.addConcept().setCode("C");
myCodeSystemDao.update(cs, mySrd);
myTerminologyDeferredStorageSvc.saveAllDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
runInTransaction(()->{
assertEquals(1, myConceptDao.count());
});
@ -96,7 +96,7 @@ public class FhirResourceDaoDstu3CodeSystemTest extends BaseJpaDstu3Test {
myCodeSystemDao.delete(id);
});
myTerminologyDeferredStorageSvc.saveDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
runInTransaction(()->{
assertEquals(0L, myConceptDao.count());
});

View File

@ -702,7 +702,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
}
@Test
public void testSearchForExtensionTwoDeepDecimal() {
public void testSearchForExtensionTwoDeepDecimalDstu3() {
SearchParameter siblingSp = new SearchParameter();
siblingSp.addBase("Patient");
siblingSp.setCode("foobar");

View File

@ -3,7 +3,7 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeSystem;
@ -23,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
public class FhirResourceDaoR4CodeSystemTest extends BaseJpaR4Test {
@Autowired private BatchJobHelper myBatchJobHelper;
@Autowired private Batch2JobHelper myBatchJobHelper;
@Test
public void testIndexContained() throws Exception {
@ -43,7 +43,6 @@ public class FhirResourceDaoR4CodeSystemTest extends BaseJpaR4Test {
@Test
public void testDeleteLargeCompleteCodeSystem() {
IIdType id = createLargeCodeSystem(null);
runInTransaction(() -> {
@ -65,7 +64,7 @@ public class FhirResourceDaoR4CodeSystemTest extends BaseJpaR4Test {
// Now the background scheduler will do its thing
myTerminologyDeferredStorageSvc.saveDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
runInTransaction(() -> {
assertEquals(0, myTermCodeSystemDao.count());
assertEquals(0, myTermCodeSystemVersionDao.count());
@ -124,7 +123,7 @@ public class FhirResourceDaoR4CodeSystemTest extends BaseJpaR4Test {
// Now the background scheduler will do its thing
myTerminologyDeferredStorageSvc.saveDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
// Entities for first resource should be gone now.
runInTransaction(() -> {
@ -159,7 +158,7 @@ public class FhirResourceDaoR4CodeSystemTest extends BaseJpaR4Test {
// Now the background scheduler will do its thing
myTerminologyDeferredStorageSvc.saveDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
// The remaining versions and Code System entities should be gone now.
runInTransaction(() -> {

View File

@ -1160,7 +1160,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
}
@Test
public void testSearchForExtensionTwoDeepDecimal() {
public void testSearchForExtensionTwoDeepDecimalR4() {
final SearchParameter siblingSp = new SearchParameter();
siblingSp.addBase("Patient");
siblingSp.setCode("foobar");

View File

@ -360,7 +360,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
myResourceReindexingSvc.markAllResourcesForReindexing();
myResourceReindexingSvc.forceReindexingPass();
myTerminologyDeferredStorageSvc.saveAllDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatch2JobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
runInTransaction(() -> {
assertEquals(3L, myTermConceptDao.count());

View File

@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.dao.r5;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.junit.jupiter.api.AfterAll;
@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
public class FhirResourceDaoR5CodeSystemTest extends BaseJpaR5Test {
@Autowired private BatchJobHelper myBatchJobHelper;
@Autowired private Batch2JobHelper myBatchJobHelper;
@Test
public void testDeleteLargeCompleteCodeSystem() {
@ -45,7 +45,7 @@ public class FhirResourceDaoR5CodeSystemTest extends BaseJpaR5Test {
// Now the background scheduler will do its thing
myTermDeferredStorageSvc.saveDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
runInTransaction(() -> {
assertEquals(0, myTermCodeSystemDao.count());
assertEquals(0, myTermCodeSystemVersionDao.count());
@ -104,7 +104,7 @@ public class FhirResourceDaoR5CodeSystemTest extends BaseJpaR5Test {
// Now the background scheduler will do its thing
myTermDeferredStorageSvc.saveDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
// Entities for first resource should be gone now.
runInTransaction(() -> {
@ -139,7 +139,7 @@ public class FhirResourceDaoR5CodeSystemTest extends BaseJpaR5Test {
// Now the background scheduler will do its thing
myTermDeferredStorageSvc.saveDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
// The remaining versions and Code System entities should be gone now.
runInTransaction(() -> {

View File

@ -4,9 +4,9 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoDstu3TerminologyTest;
import ca.uhn.fhir.jpa.term.TermReindexingSvcImpl;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeType;
@ -33,7 +33,8 @@ import static org.junit.jupiter.api.Assertions.fail;
public class ResourceProviderDstu3CodeSystemTest extends BaseResourceProviderDstu3Test {
@Autowired private BatchJobHelper myBatchJobHelper;
@Autowired
private Batch2JobHelper myBatchJobHelper;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu3CodeSystemTest.class);
public static FhirContext ourCtx = FhirContext.forDstu3Cached();
@ -139,13 +140,11 @@ public class ResourceProviderDstu3CodeSystemTest extends BaseResourceProviderDst
runInTransaction(() -> assertEquals(26L, myConceptDao.count()));
myTerminologyDeferredStorageSvc.saveDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
runInTransaction(() -> assertEquals(24L, myConceptDao.count()));
}
@Test
public void testLookupOperationByCodeAndSystemBuiltInCode() {
Parameters respParam = ourClient

View File

@ -1,12 +1,12 @@
package ca.uhn.fhir.jpa.term;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType;
import org.junit.jupiter.api.Test;
@ -23,7 +23,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
public static final String URL_MY_CODE_SYSTEM = "http://example.com/my_code_system";
@Autowired
private BatchJobHelper myBatchJobHelper;
private Batch2JobHelper myBatchJobHelper;
@Test
@ -134,7 +134,7 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
myTerminologyDeferredStorageSvc.setProcessDeferred(true);
myTerminologyDeferredStorageSvc.saveDeferred();
myTerminologyDeferredStorageSvc.setProcessDeferred(false);
myBatchJobHelper.awaitAllBulkJobCompletions(false, TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
assertEquals(theExpectedConceptCount, runInTransaction(() -> myTermConceptDao.count()));
}

View File

@ -1,5 +1,8 @@
package ca.uhn.fhir.jpa.term;
import ca.uhn.fhir.batch2.api.IJobCoordinator;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.StatusEnum;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
@ -8,18 +11,21 @@ import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.batch.core.JobExecution;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ -39,7 +45,10 @@ public class TermDeferredStorageSvcImplTest {
private ITermCodeSystemVersionDao myTermCodeSystemVersionDao;
@Mock
private JobExecution myJobExecution;
private IJobCoordinator myJobCoordinator;
@InjectMocks
private TermDeferredStorageSvcImpl mySvc;
@Test
public void testSaveDeferredWithExecutionSuspended() {
@ -51,12 +60,21 @@ public class TermDeferredStorageSvcImplTest {
@Test
public void testStorageNotEmptyWhileJobsExecuting() {
TermDeferredStorageSvcImpl svc = new TermDeferredStorageSvcImpl();
ReflectionTestUtils.setField(svc, "myCurrentJobExecutions", Collections.singletonList(myJobExecution));
String jobId = "jobId";
JobInstance instance = new JobInstance();
instance.setInstanceId(jobId);
instance.setStatus(StatusEnum.IN_PROGRESS);
when(myJobExecution.isRunning()).thenReturn(true, false);
assertFalse(svc.isStorageQueueEmpty());
assertTrue(svc.isStorageQueueEmpty());
ArrayList<String> mockExecutions = new ArrayList<>();
mockExecutions.add(jobId);
ReflectionTestUtils.setField(mySvc, "myJobExecutions", mockExecutions);
when(myJobCoordinator.getInstance(eq(jobId)))
.thenReturn(instance);
assertFalse(mySvc.isStorageQueueEmpty());
instance.setStatus(StatusEnum.COMPLETED);
assertTrue(mySvc.isStorageQueueEmpty());
}

View File

@ -4,18 +4,18 @@ import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
@ -137,7 +137,8 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
@Autowired @Qualifier(JpaConfig.JPA_VALIDATION_SUPPORT)
private IValidationSupport myJpaPersistedResourceValidationSupport;
@Autowired private BatchJobHelper myBatchJobHelper;
@Autowired
private Batch2JobHelper myBatchJobHelper;
private ZipCollectionBuilder myFiles;
@ -696,7 +697,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
String currentVer = "2.68";
uploadLoincCodeSystem(currentVer, true);
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
runCommonValidations(Lists.newArrayList(nonCurrentVer, currentVer));
@ -718,7 +719,7 @@ public class TerminologySvcImplCurrentVersionR4Test extends BaseJpaR4Test {
String lastCurrentVer = "2.69";
uploadLoincCodeSystem(lastCurrentVer, true);
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatchJobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
runCommonValidations(Lists.newArrayList(firstCurrentVer, noCurrentVer, lastCurrentVer));

View File

@ -8,8 +8,8 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeableConcept;
@ -44,7 +44,8 @@ import static org.junit.jupiter.api.Assertions.fail;
public class TerminologySvcImplR4Test extends BaseTermR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(TerminologySvcImplR4Test.class);
@Autowired private BatchJobHelper myBatchJobHelper;
@Autowired
private Batch2JobHelper myBatch2JobHelper;
ConceptValidationOptions optsNoGuess = new ConceptValidationOptions();
ConceptValidationOptions optsGuess = new ConceptValidationOptions().setInferSystem(true);
@ -395,6 +396,7 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
@Test
public void testUpdateCodeSystemUrlAndVersion() {
// create code system
CodeSystem codeSystem = new CodeSystem();
codeSystem.setUrl(CS_URL);
codeSystem.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
@ -423,7 +425,6 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
TermCodeSystem termCodeSystem = myTermCodeSystemDao.findByResourcePid(id.getIdPartAsLong());
assertEquals("1", termCodeSystem.getCurrentVersion().getCodeSystemVersionId());
});
codeSystem.setVersion("2");
@ -431,7 +432,7 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
IIdType id_v2 = myCodeSystemDao.update(codeSystem, mySrd).getId().toUnqualified();
myTerminologyDeferredStorageSvc.saveAllDeferred();
myBatchJobHelper.awaitAllBulkJobCompletions(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
myBatch2JobHelper.awaitAllJobsOfJobDefinitionIdToComplete(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
runInTransaction(() -> {
List<TermCodeSystemVersion> termCodeSystemVersions_updated = myTermCodeSystemVersionDao.findAll();

View File

@ -20,37 +20,32 @@ package ca.uhn.fhir.jpa.term.job;
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.batch2.api.IJobCoordinator;
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.UploadStatistics;
import ca.uhn.fhir.jpa.term.ZipCollectionBuilder;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import ca.uhn.fhir.util.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.ValueSet;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Properties;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_ID;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_DELETE_JOB_NAME;
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_DUPLICATE_FILE_DEFAULT;
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_FILE_DEFAULT;
@ -80,6 +75,7 @@ import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_XML_FIL
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@ -89,13 +85,14 @@ public class TermCodeSystemDeleteJobTest extends BaseJpaR4Test {
private final ServletRequestDetails myRequestDetails = new ServletRequestDetails();
private Properties uploadProperties;
@Autowired private TermLoaderSvcImpl myTermLoaderSvc;
@Autowired private IBatchJobSubmitter myJobSubmitter;
@Autowired private BatchJobHelper myBatchJobHelper;
@Autowired
private TermLoaderSvcImpl myTermLoaderSvc;
@Autowired @Qualifier(TERM_CODE_SYSTEM_DELETE_JOB_NAME)
private Job myTermCodeSystemDeleteJob;
@Autowired
private Batch2JobHelper myBatch2JobHelper;
@Autowired
private IJobCoordinator myJobCoordinator;
private void initMultipleVersionLoad() throws Exception {
File file = ResourceUtils.getFile("classpath:loinc-ver/" + LOINC_UPLOAD_PROPERTIES_FILE.getCode());
@ -125,16 +122,15 @@ public class TermCodeSystemDeleteJobTest extends BaseJpaR4Test {
assertEquals(162, myTermConceptDao.count());
});
JobParameters jobParameters = new JobParameters(
Collections.singletonMap(
JOB_PARAM_CODE_SYSTEM_ID, new JobParameter(termCodeSystemPidVect[0], true) ));
TermCodeSystemDeleteJobParameters parameters = new TermCodeSystemDeleteJobParameters();
parameters.setTermPid(termCodeSystemPidVect[0]);
JobInstanceStartRequest request = new JobInstanceStartRequest();
request.setJobDefinitionId(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
request.setParameters(JsonUtil.serialize(parameters));
Batch2JobStartResponse response = myJobCoordinator.startInstance(request);
JobExecution jobExecution = myJobSubmitter.runJob(myTermCodeSystemDeleteJob, jobParameters);
myBatchJobHelper.awaitJobCompletion(jobExecution);
assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());
myBatch2JobHelper.awaitJobCompletion(response);
runInTransaction(() -> {
assertEquals(0, myTermCodeSystemDao.count());
@ -145,44 +141,18 @@ public class TermCodeSystemDeleteJobTest extends BaseJpaR4Test {
}
@Test
public void runWithNoParameterFailsValidation() {
JobParametersInvalidException thrown = Assertions.assertThrows(
JobParametersInvalidException.class,
() -> myJobSubmitter.runJob(myTermCodeSystemDeleteJob, new JobParameters())
);
assertEquals(Msg.code(923) + "This job needs Parameter: '" + JOB_PARAM_CODE_SYSTEM_ID + "'", thrown.getMessage());
}
@Test
public void runWithNullParameterFailsValidation() {
JobParameters jobParameters = new JobParameters(
Collections.singletonMap(
JOB_PARAM_CODE_SYSTEM_ID, new JobParameter((Long) null, true) ));
JobParametersInvalidException thrown = Assertions.assertThrows(
JobParametersInvalidException.class,
() -> myJobSubmitter.runJob(myTermCodeSystemDeleteJob, jobParameters)
);
assertEquals(Msg.code(924) + "'" + JOB_PARAM_CODE_SYSTEM_ID + "' parameter is null", thrown.getMessage());
}
@Test
public void runWithParameterZeroFailsValidation() {
JobParameters jobParameters = new JobParameters(
Collections.singletonMap(
JOB_PARAM_CODE_SYSTEM_ID, new JobParameter(0L, true) ));
JobInstanceStartRequest request = new JobInstanceStartRequest();
request.setJobDefinitionId(TERM_CODE_SYSTEM_DELETE_JOB_NAME);
request.setParameters(new TermCodeSystemDeleteJobParameters()); // no pid
JobParametersInvalidException thrown = Assertions.assertThrows(
JobParametersInvalidException.class,
() -> myJobSubmitter.runJob(myTermCodeSystemDeleteJob, jobParameters)
);
assertEquals(Msg.code(925) + "Invalid parameter '" + JOB_PARAM_CODE_SYSTEM_ID + "' value: 0", thrown.getMessage());
InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
myJobCoordinator.startInstance(request);
});
assertTrue(exception.getMessage().contains("Invalid Term Code System PID 0"), exception.getMessage());
}
private IIdType uploadLoincCodeSystem(String theVersion, boolean theMakeItCurrent) throws Exception {
ZipCollectionBuilder files = new ZipCollectionBuilder();
@ -261,7 +231,4 @@ public class TermCodeSystemDeleteJobTest extends BaseJpaR4Test {
fail("Setup failed. Unexpected version: " + theVersion);
return null;
}
}

View File

@ -20,38 +20,34 @@ package ca.uhn.fhir.jpa.term.job;
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.batch2.api.IJobCoordinator;
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.batch.api.IBatchJobSubmitter;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.UploadStatistics;
import ca.uhn.fhir.jpa.term.ZipCollectionBuilder;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteVersionJobParameters;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.jpa.test.Batch2JobHelper;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.test.utilities.BatchJobHelper;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.ValueSet;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Properties;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.JOB_PARAM_CODE_SYSTEM_VERSION_ID;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME;
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_DUPLICATE_FILE_DEFAULT;
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_FILE_DEFAULT;
@ -89,13 +85,12 @@ public class TermCodeSystemVersionDeleteJobTest extends BaseJpaR4Test {
private final ServletRequestDetails myRequestDetails = new ServletRequestDetails();
private Properties uploadProperties;
@Autowired private TermLoaderSvcImpl myTermLoaderSvc;
@Autowired private IBatchJobSubmitter myJobSubmitter;
@Autowired private BatchJobHelper myBatchJobHelper;
@Autowired @Qualifier(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME)
private Job myTermCodeSystemVersionDeleteJob;
@Autowired
private TermLoaderSvcImpl myTermLoaderSvc;
@Autowired
private Batch2JobHelper myBatchJobHelper;
@Autowired
private IJobCoordinator myJobCoordinator;
private void initMultipleVersionLoad() throws Exception {
File file = ResourceUtils.getFile("classpath:loinc-ver/" + LOINC_UPLOAD_PROPERTIES_FILE.getCode());
@ -127,16 +122,17 @@ public class TermCodeSystemVersionDeleteJobTest extends BaseJpaR4Test {
assertEquals(81 * 2, myTermConceptDao.count());
});
TermCodeSystemDeleteVersionJobParameters jobParameters = new TermCodeSystemDeleteVersionJobParameters();
jobParameters.setCodeSystemVersionPid(termCodeSystemVersionPidVect[0]);
JobParameters jobParameters = new JobParameters(Collections.singletonMap(
JOB_PARAM_CODE_SYSTEM_VERSION_ID, new JobParameter(termCodeSystemVersionPidVect[0], true) ));
JobInstanceStartRequest request = new JobInstanceStartRequest();
request.setJobDefinitionId(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
request.setParameters(jobParameters);
Batch2JobStartResponse response = myJobCoordinator.startInstance(request);
JobExecution jobExecution = myJobSubmitter.runJob(myTermCodeSystemVersionDeleteJob, jobParameters);
myBatchJobHelper.awaitJobCompletion(jobExecution);
assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());
JobInstance instance = myBatchJobHelper.awaitJobCompletion(response);
assertEquals("COMPLETED", instance.getStatus().name());
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
@ -147,47 +143,25 @@ public class TermCodeSystemVersionDeleteJobTest extends BaseJpaR4Test {
}
@Test
public void runWithNoParameterFailsValidation() {
JobParametersInvalidException thrown = Assertions.assertThrows(
JobParametersInvalidException.class,
() -> myJobSubmitter.runJob(myTermCodeSystemVersionDeleteJob, new JobParameters())
);
assertEquals(Msg.code(919) + "This job needs Parameter: '" + JOB_PARAM_CODE_SYSTEM_VERSION_ID + "'", thrown.getMessage());
}
@Test
public void runWithNullParameterFailsValidation() {
JobParameters jobParameters = new JobParameters(
Collections.singletonMap(
JOB_PARAM_CODE_SYSTEM_VERSION_ID, new JobParameter((Long) null, true) ));
JobParametersInvalidException thrown = Assertions.assertThrows(
JobParametersInvalidException.class,
() -> myJobSubmitter.runJob(myTermCodeSystemVersionDeleteJob, jobParameters)
);
assertEquals(Msg.code(920) + "'" + JOB_PARAM_CODE_SYSTEM_VERSION_ID + "' parameter is null", thrown.getMessage());
}
@Test
public void runWithParameterZeroFailsValidation() {
JobParameters jobParameters = new JobParameters(
Collections.singletonMap(
JOB_PARAM_CODE_SYSTEM_VERSION_ID, new JobParameter(0L, true) ));
InvalidRequestException thrown = Assertions.assertThrows(
InvalidRequestException.class,
() -> {
TermCodeSystemDeleteVersionJobParameters jobParameters = new TermCodeSystemDeleteVersionJobParameters();
jobParameters.setCodeSystemVersionPid(0);
JobParametersInvalidException thrown = Assertions.assertThrows(
JobParametersInvalidException.class,
() -> myJobSubmitter.runJob(myTermCodeSystemVersionDeleteJob, jobParameters)
JobInstanceStartRequest request = new JobInstanceStartRequest();
request.setJobDefinitionId(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME);
request.setParameters(jobParameters);
Batch2JobStartResponse response = myJobCoordinator.startInstance(request);
}
);
assertEquals(Msg.code(921) + "Invalid parameter '" + JOB_PARAM_CODE_SYSTEM_VERSION_ID + "' value: 0", thrown.getMessage());
assertTrue(thrown.getMessage().contains("Invalid code system version PID 0"));
}
private IIdType uploadLoincCodeSystem(String theVersion, boolean theMakeItCurrent) throws Exception {
ZipCollectionBuilder files = new ZipCollectionBuilder();

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.batch2.jobs.export.BulkExportAppCtx;
import ca.uhn.fhir.batch2.jobs.expunge.DeleteExpungeAppCtx;
import ca.uhn.fhir.batch2.jobs.imprt.BulkImportAppCtx;
import ca.uhn.fhir.batch2.jobs.reindex.ReindexAppCtx;
import ca.uhn.fhir.batch2.jobs.termcodesystem.TermCodeSystemJobConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -34,7 +35,8 @@ import org.springframework.context.annotation.Import;
BulkImportAppCtx.class,
ReindexAppCtx.class,
DeleteExpungeAppCtx.class,
BulkExportAppCtx.class
BulkExportAppCtx.class,
TermCodeSystemJobConfig.class
})
public class Batch2JobsConfig {
}

View File

@ -0,0 +1,158 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem;
import ca.uhn.fhir.batch2.api.VoidModel;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete.DeleteCodeSystemCompletionHandler;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete.DeleteCodeSystemConceptsByVersionStep;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete.DeleteCodeSystemStep;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete.DeleteCodeSystemVersionStep;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete.ReadTermConceptVersionsStep;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete.TermCodeSystemDeleteJobParametersValidator;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemversiondelete.DeleteCodeSystemVersionCompletionHandler;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemversiondelete.DeleteCodeSystemVersionFinalStep;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemversiondelete.DeleteCodeSystemVersionFirstStep;
import ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemversiondelete.DeleteCodeSystemVersionParameterValidator;
import ca.uhn.fhir.batch2.model.JobDefinition;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.CodeSystemVersionPIDResult;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteVersionJobParameters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_DELETE_JOB_NAME;
import static ca.uhn.fhir.jpa.batch.config.BatchConstants.TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME;
@Configuration
public class TermCodeSystemJobConfig {
@Autowired
private ITermCodeSystemDeleteJobSvc myITermCodeSystemSvc;
/**
* Delete code system version job.
* Deletes only a specific code system version
*/
@Bean
public JobDefinition<TermCodeSystemDeleteVersionJobParameters> termCodeSystemVersionDeleteJobDefinition() {
return JobDefinition
.newBuilder()
.setJobDefinitionId(TERM_CODE_SYSTEM_VERSION_DELETE_JOB_NAME)
.setJobDescription("Term code system version job delete")
.setJobDefinitionVersion(1)
.gatedExecution()
.setParametersType(TermCodeSystemDeleteVersionJobParameters.class)
.setParametersValidator(deleteCodeSystemVersionPrameterValidator())
.addFirstStep(
"DeleteCodeSystemVersionFirstStep",
"A first step for deleting code system versions; deletes the concepts for a provided code system version",
CodeSystemVersionPIDResult.class,
deleteCodeSystemVersionFirstStep()
)
.addLastStep(
"DeleteCodeSystemVersionFinalStep",
"Deletes the code system version",
deleteCodeSystemVersionFinalStep()
)
.completionHandler(deleteCodeSystemVersionCompletionHandler())
.errorHandler(deleteCodeSystemVersionCompletionHandler())
.build();
}
/**
* Delete Code System Job
* Deletes all code system versions, before deleting the code system itself
*/
@Bean
public JobDefinition<TermCodeSystemDeleteJobParameters> termCodeSystemDeleteJobDefinition() {
return JobDefinition
.newBuilder()
.setJobDefinitionId(TERM_CODE_SYSTEM_DELETE_JOB_NAME)
.setJobDescription("Term code system job delete")
.setJobDefinitionVersion(1)
.gatedExecution()
.setParametersType(TermCodeSystemDeleteJobParameters.class)
.setParametersValidator(codeSystemDeleteParameterValidator())
.addFirstStep(
"FetchVersionsStep",
"Fetches all term code system version PIDs for given Code System PID",
CodeSystemVersionPIDResult.class,
readCodeSystemVersionsStep()
)
.addIntermediateStep(
"DeleteCodeSystemConceptsByVersionPidStep",
"Deletes the concept links, concept properties, concept designations, and concepts associated with a given code system version PID",
CodeSystemVersionPIDResult.class,
deleteCodeSystemConceptsStep()
)
.addIntermediateStep(
"DeleteCodeSystemVersionStep",
"Deletes the specified code system version",
CodeSystemVersionPIDResult.class,
deleteCodeSystemVersionsStep()
)
.addFinalReducerStep(
"DeleteCodeSystemStep",
"Deletes the code system itself",
VoidModel.class,
deleteCodeSystemFinalStep()
)
.completionHandler(deleteCodeSystemCompletionHandler())
.errorHandler(deleteCodeSystemCompletionHandler())
.build();
}
/** delete codesystem job **/
@Bean
public TermCodeSystemDeleteJobParametersValidator codeSystemDeleteParameterValidator() {
return new TermCodeSystemDeleteJobParametersValidator();
}
@Bean
public ReadTermConceptVersionsStep readCodeSystemVersionsStep() {
return new ReadTermConceptVersionsStep(myITermCodeSystemSvc);
}
@Bean
public DeleteCodeSystemConceptsByVersionStep deleteCodeSystemConceptsStep() {
return new DeleteCodeSystemConceptsByVersionStep(myITermCodeSystemSvc);
}
@Bean
public DeleteCodeSystemVersionStep deleteCodeSystemVersionsStep() {
return new DeleteCodeSystemVersionStep(myITermCodeSystemSvc);
}
@Bean
public DeleteCodeSystemStep deleteCodeSystemFinalStep() {
return new DeleteCodeSystemStep(myITermCodeSystemSvc);
}
@Bean
public DeleteCodeSystemCompletionHandler deleteCodeSystemCompletionHandler() {
return new DeleteCodeSystemCompletionHandler(myITermCodeSystemSvc);
}
/** Delete code system version job **/
@Bean
public DeleteCodeSystemVersionParameterValidator deleteCodeSystemVersionPrameterValidator() {
return new DeleteCodeSystemVersionParameterValidator();
}
@Bean
public DeleteCodeSystemVersionFirstStep deleteCodeSystemVersionFirstStep() {
return new DeleteCodeSystemVersionFirstStep(myITermCodeSystemSvc);
}
@Bean
public DeleteCodeSystemVersionFinalStep deleteCodeSystemVersionFinalStep() {
return new DeleteCodeSystemVersionFinalStep(myITermCodeSystemSvc);
}
@Bean
public DeleteCodeSystemVersionCompletionHandler deleteCodeSystemVersionCompletionHandler() {
return new DeleteCodeSystemVersionCompletionHandler(myITermCodeSystemSvc);
}
}

View File

@ -0,0 +1,22 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete;
import ca.uhn.fhir.batch2.api.IJobCompletionHandler;
import ca.uhn.fhir.batch2.api.JobCompletionDetails;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import org.springframework.beans.factory.annotation.Autowired;
public class DeleteCodeSystemCompletionHandler
implements IJobCompletionHandler<TermCodeSystemDeleteJobParameters> {
private final ITermCodeSystemDeleteJobSvc myTermCodeSystemSvc;
public DeleteCodeSystemCompletionHandler(ITermCodeSystemDeleteJobSvc theCodeSystemDeleteJobSvc) {
myTermCodeSystemSvc = theCodeSystemDeleteJobSvc;
}
@Override
public void jobComplete(JobCompletionDetails<TermCodeSystemDeleteJobParameters> theDetails) {
myTermCodeSystemSvc.notifyJobComplete(theDetails.getInstance().getInstanceId());
}
}

View File

@ -0,0 +1,36 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete;
import ca.uhn.fhir.batch2.api.IJobDataSink;
import ca.uhn.fhir.batch2.api.IJobStepWorker;
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
import ca.uhn.fhir.batch2.api.RunOutcome;
import ca.uhn.fhir.batch2.api.StepExecutionDetails;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.CodeSystemVersionPIDResult;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
public class DeleteCodeSystemConceptsByVersionStep implements IJobStepWorker<TermCodeSystemDeleteJobParameters, CodeSystemVersionPIDResult, CodeSystemVersionPIDResult> {
private final ITermCodeSystemDeleteJobSvc myITermCodeSystemSvc;
public DeleteCodeSystemConceptsByVersionStep (ITermCodeSystemDeleteJobSvc theCodeSystemDeleteJobSvc) {
myITermCodeSystemSvc = theCodeSystemDeleteJobSvc;
}
@NotNull
@Override
public RunOutcome run(
@NotNull StepExecutionDetails<TermCodeSystemDeleteJobParameters, CodeSystemVersionPIDResult> theStepExecutionDetails,
@NotNull IJobDataSink<CodeSystemVersionPIDResult> theDataSink
) throws JobExecutionFailedException {
CodeSystemVersionPIDResult versionPidResult = theStepExecutionDetails.getData();
myITermCodeSystemSvc.deleteCodeSystemConceptsByCodeSystemVersionPid(versionPidResult.getCodeSystemVersionPID());
theDataSink.accept(versionPidResult);
return RunOutcome.SUCCESS;
}
}

View File

@ -0,0 +1,54 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete;
import ca.uhn.fhir.batch2.api.ChunkExecutionDetails;
import ca.uhn.fhir.batch2.api.IJobDataSink;
import ca.uhn.fhir.batch2.api.IReductionStepWorker;
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
import ca.uhn.fhir.batch2.api.RunOutcome;
import ca.uhn.fhir.batch2.api.StepExecutionDetails;
import ca.uhn.fhir.batch2.api.VoidModel;
import ca.uhn.fhir.batch2.model.ChunkOutcome;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.CodeSystemVersionPIDResult;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
public class DeleteCodeSystemStep implements IReductionStepWorker<TermCodeSystemDeleteJobParameters, CodeSystemVersionPIDResult, VoidModel> {
private final ITermCodeSystemDeleteJobSvc myITermCodeSystemSvc;
public DeleteCodeSystemStep(ITermCodeSystemDeleteJobSvc theCodeSystemDeleteJobSvc) {
myITermCodeSystemSvc = theCodeSystemDeleteJobSvc;
}
@NotNull
@Override
public RunOutcome run(
@NotNull StepExecutionDetails<TermCodeSystemDeleteJobParameters, CodeSystemVersionPIDResult> theStepExecutionDetails,
@NotNull IJobDataSink<VoidModel> theDataSink
) throws JobExecutionFailedException {
// final step
long codeId = theStepExecutionDetails.getParameters().getTermPid();
myITermCodeSystemSvc.deleteCodeSystem(codeId);
theDataSink.accept(new VoidModel()); // nothing required here
return RunOutcome.SUCCESS;
}
@NotNull
@Override
public ChunkOutcome consume(ChunkExecutionDetails<TermCodeSystemDeleteJobParameters, CodeSystemVersionPIDResult> theChunkDetails) {
/*
* A single code system can have multiple versions.
* We don't want to call delete on all these systems
* (because if 2 threads do so at the same time, we get exceptions)
* so we'll use the reducer step to ensure we only call delete
* a single time.
*
* Thus, we don't need to "consume" anything
*/
return ChunkOutcome.SUCCESS();
}
}

View File

@ -0,0 +1,36 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete;
import ca.uhn.fhir.batch2.api.IJobDataSink;
import ca.uhn.fhir.batch2.api.IJobStepWorker;
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
import ca.uhn.fhir.batch2.api.RunOutcome;
import ca.uhn.fhir.batch2.api.StepExecutionDetails;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.CodeSystemVersionPIDResult;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import org.jetbrains.annotations.NotNull;
public class DeleteCodeSystemVersionStep implements IJobStepWorker<TermCodeSystemDeleteJobParameters, CodeSystemVersionPIDResult, CodeSystemVersionPIDResult> {
private final ITermCodeSystemDeleteJobSvc myITermCodeSystemSvc;
public DeleteCodeSystemVersionStep(ITermCodeSystemDeleteJobSvc theCodeSystemDeleteJobSvc) {
myITermCodeSystemSvc = theCodeSystemDeleteJobSvc;
}
@NotNull
@Override
public RunOutcome run(
@NotNull StepExecutionDetails<TermCodeSystemDeleteJobParameters, CodeSystemVersionPIDResult> theStepExecutionDetails,
@NotNull IJobDataSink<CodeSystemVersionPIDResult> theDataSink
) throws JobExecutionFailedException {
CodeSystemVersionPIDResult versionPidResult = theStepExecutionDetails.getData();
long versionId = versionPidResult.getCodeSystemVersionPID();
myITermCodeSystemSvc.deleteCodeSystemVersion(versionId);
theDataSink.accept(versionPidResult);
return RunOutcome.SUCCESS;
}
}

View File

@ -0,0 +1,45 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete;
import ca.uhn.fhir.batch2.api.IFirstJobStepWorker;
import ca.uhn.fhir.batch2.api.IJobDataSink;
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
import ca.uhn.fhir.batch2.api.RunOutcome;
import ca.uhn.fhir.batch2.api.StepExecutionDetails;
import ca.uhn.fhir.batch2.api.VoidModel;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.CodeSystemVersionPIDResult;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Iterator;
public class ReadTermConceptVersionsStep implements IFirstJobStepWorker<TermCodeSystemDeleteJobParameters, CodeSystemVersionPIDResult> {
private final ITermCodeSystemDeleteJobSvc myITermCodeSystemSvc;
public ReadTermConceptVersionsStep(ITermCodeSystemDeleteJobSvc theCodeSystemDeleteJobSvc) {
myITermCodeSystemSvc = theCodeSystemDeleteJobSvc;
}
@NotNull
@Override
public RunOutcome run(
@NotNull StepExecutionDetails<TermCodeSystemDeleteJobParameters, VoidModel> theStepExecutionDetails,
@NotNull IJobDataSink<CodeSystemVersionPIDResult> theDataSink
) throws JobExecutionFailedException {
TermCodeSystemDeleteJobParameters parameters = theStepExecutionDetails.getParameters();
long pid = parameters.getTermPid();
Iterator<Long> versionPids = myITermCodeSystemSvc.getAllCodeSystemVersionForCodeSystemPid(pid);
while (versionPids.hasNext()) {
long next = versionPids.next().longValue();
CodeSystemVersionPIDResult versionPidResult = new CodeSystemVersionPIDResult();
versionPidResult.setCodeSystemVersionPID(next);
theDataSink.accept(versionPidResult);
}
return RunOutcome.SUCCESS;
}
}

View File

@ -0,0 +1,22 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemdelete;
import ca.uhn.fhir.batch2.api.IJobParametersValidator;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteJobParameters;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class TermCodeSystemDeleteJobParametersValidator implements IJobParametersValidator<TermCodeSystemDeleteJobParameters> {
@Nullable
@Override
public List<String> validate(@NotNull TermCodeSystemDeleteJobParameters theParameters) {
List<String> errors = new ArrayList<>();
if (theParameters.getTermPid() <= 0) {
errors.add("Invalid Term Code System PID " + theParameters.getTermPid());
}
return errors;
}
}

View File

@ -0,0 +1,21 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemversiondelete;
import ca.uhn.fhir.batch2.api.IJobCompletionHandler;
import ca.uhn.fhir.batch2.api.JobCompletionDetails;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteVersionJobParameters;
import org.springframework.beans.factory.annotation.Autowired;
public class DeleteCodeSystemVersionCompletionHandler implements IJobCompletionHandler<TermCodeSystemDeleteVersionJobParameters> {
private final ITermCodeSystemDeleteJobSvc myTermCodeSystemSvc;
public DeleteCodeSystemVersionCompletionHandler(ITermCodeSystemDeleteJobSvc theCodeSystemDeleteJobSvc) {
myTermCodeSystemSvc = theCodeSystemDeleteJobSvc;
}
@Override
public void jobComplete(JobCompletionDetails<TermCodeSystemDeleteVersionJobParameters> theDetails) {
myTermCodeSystemSvc.notifyJobComplete(theDetails.getInstance().getInstanceId());
}
}

View File

@ -0,0 +1,35 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemversiondelete;
import ca.uhn.fhir.batch2.api.IJobDataSink;
import ca.uhn.fhir.batch2.api.ILastJobStepWorker;
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
import ca.uhn.fhir.batch2.api.RunOutcome;
import ca.uhn.fhir.batch2.api.StepExecutionDetails;
import ca.uhn.fhir.batch2.api.VoidModel;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.CodeSystemVersionPIDResult;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteVersionJobParameters;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
public class DeleteCodeSystemVersionFinalStep implements ILastJobStepWorker<TermCodeSystemDeleteVersionJobParameters, CodeSystemVersionPIDResult> {
private final ITermCodeSystemDeleteJobSvc myTermCodeSystemSvc;
public DeleteCodeSystemVersionFinalStep(ITermCodeSystemDeleteJobSvc theCodeSystemDeleteJobSvc) {
myTermCodeSystemSvc = theCodeSystemDeleteJobSvc;
}
@NotNull
@Override
public RunOutcome run(
@NotNull StepExecutionDetails<TermCodeSystemDeleteVersionJobParameters, CodeSystemVersionPIDResult> theStepExecutionDetails,
@NotNull IJobDataSink<VoidModel> theDataSink
) throws JobExecutionFailedException {
long versionPid = theStepExecutionDetails.getParameters().getCodeSystemVersionPid();
myTermCodeSystemSvc.deleteCodeSystemVersion(versionPid);
return RunOutcome.SUCCESS;
}
}

View File

@ -0,0 +1,39 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemversiondelete;
import ca.uhn.fhir.batch2.api.IFirstJobStepWorker;
import ca.uhn.fhir.batch2.api.IJobDataSink;
import ca.uhn.fhir.batch2.api.JobExecutionFailedException;
import ca.uhn.fhir.batch2.api.RunOutcome;
import ca.uhn.fhir.batch2.api.StepExecutionDetails;
import ca.uhn.fhir.batch2.api.VoidModel;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemDeleteJobSvc;
import ca.uhn.fhir.jpa.term.models.CodeSystemVersionPIDResult;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteVersionJobParameters;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
public class DeleteCodeSystemVersionFirstStep implements IFirstJobStepWorker<TermCodeSystemDeleteVersionJobParameters, CodeSystemVersionPIDResult> {
private final ITermCodeSystemDeleteJobSvc myTermCodeSystemSvc;
public DeleteCodeSystemVersionFirstStep(ITermCodeSystemDeleteJobSvc theCodeSystemDeleteJobSvc) {
myTermCodeSystemSvc = theCodeSystemDeleteJobSvc;
}
@NotNull
@Override
public RunOutcome run(
@NotNull StepExecutionDetails<TermCodeSystemDeleteVersionJobParameters, VoidModel> theStepExecutionDetails,
@NotNull IJobDataSink<CodeSystemVersionPIDResult> theDataSink
) throws JobExecutionFailedException {
long versionId = theStepExecutionDetails.getParameters().getCodeSystemVersionPid();
myTermCodeSystemSvc.deleteCodeSystemConceptsByCodeSystemVersionPid(versionId);
CodeSystemVersionPIDResult result = new CodeSystemVersionPIDResult();
result.setCodeSystemVersionPID(versionId);
theDataSink.accept(result);
return RunOutcome.SUCCESS;
}
}

View File

@ -0,0 +1,25 @@
package ca.uhn.fhir.batch2.jobs.termcodesystem.codesystemversiondelete;
import ca.uhn.fhir.batch2.api.IJobParametersValidator;
import ca.uhn.fhir.jpa.term.models.TermCodeSystemDeleteVersionJobParameters;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public class DeleteCodeSystemVersionParameterValidator implements IJobParametersValidator<TermCodeSystemDeleteVersionJobParameters> {
@Nullable
@Override
public List<String> validate(@NotNull TermCodeSystemDeleteVersionJobParameters theParameters) {
ArrayList<String> errors = new ArrayList<>();
long versionPID = theParameters.getCodeSystemVersionPid();
if (versionPID <= 0) {
errors.add("Invalid code system version PID " + versionPID);
}
return errors;
}
}

View File

@ -21,8 +21,9 @@ package ca.uhn.fhir.batch2.api;
*/
import ca.uhn.fhir.batch2.model.JobInstance;
import ca.uhn.fhir.batch2.models.JobInstanceFetchRequest;
import ca.uhn.fhir.batch2.model.JobInstanceStartRequest;
import ca.uhn.fhir.batch2.model.StatusEnum;
import ca.uhn.fhir.batch2.models.JobInstanceFetchRequest;
import ca.uhn.fhir.jpa.batch.models.Batch2JobStartResponse;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -30,6 +31,7 @@ import org.springframework.data.domain.Page;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Set;
public interface IJobCoordinator {
@ -56,7 +58,6 @@ public interface IJobCoordinator {
*/
List<JobInstance> getInstances(int thePageSize, int thePageIndex);
/**
* Fetch recent job instances
*/
@ -72,4 +73,14 @@ public interface IJobCoordinator {
* @return - page of job instances
*/
Page<JobInstance> fetchAllJobInstances(JobInstanceFetchRequest theFetchRequest);
/**
* Fetches all job instances by job definition id and statuses
*/
List<JobInstance> getJobInstancesByJobDefinitionIdAndStatuses(String theJobDefinitionId, Set<StatusEnum> theStatuses, int theCount, int theStart);
/**
* Fetches all jobs by job definition id
*/
List<JobInstance> getJobInstancesByJobDefinitionId(String theJobDefinitionId, int theCount, int theStart);
}

View File

@ -44,9 +44,13 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isBlank;
@ -159,6 +163,16 @@ public class JobCoordinatorImpl implements IJobCoordinator {
return myJobQuerySvc.getInstancesByJobDefinitionIdAndEndedStatus(theJobDefinitionId, theEnded, theCount, theStart);
}
@Override
public List<JobInstance> getJobInstancesByJobDefinitionIdAndStatuses(String theJobDefinitionId, Set<StatusEnum> theStatuses, int theCount, int theStart) {
return myJobQuerySvc.getInstancesByJobDefinitionAndStatuses(theJobDefinitionId, theStatuses, theCount, theStart);
}
@Override
public List<JobInstance> getJobInstancesByJobDefinitionId(String theJobDefinitionId, int theCount, int theStart) {
return getJobInstancesByJobDefinitionIdAndStatuses(theJobDefinitionId, new HashSet<>(Arrays.asList(StatusEnum.values())), theCount, theStart);
}
@Override
public Page<JobInstance> fetchAllJobInstances(JobInstanceFetchRequest theFetchRequest) {
return myJobQuerySvc.fetchAllInstances(theFetchRequest);

View File

@ -132,7 +132,10 @@ class JobQuerySvc {
} else {
requestedStatus = StatusEnum.getNotEndedStatuses();
}
return myJobPersistence.fetchInstancesByJobDefinitionIdAndStatus(theJobDefinitionId, requestedStatus, theCount, theStart);
return getInstancesByJobDefinitionAndStatuses(theJobDefinitionId, requestedStatus, theCount, theStart);
}
public List<JobInstance> getInstancesByJobDefinitionAndStatuses(String theJobDefinitionId, Set<StatusEnum> theStatuses, int theCount, int theStart) {
return myJobPersistence.fetchInstancesByJobDefinitionIdAndStatus(theJobDefinitionId, theStatuses, theCount, theStart);
}
}

View File

@ -0,0 +1,48 @@
package ca.uhn.fhir.jpa.term.api;
import ca.uhn.fhir.jpa.term.models.CodeSystemConceptsDeleteResult;
import java.util.Iterator;
public interface ITermCodeSystemDeleteJobSvc {
/**
* Gets an iterator for all code system version PIDs
* @param thePid
* @return
*/
Iterator<Long> getAllCodeSystemVersionForCodeSystemPid(long thePid);
/**
* Deletes all metadata associated with a code system version
* Specific metadata deleted:
* * concept links
* * concept properties
* * concept designations
* * concepts
* @param theVersionPid - the version id of the code system to delete
* @return - a wrapper for the delete results of each of the deletes (if desired)
*/
CodeSystemConceptsDeleteResult deleteCodeSystemConceptsByCodeSystemVersionPid(long theVersionPid);
/**
* Deletes a Code System Version
* NB: it is expected that any concepts related to the Code System Version are
* deleted first.
* @param theVersionPid - the code system version pid for the version to delete
*/
void deleteCodeSystemVersion(long theVersionPid);
/**
* Deletes a code system.
* NB: it is expected that all code system versions are deleted first.
* @param thePid - the code system pid
*/
void deleteCodeSystem(long thePid);
/**
* Notifies that the job has completed (or errored out).
* @param theJobId - the job id
*/
void notifyJobComplete(String theJobId);
}

View File

@ -0,0 +1,44 @@
package ca.uhn.fhir.jpa.term.models;
public class CodeSystemConceptsDeleteResult {
private int myDeletedLinks;
private int myDeletedProperties;
private int myDeletedDesignations;
private int myCodeSystemConceptDelete;
public int getDeletedLinks() {
return myDeletedLinks;
}
public void setDeletedLinks(int theDeletedLinks) {
myDeletedLinks = theDeletedLinks;
}
public int getDeletedProperties() {
return myDeletedProperties;
}
public void setDeletedProperties(int theDeletedProperties) {
myDeletedProperties = theDeletedProperties;
}
public int getDeletedDesignations() {
return myDeletedDesignations;
}
public void setDeletedDesignations(int theDeletedDesignations) {
myDeletedDesignations = theDeletedDesignations;
}
public int getCodeSystemConceptDelete() {
return myCodeSystemConceptDelete;
}
public void setCodeSystemConceptDelete(int theCodeSystemConceptDelete) {
myCodeSystemConceptDelete = theCodeSystemConceptDelete;
}
}

View File

@ -0,0 +1,18 @@
package ca.uhn.fhir.jpa.term.models;
import ca.uhn.fhir.model.api.IModelJson;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CodeSystemVersionPIDResult implements IModelJson {
@JsonProperty("codeSystemVersionPID")
private long myCodeSystemVersionPID;
public long getCodeSystemVersionPID() {
return myCodeSystemVersionPID;
}
public void setCodeSystemVersionPID(long theCodeSystemVersionPID) {
myCodeSystemVersionPID = theCodeSystemVersionPID;
}
}

View File

@ -0,0 +1,6 @@
package ca.uhn.fhir.jpa.term.models;
import ca.uhn.fhir.model.api.IModelJson;
public class DeleteCodeSystemBaseParameters implements IModelJson {
}

View File

@ -0,0 +1,20 @@
package ca.uhn.fhir.jpa.term.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class TermCodeSystemDeleteJobParameters extends DeleteCodeSystemBaseParameters {
/**
* Term code system PID
*/
@JsonProperty("codeSystemPID")
private long myTermPid;
public long getTermPid() {
return myTermPid;
}
public void setTermPid(long theTermPid) {
myTermPid = theTermPid;
}
}

View File

@ -0,0 +1,20 @@
package ca.uhn.fhir.jpa.term.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class TermCodeSystemDeleteVersionJobParameters extends DeleteCodeSystemBaseParameters {
/**
* Code system version pid
*/
@JsonProperty("versionPID")
private long myCodeSystemVersionPid;
public long getCodeSystemVersionPid() {
return myCodeSystemVersionPid;
}
public void setCodeSystemVersionPid(long theCodeSystemVersionPid) {
myCodeSystemVersionPid = theCodeSystemVersionPid;
}
}