[linux] shell script version compare
개요 linux를 사용하다 보면 version 비교하는 기능이 필요합니다. 특히 기존 설치된 패키지의 version을 확인하여 업데이트할 경우가 있겠죠. 아래와 같이 간단한 shell script로 구현할 수 있습니다.
spring boot3가 release되면서 spring batch 5로 업그레이드 되었습니다.
간단하게 종속성 업그레이드로 끝나는것이 아니라 DB 스키마 변경과 jobBuilder, stepBuilder 작동 방식도 변경되었습니다.
이 부분에 대해 간단하게 정리하도록 하겠습니다.
spring batch 5는 jdk 17이 최소 사양인 spring framework 6 기반으로 합니다.
javax 패키지는 전부 다 jakarta로 변경해야 합니다.
oracle과 sql-server인 경우는 sequence 관련 업데이트가 있습니다.
그외 모든 플랫폼은 아래와 같은 스키마 변경 사항이 있습니다.
JOB_CONFIGURATION_LOCATION 컬럼은 사용되지 않습니다.
아래 쿼리로 컬럼을 삭제하도록 합니다.
ALTER TABLE BATCH_JOB_EXECUTION DROP COLUMN JOB_CONFIGURATION_LOCATION;
batch parameter로 사용되던 string, date, long, double형 대신 <T>
제레릭으로 받을수 있게 변경되었습니다.
그리하여 각 해당 컬럼들은 삭제되고 PARAMETER_NAME, PARAMETER_TYPE, PARAMETER_VALUE 컬럼이 새로 생성되었죠.
CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
JOB_EXECUTION_ID BIGINT NOT NULL ,
--- TYPE_CD VARCHAR(6) NOT NULL ,
--- KEY_NAME VARCHAR(100) NOT NULL ,
--- STRING_VAL VARCHAR(250) ,
--- DATE_VAL DATETIME(6) DEFAULT NULL ,
--- LONG_VAL BIGINT ,
--- DOUBLE_VAL DOUBLE PRECISION ,
+++ PARAMETER_NAME VARCHAR(100) NOT NULL ,
+++ PARAMETER_TYPE VARCHAR(100) NOT NULL ,
+++ PARAMETER_VALUE VARCHAR(2500) ,
IDENTIFYING CHAR(1) NOT NULL ,
constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
);
아래 쿼리를 통해 변경하도록 합니다.
ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN DATE_VAL;
ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN LONG_VAL;
ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN DOUBLE_VAL;
ALTER TABLE BATCH_JOB_EXECUTION_PARAMS CHANGE COLUMN TYPE_CD PARAMETER_TYPE VARCHAR(100);
ALTER TABLE BATCH_JOB_EXECUTION_PARAMS CHANGE COLUMN KEY_NAME PARAMETER_NAME VARCHAR(100);
ALTER TABLE BATCH_JOB_EXECUTION_PARAMS CHANGE COLUMN STRING_VAL PARAMETER_VALUE VARCHAR(2500);
spring batch 5로 migration하는 경우 위 ALTER 쿼리 실행시 크리티컬한 버그가 있습니다.
ALTER TABLE BATCH_JOB_EXECUTION_PARAMS CHANGE COLUMN TYPE_CD PARAMETER_TYPE VARCHAR(100);
위 쿼리가 문제인데 spring batch 4일 경우 Long 타입은 TYPE_CD에 LONG 으로 저장되어 있습니다.
하지만 spring batch 5일 경우 PARAMETER_TYPE 에 java.lang.Long 으로 저장됩니다.
spring batch 5에서 신규로 만들어진 job이면 문제없지만 이전 버전부터 사용하고 있던 job을 실행하면 오류를 뿜뿜하고 나올 것입니다.
아래와 같이 여러 대안이 있죠.
각각의 장단점이 있으니 신중하게 고려해서 선택하는것이 좋습니다.
CREATE_TIME 컬럼이 신규로 생성되었으며 START_TIME 컬럼에 NOT_NULL 조건이 삭제됩니다.
아래 쿼리로 변경하면 됩니다.
ALTER TABLE BATCH_STEP_EXECUTION ADD CREATE_TIME DATETIME(6) NOT NULL DEFAULT '1970-01-01 00:00:00';
ALTER TABLE BATCH_STEP_EXECUTION MODIFY START_TIME DATETIME(6) NULL;
spring batch 4에서는 아래와 같이 BatchConfigurer을 직접 구현해야 했습니다.
spring batch 5에서는 BatchConfigurer가 제거되었고 DefaultBatchConfiguration를 상속하여 커스터마이징만 하면 됩니다.
@Configuration
public class CustomBatchConfigurer implements BatchConfigurer, BeanPostProcessor {
private final DataSource dataSource;
private final PlatformTransactionManager transactionManager;
private JobRepository jobRepository;
private JobLauncher jobLauncher;
private JobExplorer jobExplorer;
@Lazy
public CustomBatchConfigurer(@Qualifier("dataflowLazyDataSource") DataSource dataSource,
@Qualifier("dataflowTransactionManager") PlatformTransactionManager dataflowTransactionManager) {
this.dataSource = dataSource;
this.transactionManager = dataflowTransactionManager;
initialize();
}
@NotNull
@Override
public JobRepository getJobRepository() {
return this.jobRepository;
}
@NotNull
@Override
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
@NotNull
@Override
public JobLauncher getJobLauncher() {
return this.jobLauncher;
}
@NotNull
@Override
public JobExplorer getJobExplorer() {
return this.jobExplorer;
}
private void initialize() {
try {
this.jobRepository = createJobRepository();
this.jobExplorer = createJobExplorer();
this.jobLauncher = createJobLauncher();
} catch (Exception e) {
throw new BatchConfigurationException(e);
}
}
private JobLauncher createJobLauncher() throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(this.jobRepository);
jobLauncher.afterPropertiesSet();
return jobLauncher;
}
private JobExplorer createJobExplorer() throws Exception {
JobExplorerFactoryBean jobExplorerFactoryBean = new JobExplorerFactoryBean();
jobExplorerFactoryBean.setDataSource(this.dataSource);
jobExplorerFactoryBean.afterPropertiesSet();
return jobExplorerFactoryBean.getObject();
}
private JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
jobRepositoryFactoryBean.setDataSource(this.dataSource);
jobRepositoryFactoryBean.setTransactionManager(this.transactionManager);
jobRepositoryFactoryBean.afterPropertiesSet();
return jobRepositoryFactoryBean.getObject();
}
}
@Configuration
public class CustomBatchConfigurer extends DefaultBatchConfiguration {
private final DataSource dataSource;
private final PlatformTransactionManager transactionManager;
public CustomBatchConfigurer(@Qualifier("dataflowLazyDataSource") DataSource dataSource,
@Qualifier("dataflowTransactionManager") PlatformTransactionManager dataflowTransactionManager) {
this.dataSource = dataSource;
this.transactionManager = dataflowTransactionManager;
}
@Override
protected @NotNull DataSource getDataSource() {
return this.dataSource;
}
@Override
protected @NotNull PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
}
또한 @EnableBatchProcessing 어노테이션방식으로 dataSourceRef, transactionManagerRef 등 다양한 옵션을 넣을 수 있습니다.
@Configuration
@EnableBatchProcessing(dataSourceRef = "dataflowLazyDataSource",
transactionManagerRef = "dataflowTransactionManager")
public class CustomBatchConfigurer implements BeanPostProcessor {
}
DefaultBatchConfiguration와 @EnableBatchProcessing 동시에 사용 불가하다.
spring batch 4까지는 @EnableBatchProcessing 를 통해 트랜잭션 매니저가 spring context에 노출되었습니다.
하지만 무조건적인 노출은 사용자 정의 트랜잭션 매니저 적용하는데 문제가 발생하게 되었죠.
관련 이슈 →
이 부분을 수정하기 위해 tasklet에서도 명시적으로 transactionManager를 구성하도록 변경되었습니다.
// Sample with v4
@Configuration
@EnableBatchProcessing
public class MyStepConfig {
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Step myStep() {
return this.stepBuilderFactory.get("myStep")
.tasklet(..) // or .chunk()
.build();
}
}
// Sample with v5
@Configuration
@EnableBatchProcessing
public class MyStepConfig {
@Bean
public Tasklet myTasklet() {
return new MyTasklet();
}
@Bean
public Step myStep(JobRepository jobRepository, Tasklet myTasklet, PlatformTransactionManager transactionManager) {
return new StepBuilder("myStep", jobRepository)
.tasklet(myTasklet, transactionManager) // or .chunk(chunkSize, transactionManager)
.build();
}
}
JobBuilderFactory/StepBuilderFactory가 deprecated되었으며 spring context에서도 삭제되었습니다.
메서드는 아직 삭제되지 않았지만 intellij에서 warning 메시지를 노출할 것입니다.
아래와 같이 name, jobRepository를 parameter로 하여 생성하도록 합니다.
// Sample with v4
@Configuration
@EnableBatchProcessing
public class MyJobConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Bean
public Job myJob(Step step) {
return this.jobBuilderFactory.get("myJob")
.start(step)
.build();
}
}
// Sample with v5
@Configuration
@EnableBatchProcessing
public class MyJobConfig {
@Bean
public Job myJob(JobRepository jobRepository, Step step) {
return new JobBuilder("myJob", jobRepository)
.start(step)
.build();
}
}
개요 linux를 사용하다 보면 version 비교하는 기능이 필요합니다. 특히 기존 설치된 패키지의 version을 확인하여 업데이트할 경우가 있겠죠. 아래와 같이 간단한 shell script로 구현할 수 있습니다.
jdk 21 출시!!
ci/cd 오픈소스 도구로 가장 많이 사랑 받는 jenkins에 대해 포스팅 해보겠습니다. 먼저 설치부터 해야겠지요? 항상 패키지 매니저로 설치했었는데 이번에는 docker로 설치해보도록 하겠습니다.
개요 github rest API 문서를 보면 재미있는 API들이 있습니다. 오늘은 그 중 최신 release 가져오는 API를 만져보도록 하겠습니다.
개요 intellij에서 shell script 코드를 작성할 때 이런 warning 메시지를 보여주더군요.
springboot 탄생 배경 springboot란 spring framework를 좀 더 쉽게 개발/배포할려는 목적으로 만들어 졌습니다. 2012년 Mike Youngstrom은 spring 프레임워크에서 컨테이너 없는 웹 애플리케이션 아키텍처에 대한 지원을 요청하는 spring...
개요 지난번 spring-initializer를 통해 프로젝트를 생성하여 파일로 다운로드 받았습니다.
개요 springboot3로 메이저 업그레이드 되면서 JPA + querydsl 셋팅 환경에 변화가 생겼습니다. 기존 의존성으로는 작동하지 않고 jakarta classification을 추가해야 작동하는 이슈가 발생합니다. springboot3부터 javax -> jakar...
개요 2022년 하반기에 springboot3가 공식 release 되었습니다. springboot2가 2018년 상반기에 release되고 나서 새롭게 판올림 버전으로 가장 큰 변화로는 아래와 같습니다. spring framework 6 적용 최소 사양 JDK 17 ...
개요 항상 intellij ultimate 버전만 사용하고 있었는데 무슨 바람이 난건지.. intellij ce 버전에 도전하였습니다. springboot 프로젝트 생성이며.. 그 밖에 기본적으로 될꺼라 싶은것 중에 안되는 녀석들도 꽤 있더군요. 이번 시간엔 간단하게 spingbo...
개요 JPA를 spring data jpa + querydsl과의 조합으로 접하는 경우가 많습니다. spring data jpa에서 제공해주는 specification으로도 충분히 해낼수 있지만 querydsl에 비할바는 아닙니다. entity에 wrapper Q클래스를 생성하여 ...
개요 오랫동안 방치했던 블로그를 다시 열면서 jekyll를 다시 설치해봤습니다. 설치 jekyll 프로젝트로 이동하여 아래 명령어를 입력합니다. gem install jekyll bundler Fetching pathutil-0.16.2.gem Fetching terminal-t...
개발자에게 있어 탁월한 검색은 능력은 필수라고 생각됩니다.
bash를 사용하여 yaml 파일을 파싱 및 환경 변수로 손쉽게 등록할 수 있습니다.
https://app.diagrams.net/
구글 검색을 해보면 Spring Boot Gradle + 하나의 vueJS Project Build만 나와있는 경우가 많습니다.
외부 통신에 대한 Error 처리는 앱을 더욱 더 견고하게 만들 수 있습니다. Error 처리를 위해 엔드포인트에 대한 Http Status Code를 억지로 생성하는것은 매우 귀찮은 일이라고 할까요? 보다 간편하게 Mock 서버를 두는게 더 효율적이라고 볼 수 있습니다.
입력 받은 아이디를 체크하여 규칙에 맞게 추천하는 프로그램 개발 7단계의 규칙을 적용해야 하는데 그 내용은 아래와 같다.