Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/fr batch service/add dependencies #13

Merged
merged 5 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions fr-batch-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@
<version>8.2.0</version>
<scope>runtime</scope>
</dependency>
<!--https://github.com/vavr-io/vavr/releases-->
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.10.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
Expand All @@ -108,6 +114,22 @@
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<!-- https://spockframework.org -->
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>2.4-M4-groovy-4.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<version>2.4-M4-groovy-4.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
Expand Down Expand Up @@ -227,11 +249,19 @@
</includes>

<removeUnusedImports>
<engine>google-java-format</engine> <!-- optional. Defaults to `google-java-format`. Can be switched to `cleanthat-javaparser-unnecessaryimport` (e.g. to process JDK17 source files with a JDK8+ Runtime) -->
<engine>google-java-format
</engine> <!-- optional. Defaults to `google-java-format`. Can be switched to `cleanthat-javaparser-unnecessaryimport` (e.g. to process JDK17 source files with a JDK8+ Runtime) -->
</removeUnusedImports>
<importOrder> <!-- or a custom ordering -->
<wildcardsLast>false</wildcardsLast> <!-- Optional, default false. Sort wildcard import after specific imports -->
<order>java|javax,org,com,com.diffplug,,\#com.diffplug,\#</order> <!-- or use <file>${project.basedir}/eclipse.importorder</file> -->
<!-- you can use an empty string for all the imports you didn't specify explicitly, '|' to join group without blank line, and '\#` prefix for static imports. -->
<semanticSort>false</semanticSort> <!-- Optional, default false. Sort by package, then class, then member (for static imports). Splitting is based on common conventions (packages are lower case, classes start with upper case). Use <treatAsPackage> and <treatAsClass> for exceptions. -->
</importOrder>
<!-- apply a specific flavor of google-java-format and reflow long strings -->
<googleJavaFormat>
<version>1.22.0</version> <!-- https://github.com/google/google-java-format/releases optional, 1.8 is the minimum supported version for Java 11-->
<version>1.22.0
</version> <!-- https://github.com/google/google-java-format/releases optional, 1.8 is the minimum supported version for Java 11-->
<style>AOSP</style> <!-- GOOGLE or AOSP (optional) -->
<reflowLongStrings>true</reflowLongStrings> <!-- optional -->
<formatJavadoc>false</formatJavadoc> <!-- optional -->
Expand All @@ -246,6 +276,18 @@
</java>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<goals>
<goal>compileTests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import com.fronzec.frbatchservice.utils.JsonUtils;
import com.fronzec.frbatchservice.web.SingleJobDataRequest;
import io.vavr.control.Try;
import jakarta.annotation.PostConstruct;
import java.time.LocalDate;
import java.util.*;
Expand All @@ -19,17 +20,16 @@
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.stereotype.Service;

