diff --git a/custom/acme/loan/cob/dependencies.gradle b/custom/acme/loan/cob/dependencies.gradle
index 59d668289..364f7d772 100644
--- a/custom/acme/loan/cob/dependencies.gradle
+++ b/custom/acme/loan/cob/dependencies.gradle
@@ -19,4 +19,5 @@
dependencies {
implementation(project(':fineract-provider'))
+ implementation('org.springframework.boot:spring-boot-starter-data-jpa')
}
diff --git a/custom/acme/loan/job/build.gradle b/custom/acme/loan/job/build.gradle
new file mode 100644
index 000000000..235711ad7
--- /dev/null
+++ b/custom/acme/loan/job/build.gradle
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+description = 'ACME Corp.: Fineract Loan Job'
+
+group = 'com.acme.fineract'
+
+archivesBaseName = 'acme-fineract-loan-job'
+
+apply from: 'dependencies.gradle'
diff --git a/custom/acme/loan/job/dependencies.gradle b/custom/acme/loan/job/dependencies.gradle
new file mode 100644
index 000000000..fd2f26643
--- /dev/null
+++ b/custom/acme/loan/job/dependencies.gradle
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+dependencies {
+ implementation(project(':fineract-provider'))
+ implementation('org.springframework.batch:spring-batch-integration')
+ implementation('org.springframework.boot:spring-boot-starter-data-jpa')
+}
diff --git a/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeJobName.java b/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeJobName.java
new file mode 100644
index 000000000..342b9f189
--- /dev/null
+++ b/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeJobName.java
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package com.acme.fineract.loan.job;
+
+public enum AcmeJobName {
+
+ ACME_NOOP_JOB("Acme Noop Job");
+
+ private final String name;
+
+ AcmeJobName(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return this.name;
+ }
+}
diff --git a/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeJobNameConfig.java b/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeJobNameConfig.java
new file mode 100644
index 000000000..4aabfbab4
--- /dev/null
+++ b/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeJobNameConfig.java
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package com.acme.fineract.loan.job;
+
+import java.util.List;
+import org.apache.fineract.infrastructure.jobs.service.jobname.JobNameData;
+import org.apache.fineract.infrastructure.jobs.service.jobname.JobNameProvider;
+import org.apache.fineract.infrastructure.jobs.service.jobname.SimpleJobNameProvider;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AcmeJobNameConfig {
+
+ @Bean
+ public JobNameProvider acmeJobNameProvider() {
+ return new SimpleJobNameProvider(List.of(new JobNameData(AcmeJobName.ACME_NOOP_JOB.name(), AcmeJobName.ACME_NOOP_JOB.toString())));
+ }
+}
diff --git a/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeNoopJobConfiguration.java b/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeNoopJobConfiguration.java
new file mode 100644
index 000000000..040c9e9b2
--- /dev/null
+++ b/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeNoopJobConfiguration.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package com.acme.fineract.loan.job;
+
+import org.springframework.batch.core.Job;
+import org.springframework.batch.core.Step;
+import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
+import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
+import org.springframework.batch.core.launch.support.RunIdIncrementer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AcmeNoopJobConfiguration {
+
+ @Autowired
+ private JobBuilderFactory jobs;
+ @Autowired
+ private StepBuilderFactory steps;
+ @Autowired
+ private AcmeNoopJobTasklet tasklet;
+
+ @Bean
+ protected Step acmeNoopJobStep() {
+ return steps.get(AcmeJobName.ACME_NOOP_JOB.name()).tasklet(tasklet).build();
+ }
+
+ @Bean
+ public Job acmeNoopJob() {
+ return jobs.get(AcmeJobName.ACME_NOOP_JOB.name()).start(acmeNoopJobStep()).incrementer(new RunIdIncrementer()).build();
+ }
+
+}
diff --git a/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeNoopJobTasklet.java b/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeNoopJobTasklet.java
new file mode 100644
index 000000000..4c644e1ce
--- /dev/null
+++ b/custom/acme/loan/job/src/main/java/com/acme/fineract/loan/job/AcmeNoopJobTasklet.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package com.acme.fineract.loan.job;
+
+import lombok.extern.slf4j.Slf4j;
+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.stereotype.Component;
+
+@Slf4j
+@Component
+public class AcmeNoopJobTasklet implements Tasklet {
+
+ @Override
+ public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
+ log.info("Acme custom job execution");
+ return RepeatStatus.FINISHED;
+ }
+}
diff --git a/custom/acme/loan/job/src/main/resources/db/custom-changelog/0001_acme_loan_job.xml b/custom/acme/loan/job/src/main/resources/db/custom-changelog/0001_acme_loan_job.xml
new file mode 100644
index 000000000..f466fdaf3
--- /dev/null
+++ b/custom/acme/loan/job/src/main/resources/db/custom-changelog/0001_acme_loan_job.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/custom/acme/loan/job/src/test/java/AcmeNoopJobTaskletTest.java b/custom/acme/loan/job/src/test/java/AcmeNoopJobTaskletTest.java
new file mode 100644
index 000000000..f8b6e5026
--- /dev/null
+++ b/custom/acme/loan/job/src/test/java/AcmeNoopJobTaskletTest.java
@@ -0,0 +1,53 @@
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+import static org.junit.Assert.assertEquals;
+
+import com.acme.fineract.loan.job.AcmeNoopJobTasklet;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.batch.core.StepContribution;
+import org.springframework.batch.core.scope.context.ChunkContext;
+import org.springframework.batch.repeat.RepeatStatus;
+
+@ExtendWith(MockitoExtension.class)
+public class AcmeNoopJobTaskletTest {
+
+ @Mock
+ private StepContribution stepContribution;
+ @Mock
+ private ChunkContext chunkContext;
+ private RepeatStatus resultStatus;
+ private AcmeNoopJobTasklet underTest;
+
+ @BeforeEach
+ public void setUp() {
+ underTest = new AcmeNoopJobTasklet();
+ }
+
+ @Test
+ public void testJobExecution() throws Exception {
+ resultStatus = underTest.execute(stepContribution, chunkContext);
+ assertEquals(resultStatus, RepeatStatus.FINISHED);
+ }
+
+}
diff --git a/custom/acme/loan/starter/src/main/java/com/acme/fineract/loan/starter/AcmeLoanAutoConfiguration.java b/custom/acme/loan/starter/src/main/java/com/acme/fineract/loan/starter/AcmeLoanAutoConfiguration.java
index 8e4560a32..d1516f3a0 100644
--- a/custom/acme/loan/starter/src/main/java/com/acme/fineract/loan/starter/AcmeLoanAutoConfiguration.java
+++ b/custom/acme/loan/starter/src/main/java/com/acme/fineract/loan/starter/AcmeLoanAutoConfiguration.java
@@ -29,7 +29,8 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
@AutoConfiguration
-@ComponentScans({ @ComponentScan("com.acme.fineract.loan.cob"), @ComponentScan("com.acme.fineract.loan.processor") })
+@ComponentScans({ @ComponentScan("com.acme.fineract.loan.cob"), @ComponentScan("com.acme.fineract.loan.processor"),
+ @ComponentScan("com.acme.fineract.loan.job") })
@ConditionalOnProperty("acme.loan.enabled")
public class AcmeLoanAutoConfiguration {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/config/JobNameProviderConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/config/JobNameProviderConfig.java
new file mode 100644
index 000000000..a43bc54c3
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/config/JobNameProviderConfig.java
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.fineract.infrastructure.jobs.config;
+
+import java.util.Arrays;
+import java.util.List;
+import org.apache.fineract.infrastructure.jobs.service.JobName;
+import org.apache.fineract.infrastructure.jobs.service.jobname.JobNameData;
+import org.apache.fineract.infrastructure.jobs.service.jobname.JobNameProvider;
+import org.apache.fineract.infrastructure.jobs.service.jobname.SimpleJobNameProvider;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class JobNameProviderConfig {
+
+ @Bean
+ public JobNameProvider fineractJobNameProvider() {
+ List jobNames = Arrays.stream(JobName.values()).map(jn -> new JobNameData(jn.name(), jn.toString())).toList();
+ return new SimpleJobNameProvider(jobNames);
+ }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
index 9b1a32308..1858733e4 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobName.java
@@ -18,9 +18,6 @@
*/
package org.apache.fineract.infrastructure.jobs.service;
-import java.util.Arrays;
-import java.util.Optional;
-
public enum JobName {
UPDATE_LOAN_ARREARS_AGEING("Update Loan Arrears Ageing"), //
@@ -66,13 +63,9 @@ public enum JobName {
this.name = name;
}
- public static JobName getJobByName(String jobName) {
- Optional optionalJob = Arrays.stream(JobName.values()).filter(jn -> jobName.equals(jn.name)).findAny();
- return optionalJob.orElseThrow(() -> new IllegalArgumentException("Job not found by name: " + jobName));
- }
-
@Override
public String toString() {
return this.name;
}
+
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobRegisterServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobRegisterServiceImpl.java
index bd627cc92..d5ae619f8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobRegisterServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/JobRegisterServiceImpl.java
@@ -33,6 +33,8 @@ import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobDetail;
import org.apache.fineract.infrastructure.jobs.domain.SchedulerDetail;
import org.apache.fineract.infrastructure.jobs.exception.JobNodeIdMismatchingException;
import org.apache.fineract.infrastructure.jobs.exception.JobNotFoundException;
+import org.apache.fineract.infrastructure.jobs.service.jobname.JobNameData;
+import org.apache.fineract.infrastructure.jobs.service.jobname.JobNameService;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
@@ -79,6 +81,9 @@ public class JobRegisterServiceImpl implements JobRegisterService, ApplicationLi
@Autowired
private JobStarter jobStarter;
+ @Autowired
+ private JobNameService jobNameService;
+
private static final String JOB_STARTER_METHOD_NAME = "run";
public void executeJob(final ScheduledJobDetail scheduledJobDetail, String triggerType) {
@@ -313,8 +318,8 @@ public class JobRegisterServiceImpl implements JobRegisterService, ApplicationLi
private JobDetail createJobDetail(final ScheduledJobDetail scheduledJobDetail) throws Exception {
final FineractPlatformTenant tenant = ThreadLocalContextUtil.getTenant();
- JobName jobName = JobName.getJobByName(scheduledJobDetail.getJobName());
- Job job = jobLocator.getJob(jobName.name());
+ JobNameData jobName = jobNameService.getJobByHumanReadableName(scheduledJobDetail.getJobName());
+ Job job = jobLocator.getJob(jobName.getEnumStyleName());
final MethodInvokingJobDetailFactoryBean jobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean();
jobDetailFactoryBean.setName(scheduledJobDetail.getJobName() + "JobDetail" + tenant.getId());
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameData.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameData.java
new file mode 100644
index 000000000..dda306214
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameData.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.fineract.infrastructure.jobs.service.jobname;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor
+public class JobNameData {
+
+ private final String enumStyleName;
+ private final String humanReadableName;
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameProvider.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameProvider.java
new file mode 100644
index 000000000..9f1a17db7
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameProvider.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.fineract.infrastructure.jobs.service.jobname;
+
+import java.util.Set;
+
+public interface JobNameProvider {
+
+ Set provide();
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameService.java
new file mode 100644
index 000000000..b0feb804d
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/JobNameService.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.fineract.infrastructure.jobs.service.jobname;
+
+import static java.util.stream.Collectors.toSet;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.Set;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class JobNameService {
+
+ private final Collection providers;
+
+ public JobNameData getJobByHumanReadableName(String jobName) {
+ Optional optionalJob = getJobNames().stream().filter(jn -> jobName.equals(jn.getHumanReadableName())).findAny();
+ return optionalJob.orElseThrow(() -> new IllegalArgumentException("Job not found by name: " + jobName));
+ }
+
+ private Set getJobNames() {
+ return providers.stream().map(JobNameProvider::provide).flatMap(Collection::stream).collect(toSet());
+ }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/SimpleJobNameProvider.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/SimpleJobNameProvider.java
new file mode 100644
index 000000000..7c03d0062
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/jobname/SimpleJobNameProvider.java
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.fineract.infrastructure.jobs.service.jobname;
+
+import java.util.Collection;
+import java.util.Set;
+
+public class SimpleJobNameProvider implements JobNameProvider {
+
+ private final Set jobNames;
+
+ public SimpleJobNameProvider(Collection jobNames) {
+ this.jobNames = Set.copyOf(jobNames);
+ }
+
+ @Override
+ public Set provide() {
+ return jobNames;
+ }
+}