From b79b6a2ce9282fb7c70f41f3288c84d4002b1bcd Mon Sep 17 00:00:00 2001 From: stvort Date: Wed, 26 Feb 2020 01:07:58 +0400 Subject: [PATCH 1/3] 2019-11 spring-batch-demo added --- .../spring-batch-demo/.gitignore | 6 + .../spring-batch-demo/entries.csv | 16 ++ .../spring-batch-demo/expected_output.dat | 16 ++ .../spring-batch-demo/pom.xml | 113 ++++++++++++++ .../ru/otus/example/springbatch/Main.java | 17 +++ .../chandgelogs/InitMongoDBDataChangeLog.java | 45 ++++++ .../example/springbatch/config/AppProps.java | 21 +++ .../springbatch/config/BatchConfig.java | 43 ++++++ .../example/springbatch/config/JobConfig.java | 138 ++++++++++++++++++ .../springbatch/config/MongoConfig.java | 24 +++ .../example/springbatch/model/Person.java | 13 ++ .../service/HappyBirthdayService.java | 13 ++ .../springbatch/shell/BatchCommands.java | 56 +++++++ .../src/main/resources/application.yml | 31 ++++ .../springbatch/config/ImportUserJobTest.java | 59 ++++++++ .../src/test/resources/application.yml | 19 +++ 16 files changed, 630 insertions(+) create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/.gitignore create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/entries.csv create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/expected_output.dat create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/pom.xml create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/Main.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/chandgelogs/InitMongoDBDataChangeLog.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/AppProps.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/BatchConfig.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/JobConfig.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/MongoConfig.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/model/Person.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/service/HappyBirthdayService.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/shell/BatchCommands.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/main/resources/application.yml create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/test/java/ru/otus/example/springbatch/config/ImportUserJobTest.java create mode 100644 2019-11/spring-25-spring-batch/spring-batch-demo/src/test/resources/application.yml diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/.gitignore b/2019-11/spring-25-spring-batch/spring-batch-demo/.gitignore new file mode 100644 index 00000000..04e0ae48 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/.gitignore @@ -0,0 +1,6 @@ +.idea/ +*.iml + +target/ + +output.csv diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/entries.csv b/2019-11/spring-25-spring-batch/spring-batch-demo/entries.csv new file mode 100644 index 00000000..bde433ce --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/entries.csv @@ -0,0 +1,16 @@ +Ivan,23 +John,24 +Ivan,23 +John,24 +Ivan,23 +Mary,24 +Ivan,23 +John,24 +Sunny,23 +John,24 +Ivan,23 +John,24 +Ivan,23 +John,24 +Ivan,23 +John,24 diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/expected_output.dat b/2019-11/spring-25-spring-batch/spring-batch-demo/expected_output.dat new file mode 100644 index 00000000..b4c926b1 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/expected_output.dat @@ -0,0 +1,16 @@ +Person(name=Ivan, age=24) +Person(name=John, age=25) +Person(name=Ivan, age=24) +Person(name=John, age=25) +Person(name=Ivan, age=24) +Person(name=Mary, age=25) +Person(name=Ivan, age=24) +Person(name=John, age=25) +Person(name=Sunny, age=24) +Person(name=John, age=25) +Person(name=Ivan, age=24) +Person(name=John, age=25) +Person(name=Ivan, age=24) +Person(name=John, age=25) +Person(name=Ivan, age=24) +Person(name=John, age=25) diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/pom.xml b/2019-11/spring-25-spring-batch/spring-batch-demo/pom.xml new file mode 100644 index 00000000..bda68754 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + + ru.otus.example + spring-batch-demo + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.2.4.RELEASE + + + + 13 + 13 + 13 + 2.0.2 + + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-batch + + + + com.h2database + h2 + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + LATEST + + + + com.github.cloudyrock.mongock + mongock-spring + ${mongock.version} + + + + org.springframework.boot + spring-boot-starter-web + 2.1.8.RELEASE + + + + org.projectlombok + lombok + true + + + + org.springframework.shell + spring-shell-starter + 2.0.1.RELEASE + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.batch + spring-batch-test + test + + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} + test + + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + + + spring-batch-demo + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/Main.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/Main.java new file mode 100644 index 00000000..d2d0768d --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/Main.java @@ -0,0 +1,17 @@ +package ru.otus.example.springbatch; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +import java.io.IOException; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) throws IOException { + SpringApplication.run(Main.class, args); + } +} + + diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/chandgelogs/InitMongoDBDataChangeLog.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/chandgelogs/InitMongoDBDataChangeLog.java new file mode 100644 index 00000000..274a0a86 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/chandgelogs/InitMongoDBDataChangeLog.java @@ -0,0 +1,45 @@ +package ru.otus.example.springbatch.chandgelogs; + +import com.github.cloudyrock.mongock.ChangeLog; +import com.github.cloudyrock.mongock.ChangeSet; +import com.mongodb.client.MongoDatabase; +import org.springframework.data.mongodb.core.MongoTemplate; +import ru.otus.example.springbatch.model.Person; + +@ChangeLog(order = "001") +public class InitMongoDBDataChangeLog { + + @ChangeSet(order = "000", id = "dropDB", author = "stvort", runAlways = true) + public void dropDB(MongoDatabase database){ + database.drop(); + } + + @ChangeSet(order = "001", id = "initPersons", author = "stvort", runAlways = true) + public void initPersons(MongoTemplate template){ + template.save(new Person("John", 21)); + template.save(new Person("Ivan", 32)); + template.save(new Person("Dima", 52)); + template.save(new Person("Mike", 22)); + template.save(new Person("Duke", 33)); + template.save(new Person("John", 21)); + template.save(new Person("Ivan", 32)); + template.save(new Person("Dima", 52)); + template.save(new Person("Mike", 22)); + template.save(new Person("Duke", 33)); + template.save(new Person("John", 21)); + template.save(new Person("Ivan", 32)); + template.save(new Person("Dima", 52)); + template.save(new Person("Mike", 22)); + template.save(new Person("Duke", 33)); + template.save(new Person("John", 21)); + template.save(new Person("Ivan", 32)); + template.save(new Person("Dima", 52)); + template.save(new Person("Mike", 22)); + template.save(new Person("Duke", 33)); + template.save(new Person("John", 21)); + template.save(new Person("Ivan", 32)); + template.save(new Person("Dima", 52)); + template.save(new Person("Mike", 22)); + template.save(new Person("Duke", 33)); + } +} diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/AppProps.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/AppProps.java new file mode 100644 index 00000000..1e704a2d --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/AppProps.java @@ -0,0 +1,21 @@ +package ru.otus.example.springbatch.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +@Data +@Component +public class AppProps { + + @Value("${spring.data.mongodb.database}") + private String mongoDBName; + + @Value("${app.input-file:''}") + private String inputFileName; + + @Value("${app.output-file:''}") + private String outputFileName; + +} diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/BatchConfig.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/BatchConfig.java new file mode 100644 index 00000000..c2649770 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/BatchConfig.java @@ -0,0 +1,43 @@ +package ru.otus.example.springbatch.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.*; +import org.springframework.batch.core.configuration.JobRegistry; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor; +import org.springframework.batch.core.job.flow.FlowJob; +import org.springframework.batch.core.launch.support.RunIdIncrementer; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.file.FlatFileItemReader; +import org.springframework.batch.item.file.FlatFileItemWriter; +import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; +import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder; +import org.springframework.batch.item.file.transform.DelimitedLineAggregator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.FileSystemResource; +import org.springframework.transaction.PlatformTransactionManager; +import ru.otus.example.springbatch.model.Person; +import ru.otus.example.springbatch.service.HappyBirthdayService; + +import java.util.List; + +@EnableBatchProcessing +@Configuration +public class BatchConfig { + @Bean + public JobRegistryBeanPostProcessor postProcessor(JobRegistry jobRegistry) { + var processor = new JobRegistryBeanPostProcessor(); + processor.setJobRegistry(jobRegistry); + return processor; + } + +} diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/JobConfig.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/JobConfig.java new file mode 100644 index 00000000..edaf8645 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/JobConfig.java @@ -0,0 +1,138 @@ +package ru.otus.example.springbatch.config; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.*; +import org.springframework.batch.core.configuration.JobRegistry; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor; +import org.springframework.batch.core.launch.support.RunIdIncrementer; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.file.FlatFileItemReader; +import org.springframework.batch.item.file.FlatFileItemWriter; +import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; +import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder; +import org.springframework.batch.item.file.transform.DelimitedLineAggregator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.FileSystemResource; +import ru.otus.example.springbatch.model.Person; +import ru.otus.example.springbatch.service.HappyBirthdayService; + +import java.util.List; + +@SuppressWarnings("all") +@Configuration +public class JobConfig { + private static final int CHUNK_SIZE = 5; + private final Logger logger = LoggerFactory.getLogger("Batch"); + + public static final String OUTPUT_FILE_NAME = "outputFileName"; + public static final String INPUT_FILE_NAME = "inputFileName"; + public static final String IMPORT_USER_JOB_NAME = "importUserJob"; + + @Autowired + private JobBuilderFactory jobBuilderFactory; + + @Autowired + private StepBuilderFactory stepBuilderFactory; + + @StepScope + @Bean + public FlatFileItemReader reader(@Value("#{jobParameters['" + INPUT_FILE_NAME + "']}") String inputFileName) { + return new FlatFileItemReaderBuilder() + .name("personItemReader") + .resource(new FileSystemResource(inputFileName)) + + // Работа через lineMapper + .lineMapper((s, i) -> { + String[] fieldsValues = s.split(","); + return new Person(fieldsValues[0], Integer.parseInt(fieldsValues[1])); + }) +/* + // Работа через fieldSetMapper + .delimited() + .names("name", "age") + .fieldSetMapper(new BeanWrapperFieldSetMapper<>() {{ + setTargetType(Person.class); + }}) +*/ + .build(); + } + + + + @StepScope + @Bean + public ItemProcessor processor(HappyBirthdayService happyBirthdayService) { + return (ItemProcessor) happyBirthdayService::doHappyBirthday; + } + + @StepScope + @Bean + public FlatFileItemWriter writer(@Value("#{jobParameters['" + OUTPUT_FILE_NAME + "']}") String outputFileName) { + return new FlatFileItemWriterBuilder<>() + .name("personItemWriter") + .resource(new FileSystemResource(outputFileName)) + .lineAggregator(new DelimitedLineAggregator<>()) + .build(); + } + + @Bean + public Job importUserJob(Step step1) { + return jobBuilderFactory.get(IMPORT_USER_JOB_NAME) + .incrementer(new RunIdIncrementer()) + .flow(step1) + .end() + .listener(new JobExecutionListener() { + @Override + public void beforeJob(JobExecution jobExecution) { + logger.info("Начало job"); + } + + @Override + public void afterJob(JobExecution jobExecution) { + logger.info("Конец job"); + } + }) + .build(); + } + + @Bean + public Step step1(FlatFileItemWriter writer, ItemReader reader, ItemProcessor itemProcessor) { + return stepBuilderFactory.get("step1") + .chunk(CHUNK_SIZE) + .reader(reader) + .processor(itemProcessor) + .writer(writer) + .listener(new ItemReadListener() { + public void beforeRead() { logger.info("Начало чтения"); } + public void afterRead(Object o) { logger.info("Конец чтения"); } + public void onReadError(Exception e) { logger.info("Ошибка чтения"); } + }) + .listener(new ItemWriteListener() { + public void beforeWrite(List list) { logger.info("Начало записи"); } + public void afterWrite(List list) { logger.info("Конец записи"); } + public void onWriteError(Exception e, List list) { logger.info("Ошибка записи"); } + }) + .listener(new ItemProcessListener() { + public void beforeProcess(Object o) {logger.info("Начало обработки");} + public void afterProcess(Object o, Object o2) {logger.info("Конец обработки");} + public void onProcessError(Object o, Exception e) {logger.info("Ошбка обработки");} + }) + .listener(new ChunkListener() { + public void beforeChunk(ChunkContext chunkContext) {logger.info("Начало пачки");} + public void afterChunk(ChunkContext chunkContext) {logger.info("Конец пачки");} + public void afterChunkError(ChunkContext chunkContext) {logger.info("Ошибка пачки");} + }) +// .taskExecutor(new SimpleAsyncTaskExecutor()) + .build(); + } +} diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/MongoConfig.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/MongoConfig.java new file mode 100644 index 00000000..9d7eb407 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/config/MongoConfig.java @@ -0,0 +1,24 @@ +package ru.otus.example.springbatch.config; + +import com.github.cloudyrock.mongock.Mongock; +import com.github.cloudyrock.mongock.SpringMongockBuilder; +import com.mongodb.MongoClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.otus.example.springbatch.chandgelogs.InitMongoDBDataChangeLog; + +@Configuration +public class MongoConfig { + + @Autowired + private AppProps appProps; + + @Bean + public Mongock mongock(MongoClient mongoClient) { + return new SpringMongockBuilder(mongoClient, appProps.getMongoDBName(), + InitMongoDBDataChangeLog.class.getPackageName()) + .build(); + } +} diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/model/Person.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/model/Person.java new file mode 100644 index 00000000..b95cb1ff --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/model/Person.java @@ -0,0 +1,13 @@ +package ru.otus.example.springbatch.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +@Data +public class Person { + private String name; + private int age; +} diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/service/HappyBirthdayService.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/service/HappyBirthdayService.java new file mode 100644 index 00000000..00ec7287 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/service/HappyBirthdayService.java @@ -0,0 +1,13 @@ +package ru.otus.example.springbatch.service; + +import org.springframework.stereotype.Service; +import ru.otus.example.springbatch.model.Person; + +@Service +public class HappyBirthdayService { + + public Person doHappyBirthday(Person person){ + person.setAge(person.getAge() + 1); + return person; + } +} diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/shell/BatchCommands.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/shell/BatchCommands.java new file mode 100644 index 00000000..0e0cfea1 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/java/ru/otus/example/springbatch/shell/BatchCommands.java @@ -0,0 +1,56 @@ +package ru.otus.example.springbatch.shell; + +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.explore.JobExplorer; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.JobOperator; +import org.springframework.shell.standard.ShellComponent; +import org.springframework.shell.standard.ShellMethod; +import ru.otus.example.springbatch.config.AppProps; + + +import static ru.otus.example.springbatch.config.JobConfig.*; + +@RequiredArgsConstructor +@ShellComponent +public class BatchCommands { + + private final AppProps appProps; + private final Job importUserJob; + + private final JobLauncher jobLauncher; + private final JobOperator jobOperator; + private final JobExplorer jobExplorer; + + //http://localhost:8080/h2-console/ + + @SneakyThrows + @ShellMethod(value = "startMigrationJobWithJobLauncher", key = "sm-jl") + public void startMigrationJobWithJobLauncher() { + JobExecution execution = jobLauncher.run(importUserJob, new JobParametersBuilder() + .addString(INPUT_FILE_NAME, appProps.getInputFileName()) + .addString(OUTPUT_FILE_NAME, appProps.getOutputFileName()) + .toJobParameters()); + System.out.println(execution); + } + + @SneakyThrows + @ShellMethod(value = "startMigrationJobWithJobOperator", key = "sm-jo") + public void startMigrationJobWithJobOperator() { + Long executionId = jobOperator.start(IMPORT_USER_JOB_NAME, + INPUT_FILE_NAME + "=" + appProps.getInputFileName() + "\n" + + OUTPUT_FILE_NAME + "=" + appProps.getOutputFileName() + ); + System.out.println(jobOperator.getSummary(executionId)); + } + + @ShellMethod(value = "showInfo", key = "i") + public void showInfo() { + System.out.println(jobExplorer.getJobNames()); + System.out.println(jobExplorer.getLastJobInstance(IMPORT_USER_JOB_NAME)); + } +} diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/resources/application.yml b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/resources/application.yml new file mode 100644 index 00000000..a9bbf414 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/main/resources/application.yml @@ -0,0 +1,31 @@ +spring: + batch: + job: + enabled: false + shell: + interactive: + enabled: true + + datasource: + url: jdbc:h2:mem:testdb + driverClassName: org.h2.Driver + username: sa + password: + + h2: + console: + enabled: true + path: /h2-console + + data: + mongodb: + uri: mongodb://localhost + port: 0 #27017 + database: SpringBatchExampleDB + +app: + ages-count-to-add: 1 + input-file: entries.csv + output-file: output.dat + +#debug: true diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/test/java/ru/otus/example/springbatch/config/ImportUserJobTest.java b/2019-11/spring-25-spring-batch/spring-batch-demo/src/test/java/ru/otus/example/springbatch/config/ImportUserJobTest.java new file mode 100644 index 00000000..5a9fa468 --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/test/java/ru/otus/example/springbatch/config/ImportUserJobTest.java @@ -0,0 +1,59 @@ +package ru.otus.example.springbatch.config; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.test.AssertFile; +import org.springframework.batch.test.JobLauncherTestUtils; +import org.springframework.batch.test.JobRepositoryTestUtils; +import org.springframework.batch.test.context.SpringBatchTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.io.FileSystemResource; + + +import static org.assertj.core.api.Assertions.assertThat; +import static ru.otus.example.springbatch.config.JobConfig.*; + +@SpringBootTest +@SpringBatchTest +class ImportUserJobTest { + + private static final String TEST_INPUT_FILE_NAME = "entries.csv"; + private static final String EXPECTED_OUTPUT_FILE_NAME = "expected_output.dat"; + private static final String TEST_OUTPUT_FILE_NAME = "test_output.dat"; + + @Autowired + private JobLauncherTestUtils jobLauncherTestUtils; + + @Autowired + private JobRepositoryTestUtils jobRepositoryTestUtils; + + @BeforeEach + void clearMetaData() { + jobRepositoryTestUtils.removeJobExecutions(); + } + + @Test + void testJob() throws Exception { + FileSystemResource expectedResult = new FileSystemResource(EXPECTED_OUTPUT_FILE_NAME); + FileSystemResource actualResult = new FileSystemResource(TEST_OUTPUT_FILE_NAME); + + Job job = jobLauncherTestUtils.getJob(); + assertThat(job).isNotNull() + .extracting(Job::getName) + .isEqualTo(IMPORT_USER_JOB_NAME); + + JobParameters parameters = new JobParametersBuilder() + .addString(INPUT_FILE_NAME, TEST_INPUT_FILE_NAME) + .addString(OUTPUT_FILE_NAME, TEST_OUTPUT_FILE_NAME) + .toJobParameters(); + JobExecution jobExecution = jobLauncherTestUtils.launchJob(parameters); + + assertThat(jobExecution.getExitStatus().getExitCode()).isEqualTo("COMPLETED"); + AssertFile.assertFileEquals(expectedResult, actualResult); + } +} \ No newline at end of file diff --git a/2019-11/spring-25-spring-batch/spring-batch-demo/src/test/resources/application.yml b/2019-11/spring-25-spring-batch/spring-batch-demo/src/test/resources/application.yml new file mode 100644 index 00000000..61fa4c4b --- /dev/null +++ b/2019-11/spring-25-spring-batch/spring-batch-demo/src/test/resources/application.yml @@ -0,0 +1,19 @@ +spring: + batch: + job: + enabled: false + shell: + interactive: + enabled: false + + datasource: + url: jdbc:h2:mem:testdb + driverClassName: org.h2.Driver + username: sa + password: + + data: + mongodb: + uri: mongodb://localhost + port: 0 + database: SpringBatchTestExampleDB \ No newline at end of file From 38c1cbe4e71ecccdbcaa46b14d427e28ad69b2f6 Mon Sep 17 00:00:00 2001 From: Yuriy Dvorzhetskiy Date: Wed, 26 Feb 2020 20:50:01 +0600 Subject: [PATCH 2/3] 2020-02 - 00,01 --- 2020-02/junit/.gitignore | 24 ++++++++++++ 2020-02/junit/pom.xml | 37 +++++++++++++++++++ .../java/ru/otus/junit/dao/PersonDao.java | 16 ++++++++ .../java/ru/otus/junit/dao/PersonDaoImpl.java | 36 ++++++++++++++++++ .../junit/dao/PersonNotFoundException.java | 8 ++++ .../java/ru/otus/junit/domain/Person.java | 32 ++++++++++++++++ .../ru/otus/junit/service/PersonService.java | 16 ++++++++ .../otus/junit/service/PersonServiceImpl.java | 37 +++++++++++++++++++ .../java/ru/otus/junit/domain/PersonTest.java | 23 ++++++++++++ .../junit/service/PersonServiceImplTest.java | 37 +++++++++++++++++++ 2020-02/spring-01/.gitignore | 24 ++++++++++++ 2020-02/spring-01/pom.xml | 17 +++++++++ 2020-02/spring-01/spring-01-exercise/pom.xml | 20 ++++++++++ .../src/main/java/ru/otus/spring/Main.java | 17 +++++++++ .../java/ru/otus/spring/dao/PersonDao.java | 8 ++++ .../ru/otus/spring/dao/PersonDaoSimple.java | 10 +++++ .../java/ru/otus/spring/domain/Person.java | 20 ++++++++++ .../ru/otus/spring/service/PersonService.java | 8 ++++ .../spring/service/PersonServiceImpl.java | 17 +++++++++ .../src/main/resources/spring-context.xml | 11 ++++++ 2020-02/spring-01/spring-01-solution/pom.xml | 24 ++++++++++++ .../src/main/java/ru/otus/spring/Main.java | 20 ++++++++++ .../java/ru/otus/spring/dao/PersonDao.java | 8 ++++ .../ru/otus/spring/dao/PersonDaoSimple.java | 10 +++++ .../java/ru/otus/spring/domain/Person.java | 20 ++++++++++ .../ru/otus/spring/service/PersonService.java | 8 ++++ .../spring/service/PersonServiceImpl.java | 17 +++++++++ .../src/main/resources/spring-context.xml | 14 +++++++ 28 files changed, 539 insertions(+) create mode 100644 2020-02/junit/.gitignore create mode 100644 2020-02/junit/pom.xml create mode 100644 2020-02/junit/src/main/java/ru/otus/junit/dao/PersonDao.java create mode 100644 2020-02/junit/src/main/java/ru/otus/junit/dao/PersonDaoImpl.java create mode 100644 2020-02/junit/src/main/java/ru/otus/junit/dao/PersonNotFoundException.java create mode 100644 2020-02/junit/src/main/java/ru/otus/junit/domain/Person.java create mode 100644 2020-02/junit/src/main/java/ru/otus/junit/service/PersonService.java create mode 100644 2020-02/junit/src/main/java/ru/otus/junit/service/PersonServiceImpl.java create mode 100644 2020-02/junit/src/test/java/ru/otus/junit/domain/PersonTest.java create mode 100644 2020-02/junit/src/test/java/ru/otus/junit/service/PersonServiceImplTest.java create mode 100644 2020-02/spring-01/.gitignore create mode 100644 2020-02/spring-01/pom.xml create mode 100644 2020-02/spring-01/spring-01-exercise/pom.xml create mode 100644 2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/Main.java create mode 100644 2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/dao/PersonDao.java create mode 100644 2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java create mode 100644 2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/service/PersonService.java create mode 100644 2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/service/PersonServiceImpl.java create mode 100644 2020-02/spring-01/spring-01-exercise/src/main/resources/spring-context.xml create mode 100644 2020-02/spring-01/spring-01-solution/pom.xml create mode 100644 2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/Main.java create mode 100644 2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/dao/PersonDao.java create mode 100644 2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java create mode 100644 2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/service/PersonService.java create mode 100644 2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/service/PersonServiceImpl.java create mode 100644 2020-02/spring-01/spring-01-solution/src/main/resources/spring-context.xml diff --git a/2020-02/junit/.gitignore b/2020-02/junit/.gitignore new file mode 100644 index 00000000..4ea52072 --- /dev/null +++ b/2020-02/junit/.gitignore @@ -0,0 +1,24 @@ +target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ diff --git a/2020-02/junit/pom.xml b/2020-02/junit/pom.xml new file mode 100644 index 00000000..cdc69557 --- /dev/null +++ b/2020-02/junit/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + ru.otus + junit + 1.0 + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.1.RELEASE + + + + + 11 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + diff --git a/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonDao.java b/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonDao.java new file mode 100644 index 00000000..6ff0d1ef --- /dev/null +++ b/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonDao.java @@ -0,0 +1,16 @@ +package ru.otus.junit.dao; + +import ru.otus.junit.domain.Person; + +import java.util.List; + +public interface PersonDao { + + Person getByName(String name) throws PersonNotFoundException; + + List getAll(); + + void deleteByName(String name) throws PersonNotFoundException; + + void save(Person person); +} diff --git a/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonDaoImpl.java b/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonDaoImpl.java new file mode 100644 index 00000000..efe93ef7 --- /dev/null +++ b/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonDaoImpl.java @@ -0,0 +1,36 @@ +package ru.otus.junit.dao; + +import ru.otus.junit.domain.Person; + +import java.util.List; + +public class PersonDaoImpl implements PersonDao { + + // TODO: добавить поле - список Person-ов + + @Override + public Person getByName(String name) throws PersonNotFoundException { + // TODO: реализовать поиск в списке по имени (по технике Test-First) + // TODO: да, этот метод может бросать Exception, и это нужно покрыть другим тестом + return null; + } + + @Override + public List getAll() { + // TODO: реализовать получние всех Person (по технике Test-First) + return null; + } + + @Override + public void deleteByName(String name) throws PersonNotFoundException { + // TODO: реализовать удаление по имени (по технике Test-First) + // TODO: да, этот метод может бросать Exception, и это нужно покрыть другим тестом + } + + @Override + public void save(Person person) { + // TODO: этот метод должен найти по имени в списке + // TODO: если такой есть - заменить + // TODO: если такого нет - добавить + } +} diff --git a/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonNotFoundException.java b/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonNotFoundException.java new file mode 100644 index 00000000..12f78d77 --- /dev/null +++ b/2020-02/junit/src/main/java/ru/otus/junit/dao/PersonNotFoundException.java @@ -0,0 +1,8 @@ +package ru.otus.junit.dao; + +public class PersonNotFoundException extends RuntimeException { + + public PersonNotFoundException(String message) { + super(message); + } +} diff --git a/2020-02/junit/src/main/java/ru/otus/junit/domain/Person.java b/2020-02/junit/src/main/java/ru/otus/junit/domain/Person.java new file mode 100644 index 00000000..10d5294c --- /dev/null +++ b/2020-02/junit/src/main/java/ru/otus/junit/domain/Person.java @@ -0,0 +1,32 @@ +package ru.otus.junit.domain; + +@SuppressWarnings({"WeakerAccess", "unused"}) +public class Person { + + private int age; + private String name; + + public Person(int age, String name) { + this.age = age; + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void birthDay() { + this.age++; + } +} diff --git a/2020-02/junit/src/main/java/ru/otus/junit/service/PersonService.java b/2020-02/junit/src/main/java/ru/otus/junit/service/PersonService.java new file mode 100644 index 00000000..0cb144f1 --- /dev/null +++ b/2020-02/junit/src/main/java/ru/otus/junit/service/PersonService.java @@ -0,0 +1,16 @@ +package ru.otus.junit.service; + +import ru.otus.junit.domain.Person; + +import java.util.List; + +public interface PersonService { + + Person getByName(String name); + + List getAll(); + + boolean existsWithName(String name); + + void save(Person p); +} diff --git a/2020-02/junit/src/main/java/ru/otus/junit/service/PersonServiceImpl.java b/2020-02/junit/src/main/java/ru/otus/junit/service/PersonServiceImpl.java new file mode 100644 index 00000000..52b82f10 --- /dev/null +++ b/2020-02/junit/src/main/java/ru/otus/junit/service/PersonServiceImpl.java @@ -0,0 +1,37 @@ +package ru.otus.junit.service; + +import ru.otus.junit.dao.PersonDao; +import ru.otus.junit.domain.Person; + +import java.util.List; + +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + @Override + public Person getByName(String name) { + return dao.getByName(name); + } + + @Override + public List getAll() { + // TODO: реализовать данный метод по технике Test-First + return null; + } + + @Override + public boolean existsWithName(String name) { + // TODO: реализовать данный метод по технике Test-First + return false; + } + + @Override + public void save(Person p) { + // TODO: реализовать данный метод по технике Test-First + } +} diff --git a/2020-02/junit/src/test/java/ru/otus/junit/domain/PersonTest.java b/2020-02/junit/src/test/java/ru/otus/junit/domain/PersonTest.java new file mode 100644 index 00000000..30366c3f --- /dev/null +++ b/2020-02/junit/src/test/java/ru/otus/junit/domain/PersonTest.java @@ -0,0 +1,23 @@ +package ru.otus.junit.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DisplayName("Класс Person") +class PersonTest { + + @DisplayName("корректно создаётся конструктором") + @Test + void shouldHaveCorrectConstructor() { + Person person = new Person(42, "Ivan"); + + assertEquals("Ivan", person.getName()); + assertEquals(42, person.getAge()); + } + + // TODO: @DisplayName("должен") + + // TODO: @DisplayName("должен увеличивать возраст при вызове birthDay") +} diff --git a/2020-02/junit/src/test/java/ru/otus/junit/service/PersonServiceImplTest.java b/2020-02/junit/src/test/java/ru/otus/junit/service/PersonServiceImplTest.java new file mode 100644 index 00000000..47fa7a7e --- /dev/null +++ b/2020-02/junit/src/test/java/ru/otus/junit/service/PersonServiceImplTest.java @@ -0,0 +1,37 @@ +package ru.otus.junit.service; + +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 ru.otus.junit.dao.PersonDao; +import ru.otus.junit.domain.Person; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; + +@ExtendWith(MockitoExtension.class) +class PersonServiceImplTest { + + @Mock + private PersonDao personDao; + + private PersonService personService; + + @BeforeEach + void setUp() { + personService = new PersonServiceImpl(personDao); + } + + @Test + void getByName() { + // TODO: используйте eq() mapper вместо any() + given(personDao.getByName(any())) + .willReturn(new Person(10, "Ivan")); + + assertThat(personService.getByName("Ivan")) + .isNotNull(); // TODO: сравните с помощью equals + } +} diff --git a/2020-02/spring-01/.gitignore b/2020-02/spring-01/.gitignore new file mode 100644 index 00000000..4ea52072 --- /dev/null +++ b/2020-02/spring-01/.gitignore @@ -0,0 +1,24 @@ +target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ diff --git a/2020-02/spring-01/pom.xml b/2020-02/spring-01/pom.xml new file mode 100644 index 00000000..6658aaa0 --- /dev/null +++ b/2020-02/spring-01/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + ru.otus + spring-01 + 1.0 + + pom + + + spring-01-exercise + spring-01-solution + + diff --git a/2020-02/spring-01/spring-01-exercise/pom.xml b/2020-02/spring-01/spring-01-exercise/pom.xml new file mode 100644 index 00000000..e3aa2772 --- /dev/null +++ b/2020-02/spring-01/spring-01-exercise/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + ru.otus + spring-01-exercise + 1.0 + + + 11 + 11 + UTF-8 + + + + + + diff --git a/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/Main.java b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..e3201a16 --- /dev/null +++ b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,17 @@ +package ru.otus.spring; + +//import org.springframework.context.support.ClassPathXmlApplicationContext; +import ru.otus.spring.domain.Person; + +public class Main { + + public static void main(String[] args) { + // TODO: создайте здесь класс контекста + + // TODO: Получите Person Service + + // Получите Person "Ivan" + Person ivan = null; + System.out.println("name: " + ivan.getName() + " age: " + ivan.getAge()); + } +} diff --git a/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/dao/PersonDao.java b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/dao/PersonDao.java new file mode 100644 index 00000000..d33939bd --- /dev/null +++ b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java new file mode 100644 index 00000000..7f7c97c6 --- /dev/null +++ b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java @@ -0,0 +1,10 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public class PersonDaoSimple implements PersonDao { + + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/domain/Person.java b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..b19b42c1 --- /dev/null +++ b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,20 @@ +package ru.otus.spring.domain; + +public class Person { + + private String name; + private int age; + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } +} diff --git a/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/service/PersonService.java b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/service/PersonService.java new file mode 100644 index 00000000..9b83e7de --- /dev/null +++ b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.spring.service; + +import ru.otus.spring.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/service/PersonServiceImpl.java b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/service/PersonServiceImpl.java new file mode 100644 index 00000000..794c29dd --- /dev/null +++ b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/service/PersonServiceImpl.java @@ -0,0 +1,17 @@ +package ru.otus.spring.service; + +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.domain.Person; + +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2020-02/spring-01/spring-01-exercise/src/main/resources/spring-context.xml b/2020-02/spring-01/spring-01-exercise/src/main/resources/spring-context.xml new file mode 100644 index 00000000..2cb9eabe --- /dev/null +++ b/2020-02/spring-01/spring-01-exercise/src/main/resources/spring-context.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/2020-02/spring-01/spring-01-solution/pom.xml b/2020-02/spring-01/spring-01-solution/pom.xml new file mode 100644 index 00000000..734d9a3c --- /dev/null +++ b/2020-02/spring-01/spring-01-solution/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + ru.otus + spring-01-solution + 1.0 + + + 11 + 11 + UTF-8 + + + + + org.springframework + spring-context + 5.2.3.RELEASE + + + diff --git a/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/Main.java b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..f5b2fafb --- /dev/null +++ b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,20 @@ +package ru.otus.spring; + +import org.springframework.context.support.ClassPathXmlApplicationContext; +import ru.otus.spring.domain.Person; +import ru.otus.spring.service.PersonService; + +public class Main { + + public static void main(String[] args) { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml"); + PersonService service = context.getBean(PersonService.class); + Person ivan = service.getByName("Ivan"); + System.out.println("name: " + ivan.getName() + " age: " + ivan.getAge()); + + // Данная операция, в принципе не нужна. + // Мы не работаем пока что с БД, а Spring Boot сделает закрытие за нас + // Подробности - через пару занятий + context.close(); + } +} diff --git a/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/dao/PersonDao.java b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/dao/PersonDao.java new file mode 100644 index 00000000..d33939bd --- /dev/null +++ b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/dao/PersonDao.java @@ -0,0 +1,8 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public interface PersonDao { + + Person findByName(String name); +} diff --git a/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java new file mode 100644 index 00000000..7f7c97c6 --- /dev/null +++ b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/dao/PersonDaoSimple.java @@ -0,0 +1,10 @@ +package ru.otus.spring.dao; + +import ru.otus.spring.domain.Person; + +public class PersonDaoSimple implements PersonDao { + + public Person findByName(String name) { + return new Person(name, 18); + } +} diff --git a/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/domain/Person.java b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..b19b42c1 --- /dev/null +++ b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,20 @@ +package ru.otus.spring.domain; + +public class Person { + + private String name; + private int age; + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } +} diff --git a/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/service/PersonService.java b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/service/PersonService.java new file mode 100644 index 00000000..9b83e7de --- /dev/null +++ b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/service/PersonService.java @@ -0,0 +1,8 @@ +package ru.otus.spring.service; + +import ru.otus.spring.domain.Person; + +public interface PersonService { + + Person getByName(String name); +} diff --git a/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/service/PersonServiceImpl.java b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/service/PersonServiceImpl.java new file mode 100644 index 00000000..794c29dd --- /dev/null +++ b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/service/PersonServiceImpl.java @@ -0,0 +1,17 @@ +package ru.otus.spring.service; + +import ru.otus.spring.dao.PersonDao; +import ru.otus.spring.domain.Person; + +public class PersonServiceImpl implements PersonService { + + private final PersonDao dao; + + public PersonServiceImpl(PersonDao dao) { + this.dao = dao; + } + + public Person getByName(String name) { + return dao.findByName(name); + } +} diff --git a/2020-02/spring-01/spring-01-solution/src/main/resources/spring-context.xml b/2020-02/spring-01/spring-01-solution/src/main/resources/spring-context.xml new file mode 100644 index 00000000..c3541cec --- /dev/null +++ b/2020-02/spring-01/spring-01-solution/src/main/resources/spring-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + From fbf9b1995103f03b56b0aa0f5f0da1c9fc871699 Mon Sep 17 00:00:00 2001 From: Yuriy Dvorzhetskiy Date: Wed, 26 Feb 2020 21:13:05 +0600 Subject: [PATCH 3/3] 2020-02 - 01: final in fields --- .../src/main/java/ru/otus/spring/domain/Person.java | 4 ++-- .../src/main/java/ru/otus/spring/domain/Person.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/domain/Person.java b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/domain/Person.java index b19b42c1..c23be0c6 100644 --- a/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/domain/Person.java +++ b/2020-02/spring-01/spring-01-exercise/src/main/java/ru/otus/spring/domain/Person.java @@ -2,8 +2,8 @@ package ru.otus.spring.domain; public class Person { - private String name; - private int age; + private final String name; + private final int age; public Person(String name, int age) { this.name = name; diff --git a/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/domain/Person.java b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/domain/Person.java index b19b42c1..c23be0c6 100644 --- a/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/domain/Person.java +++ b/2020-02/spring-01/spring-01-solution/src/main/java/ru/otus/spring/domain/Person.java @@ -2,8 +2,8 @@ package ru.otus.spring.domain; public class Person { - private String name; - private int age; + private final String name; + private final int age; public Person(String name, int age) { this.name = name;