/** Esta clas se encarga de proveer y gestionar la vida de los jobs */
@Service
public class JobsManagerService {

// TODO esto se debe mover a la BD a un modelo entidad relacion
// TODO This must be moved to the DB to an entity relationship model

/** Saves jobBeanNames and jobsParams */
private Map<String, Map<String, String>> jobs = new HashMap<>();
private Map<String, Map<String, String>> manualDefinedJobs = new HashMap<>();

private static final Logger logger = LoggerFactory.getLogger(JobsManagerService.class);

Expand Down Expand Up @@ -85,100 +85,72 @@ public void init() {
Map<String, String> params = new HashMap<>();
params.put("paramname", "paramvalue");

jobs.put("job1", params);
jobs.put("job2", params);
jobs.put("job3", params);
manualDefinedJobs.put("job1", params);
manualDefinedJobs.put("job2", params);
manualDefinedJobs.put("job3", params);
// TODO: 16/05/21 trying to run non existing job
jobs.put("nonExistingJob", params);
manualDefinedJobs.put("nonExistingJob", params);

// NOTE: 16/05/21 Jobs loaded in our service using spring, see injection on constructor
logger.info("jobs found by spring -> {}", jobsList.size());
jobsList.forEach(job -> logger.info("job-> {}", job));
StringBuilder sb = new StringBuilder();
sb.append(String.format("jobs found by spring -> < count= %s >", jobsList.size()));
jobsList.forEach(job -> sb.append(String.format(" | [job -> %s]", job)));
logger.info("-> {}", sb);
}

public HashMap<String, String> launchAllNonAutoDetectedJobsAsync(
Date date, final int runningNumber) {
Objects.requireNonNull(date);
// TODO: 15/05/21 get all jobs
// TODO: 16/05/21 instance a job parameter and job names
HashMap<String, String> info = new HashMap<>(jobs.size());
jobs.forEach(
(key, params) -> {
try {
var theJob = (Job) beanFactory.getBean(key);
Objects.requireNonNull(theJob);
var jobParametersBuilder = new JobParametersBuilder();
// Adding the date to our param we set and allow run a single job only for
// one day
int day = date.getDay();
int month = date.getMonth();
int year = date.getYear();
params.put("DATE", String.format("%s-%s-%s", day, month, year));
params.put("RUNNING_NUMBER", String.valueOf(runningNumber));
params.forEach(jobParametersBuilder::addString);
try {
logger.info("Running job: {} with params -> {}", theJob, params);
asyncJobLauncher.run(theJob, jobParametersBuilder.toJobParameters());
info.put(key, theJob.toString());
} catch (JobExecutionAlreadyRunningException e) {
logger.error("already", e);
info.put(key, e.getMessage());
} catch (JobRestartException e) {
logger.error("restart", e);
info.put(key, e.getMessage());
} catch (JobInstanceAlreadyCompleteException e) {
logger.error("completed", e);
info.put(key, e.getMessage());
} catch (JobParametersInvalidException e) {
logger.info("parameters", e);
info.put(key, e.getMessage());
}
} catch (NoSuchBeanDefinitionException e) {
logger.info("nobeanjob found", e);
info.put(key, e.getMessage());
}
});

return info;
LocalDate date, final int runningNumber) {
return launchAllNonAutoDetectedJobs(date, runningNumber, false);
}

public HashMap<String, String> launchAllNonAutoDetectedJobsSync(
LocalDate execDate, final int runningNumber) {
return launchAllNonAutoDetectedJobs(execDate, runningNumber, true);
}

private HashMap<String, String> launchAllNonAutoDetectedJobs(
LocalDate execDate, final int runningNumber, boolean useSyncExecutor) {
Objects.requireNonNull(execDate);
HashMap<String, String> resultInfoHolder = new HashMap<>(jobs.size());
jobs.forEach(
HashMap<String, String> resultInfoHolder = new HashMap<>(manualDefinedJobs.size());
manualDefinedJobs.forEach(
(key, defaultJobParams) -> {
Try<Job> theJob = Try.of(() -> (Job) beanFactory.getBean(key));
if (theJob.isFailure()) {
Throwable e = theJob.getCause();
logger.info("nobeanjob found {}", e.toString());
resultInfoHolder.put(key, e.getMessage());
logger.warn("failure building the bean for the job, continuing with next");
return;
}

var jobParametersBuilder = new JobParametersBuilder();
// note: Params used as part of identifying a job instance
defaultJobParams.put("DATE", execDate.toString());
defaultJobParams.put("ATTEMPT_NUMBER", String.valueOf(runningNumber));
defaultJobParams.forEach(jobParametersBuilder::addString);
// note: Params not used to identify a job instance
jobParametersBuilder.addString("DESCRIPTION", "some useful description", false);
try {
var theJob = (Job) beanFactory.getBean(key);
Objects.requireNonNull(theJob, "Bean Job cannot be instantiated");
var jobParametersBuilder = new JobParametersBuilder();
// note: Params used as part of identifying a job instance
defaultJobParams.put("DATE", execDate.toString());
defaultJobParams.put("ATTEMPT_NUMBER", String.valueOf(runningNumber));
defaultJobParams.forEach(jobParametersBuilder::addString);
// note: Params not used to identify a job instance
jobParametersBuilder.addString(
"DESCRIPTION", "some useful description", false);
try {
logger.info(
"Running job: {} with params -> {}", theJob, defaultJobParams);
syncJobLauncher.run(theJob, jobParametersBuilder.toJobParameters());
resultInfoHolder.put(key, theJob.toString());
} catch (JobExecutionAlreadyRunningException e) {
logger.error("already", e);
resultInfoHolder.put(key, e.getMessage());
} catch (JobRestartException e) {
logger.error("restart", e);
resultInfoHolder.put(key, e.getMessage());
} catch (JobInstanceAlreadyCompleteException e) {
logger.error("completed", e);
resultInfoHolder.put(key, e.getMessage());
} catch (JobParametersInvalidException e) {
logger.info("parameters", e);
resultInfoHolder.put(key, e.getMessage());
Job jobToRun = theJob.get();
logger.info(
"Running job: {} with params -> {}", jobToRun, defaultJobParams);
if (useSyncExecutor) {
syncJobLauncher.run(jobToRun, jobParametersBuilder.toJobParameters());
} else {
asyncJobLauncher.run(jobToRun, jobParametersBuilder.toJobParameters());
}
} catch (NoSuchBeanDefinitionException e) {
logger.info("nobeanjob found", e);
resultInfoHolder.put(key, jobToRun.toString());
} catch (JobExecutionAlreadyRunningException e) {
logger.error("already", e);
resultInfoHolder.put(key, e.getMessage());
} catch (JobRestartException e) {
logger.error("restart", e);
resultInfoHolder.put(key, e.getMessage());
} catch (JobInstanceAlreadyCompleteException e) {
logger.error("completed", e);
resultInfoHolder.put(key, e.getMessage());
} catch (JobParametersInvalidException e) {
logger.info("parameters", e);
resultInfoHolder.put(key, e.getMessage());
}
});
Expand Down Expand Up @@ -231,7 +203,7 @@ public HashMap<String, String> launchAllJobsPreloaded(Date date, final Integer r
public Map<String, String> asyncRunJobWithParams(SingleJobDataRequest request) {
Map<String, String> launchedJobMetadata = new HashMap<>();
Map<String, String> jobExecParams = new HashMap<>();
if (jobs.containsKey(request.getJobBeanName())) {
if (manualDefinedJobs.containsKey(request.getJobBeanName())) {
try {
var theJob = (Job) beanFactory.getBean(request.getJobBeanName());
Objects.requireNonNull(theJob);
Expand Down Expand Up @@ -277,7 +249,7 @@ public Map<String, String> asyncRunJobWithParams(SingleJobDataRequest request) {
public Map<String, String> syncRunJobWithParams(SingleJobDataRequest request) {
Map<String, String> launchedJobMetadata = new HashMap<>();
Map<String, String> jobExecParams = new HashMap<>();
if (jobs.containsKey(request.getJobBeanName())) {
if (manualDefinedJobs.containsKey(request.getJobBeanName())) {
try {
var theJob = (Job) beanFactory.getBean(request.getJobBeanName());
Objects.requireNonNull(theJob);
Expand Down Expand Up @@ -326,7 +298,8 @@ public Map<String, String> syncRunJobWithParams(SingleJobDataRequest request) {

public HashMap<String, String> stopAllJobs() {
HashMap<String, String> singaledStopped = new HashMap<>();
jobs.keySet()
manualDefinedJobs
.keySet()
.forEach(
name -> {
try {
Expand Down Expand Up @@ -358,7 +331,8 @@ public HashMap<String, String> stopAllJobs() {

public HashMap<String, Map<String, String>> getRunning() {
HashMap<String, Map<String, String>> running = new HashMap<>();
jobs.keySet()
manualDefinedJobs
.keySet()
.forEach(
key -> {
HashMap<String, String> tmp = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public ResponseEntity<JobInfo> startAllJobsAsync(
@Valid @RequestBody AllJobsDataRequest dataRequest) {
HashMap<String, String> stringStringHashMap =
jobsManagerService.launchAllNonAutoDetectedJobsAsync(
dataRequest.getDate(), dataRequest.getTryNumber());
dataRequest.getLocalDate(), dataRequest.getTryNumber());
JobInfo jobInfo = new JobInfo();
jobInfo.setInfo(stringStringHashMap);
return ResponseEntity.ok(jobInfo);
Expand Down