[컴] gradle 에서 flyway 설정하기

migration tool / spring boot / spring migration 툴 / db / database 

gradle 에서 flyway 설정하기

ref. 1 의 방법을 참고하면 된다. 다만 ref. 1 은 구버전의 flyway 에 대한 글이다. 현재 2022-11 기준, 최신버전은 9.7.0 이다.

여기서 이야기하려는 것은 gradle 을 통해서 flyway 를 실행하는 방법이다. 그래서 build.gradle 에 설정해 주면 된다. 다만 몇가지 설정값(pw같은)을 외부로 뺄 것이라서, flyway.conf 파일이 추가로 쓰인다.

디렉토리 구조:

- <proj_root>/
    - conf/
        - flyway.conf
    - build.gradle

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        ...
        // for flyway
        classpath "org.flywaydb:flyway-mysql:9.7.0"
    }
}

plugins {
    id "org.flywaydb.flyway" version "9.7.0"
}

config file 예시

config file 은 아래처럼 작성하면 된다.

# flyway.conf
flyway.url=jdbc:mariadb://127.0.0.1:3306/mydatabase?log=true&sessionVariables=time_zone='+00:00'
flyway.user=testflyway
flyway.password=testflyway
flyway.encoding=UTF-8

config file 을 사용해서 실행하는 방법

<proj>/conf/flyway.conf 를 사용하는 법은 Config file 사용법을 참고하면, 아래처럼 실행을 하면 된다.

아래는 gradlew flywayBaseline 을 실행하는 command 이다.

gradlew -Dflyway.configFiles=./conf/flyway.conf -Dflyway.baselineVersion="1.3.1" -Dflyway.baselineDescription="Existing version of MyDatabase" flywayBaseline

gradlew flywayBaseline -i 를 하면 좀 더 자세한 정보를 확인할 수 있다.

migrate 방법

flywayMigrate 를 하면 다음 경로에 있는 .sql 파일을 실행한다.

  • <proj>/src/main/resources/db/migration/
gradlew -Dflyway.configFiles=./conf/flyway.conf flywayMigrate

예를 들어 <proj>/src/main/resources/db/migration/V1.3.2__testgen.sql 라는 파일이 있는경우, flywayMigrate 를 하면, 아래처럼 history 가 추가되고, sql file 내의 sql statement 가 실행된다.

주의할점

주의할 점은 위의 flywayBaseline 명령을 할 때 flyway.baselineVersion="1.3.1" 를 정했기 때문에, flywayMigrate 는 그 이후부터 실행된다. 그래서 만약 .sql file 의 file 이름이 예를 들어 V1.3.0__testgen.sql 라면, 1.3.1 보다 낮은 버전이기 때문에 실행되지 않는다.

undo

undo 기능은 commecial 에서만 제공한다고 한다.

tip: 그냥 undo 를 하지 말고, 새롭게 버전을 만들고, 그곳에 undo 에서 수행할 내용을 적으면 될 듯 하다.

Gradle Flyway Tasks

See Also

  1. 쿠…sal: [컴] flywayMigrate 를 해서 checksum error 가 나온 경우

Reference

  1. GitHub - iinow/flyway: spring boot + flyway

[컴][nodejs] vscode 에서 webpack 에 대한 debugger 사용법

 

node_modules 에 대한 debugger / debugging / 디버거 / 디버깅 /nodejs webpack

vscode 에서 webpack 에 대한 debugger 사용법

webpack 으로 build 하는 경우 webpack 설정이 어떻게 동작하는지에 대해 보고자 debugger 를 attach 하려했다.

그래서 다음처럼 실행하는 것으로 debugger 를 붙일 수 있었다. 다음은 vscode의 launch.json이다.

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "skipFiles": [
                "<node_internals>/**"
            ],
            
            "program": "${workspaceFolder}\\node_modules\\webpack\\bin\\webpack.js",
            "args": [
                "--config",
                "webpack.prod.js"
            ],
            "env": {
                "NODE_OPTIONS": "--openssl-legacy-provider"
            },
            "stopOnEntry": true
        },
    ]
}

[컴] Spring 의 @Autowired annotation

 

springboot annotation @autowired

Spring 의 @Autowired annotation

Autowired 는 Dependency Injection 을 사용한다. 즉, @Autowired 는 dependency가 있는 object 를 inject 해준다.

이것을 ref.2 에서 좀 더 자세히 풀어준다. 그것을 대략적으로 옮겨오면 다음과 같다.

Spring Container 이 가지고 있는 object(bean) 들이 있는데, 우리의 controller bean 이 저기에 spring container 내가 사용할 bean 이 있다는 것을 안다. 그러면, 우리는 이 Controller class bean 에게 helper class bean 을 연결해줘야 한다. 이것이 @Autowired 이다.

그러면 이제 그 bean 을 찾고, 그것을 지정한 변수에 담는다. (inject) 그러면 이제 변수가 초기화후 사용할 준비가 되게 된다.

References

  1. GitHub - fmarchioni/masterspringboot: Source code for www.masterspringboot.com
  2. @Autowired In Spring Boot. Hello programmers, | by pratik Raghuwanshi | Javarevisited | Medium

[컴] Spring Boot 간략 정리

 

스프링 / java spring boot / spring boot

Spring Boot 간략 정리

6.2.2. Locating the Main Application Class 에 나와있는 일반적인 springboot 구조

com
 +- example
     +- myapplication
         +- MyApplication.java  --> 여기에 main 이 있다.
         |
         +- customer
         |   +- Customer.java
         |   +- CustomerController.java
         |   +- CustomerService.java
         |   +- CustomerRepository.java
         |
         +- order
             +- Order.java
             +- OrderController.java
             +- OrderService.java
             +- OrderRepository.java
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class MyApplication

fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}

Configuration class

1개의 @Configuration class 를 주요 class 로 사용하길 추천한다.(참고) main 이 들어있는 class 도 primary @Configuration 으로 좋은 후보 class 이다.

@ComponentScan 을 사용하면, 자동으로 모든 Spring component들을 가져온다. 당연히 @Configuration도 가져온다.

@Configuration class 에서 @Import 를 써서 다른 Configuration 을 import 할 수 있다.

@Configuration
@Import(AConfig::class, BConfig::class)
class MyConfig {
    ...
}

auto-configuration 은 @SpringBootApplication 이나 @EnableAutoConfiguration을 사용하면 enable 된다. 그러면, 자동으로 설정이 잡힌다. classpath 에 jar 이 추가되면, 이 jar에 대한 configuration 도 자동으로 된다. 추후 필요한 부분들을 override 해서 값들을 수정하면 된다.

만약 특정 부분에 대한 auto configuration 을 하고 싶지 않다면, 다음처럼 exclude 할 수 있다.

@SpringBootApplication(exclude = [DataSourceAutoConfiguration::class])
class MyApplication

일반적으로 constructor injection을 사용하여 dependency 들을 연결하고, @ComponentScan을 사용하여 bean을 찾는 것이 좋다.(참고)

@ComponentScan 을 사용하면 @Component, @Service, @Repository, @Controller 등 모든 application component들이 자동으로 Spring Beans 로 등록된다.

다음 예제가 contructor injection 을 보여준다.

@Service
public class MyAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    public MyAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}

kotlin 코드는

@Service
class MyAccountService(private val riskAssessor: RiskAssessor) : AccountService

여러개의 consturctor 가 있으면, 어떤 constructor 를 쓸 것인지 지정해줘야 한다.(@Autowired)

@Service
class MyAccountService : AccountService {

    private val riskAssessor: RiskAssessor

    private val out: PrintStream

    @Autowired
    constructor(riskAssessor: RiskAssessor) {
        this.riskAssessor = riskAssessor
        out = System.out
    }

    constructor(riskAssessor: RiskAssessor, out: PrintStream) {
        this.riskAssessor = riskAssessor
        this.out = out
    }

    // ...

}

Application Event들

ApplicationContext 가 생성되기전의 event 들이 몇개있는데, 그 event 에 대한 listener를 Bean 으로 등록을 할 수 없다.

  • SpringApplication.addListeners() 를 이용
  • SpringApplicationBuilder.listeners() 를 이용
  • META-INF/spring.factoriesApplicationListener 로 등록하기
    • 예: org.springframework.context.ApplicationListener=com.example.project.MyListener

Application events 들은 다음순서로 발생된다. 이 event 들은 SpringApplication 에 묶인다. 이벤트가 어떤 의미를 갖는지는 여기를 참고하자.

  1. ApplicationStartingEvent
  2. ApplicationEnvironmentPreparedEvent
  3. ApplicationContextInitializedEvent
  4. ApplicationPreparedEvent
    1. WebServerInitializedEvent
    2. ContextRefreshedEvent
  5. ApplicationStartedEvent
  6. AvailabilityChangeEvent
  7. ApplicationReadyEvent
  8. AvailabilityChangeEvent
  9. ApplicationFailedEvent

SpringApplication은 사용자를 대신하여 right type의 ApplicationContext를 만들려한다. 웹 응용 프로그램 (WebApplicationType)을 결정하는 데 사용되는 알고리즘유형은 다음과 같다.

  • Spring MVC가 있는 경우 AnnotationConfigServletWebServerApplicationContext가 사용
  • Spring MVC가 없는 경우 AnnotationConfigReactiveWebServerApplicationContext가 사용
  • 그외의 경우 : AnnotationConfigApplicationContext

setWebApplicationType(WebApplicationType) 을 통해 override 할 수 있다.

JUnit test 내에서 SpringApplication 을 사용할 때는 setWebApplicationType(WebApplicationType.NONE) 를 사용하자.

Application Arguments

아래에서 보이는 args 를 bean 등으로 넘길 수 있다.

fun main(args: Array<String>) {
    val defaultProp = Properties().apply {
        set("young.pa.phase", "local")
        set("young.pa.debug", false)
    }
    runApplication<Application>(*args) { setDefaultProperties(defaultProp) }
}

아래처럼 사용하면 된다.

import org.springframework.boot.ApplicationArguments
import org.springframework.stereotype.Component

@Component
class MyBean(args: ApplicationArguments) {

    init {
        val debug = args.containsOption("debug")
        val files = args.nonOptionArgs
        if (debug) {
            println(files)
        }
        // if run with "--debug logfile.txt" prints ["logfile.txt"]
    }

}

Application 시작을 추적하려면

외부 설정 방법들

  • SpringApplication.setDefaultProperties
  • application.propertiesapplication.yml
    • spring 이 자동으로 찾아서 load 한다.
    • classpath 들의 root 와 /config package 에서 찾는다.
    • 현재 directory 와 하위 directory 의 /config 에서 찾는다.
    • <proj>/src/main/resources/application.properties에 두면 된다.
  • 기타 여러가지 방법들은 Externalized Configuration 를 참고하자.

Testing

Task Execution and Scheduling

See Also

  1. 6.7.5. Hot Swapping

Reference

  1. Spring Boot Reference Documentation

[컴] @SpringBootApplication annotation

 

어노테이션 / 스프링 시작 / 어떻게 빈 들을 등록하는가 / 언제 등록되는건가 / 스프링붓 / 부트 /

@SpringBootApplication annotation

@SpringBootApplication 를 사용하는 것은 @SpringBootConfiguration, @EnableAutoConfiguration, @ComponentScan 를 같이 사용하는 것과 같다고 한다.[ref.2]

// @SpringBootConfiguration
// @EnableAutoConfiguration
// @ComponentScan
@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

scan 하려는 package 를 추가하려 할 때

기본적으로, component들의 위치를 찾을 때 spring-boot 은 main class 가 있는 곳의 sub-package들을 찾아보게 된다.

@SpringBootApplication(
    scanBasePackages = [
        com.springhow.examples.autoconfig::class,
        com.springhow.examples.components::class,
        com.thirdparty.components::class
    ],
    exclude = [SecurityAutoConfiguration::class]
)

@EnableAutoConfiguration

  • SpringApplicationContext 의 auto-configuration 기능을 enable 시킨다. 그래서 classpath 의 component들을 scan 하고, bean들을 등록한다.
  • @Component, @Configuration, @Bean, meta-annotations 등이 설정된 bean들을 자동으로 등록한다.(register)
  • 이 설정은 application 내에서 한번만 사용해야 한다.

@Configuration

class에 annotation 을 넣으면, Spring Container 에게 이 class 가 @Bean 을 정의하는 methods 를 가지고 있다고 알려주게 된다.

그러면, Spring container가 class 를 처리해서 application 에 사용할 Spring Bean들을 만든다.

Reference

  1. Spring Initializr
  2. @SpringBootApplication annotation - How it works | SpringHow
  3. Spring Boot - Auto-configuration - GeeksforGeeks
  4. Spring @Configuration Annotation with Example - GeeksforGeeks

[컴] rover, terraform visualizer 사용

테라폼 분석 / 다이어그램 그리기 /

rover, terraform visualizer 사용

rover 를 실행하기 위해선, terraform 이 필요하다.

실행파일은 release page 에서 얻을 수 있다.

d:\a\prog\my-infra.tf 파일을 넣고 아래처럼 실행하면 된다.

rover_v0.3.3.exe -workingDir "d:\a\prog\my-infra" -tfPath "d:/a/apps/terraform/1.3.3/terraform.exe"

그리고 browser에서 localhost:9000 으로 접속하면 된다.

d:\a\apps\rover>rover_v0.3.3.exe -workingDir "d:\a\prog\my-infra" -tfPath "d:/a/apps/terraform/1.3.3/terraform.exe"
2022/11/01 15:25:54 Starting Rover...
2022/11/01 15:25:54 Initializing Terraform...
2022/11/01 15:25:55 Generating plan...
2022/11/01 15:26:04 Generating resource overview...
2022/11/01 15:26:04 No submodule configurations found...
2022/11/01 15:26:04 Generating resource map...
2022/11/01 15:26:04 Generating resource graph...
2022/11/01 15:26:04 Done generating assets.
2022/11/01 15:26:04 Rover is running on 0.0.0.0:9000

save

다음처럼 -standalone true 옵션을 주면, rover.zip 으로 결과파일을 저장해준다. 압축을 풀고, index.html 를 실행하면 똑같은 결과를 확인할 수 있다.

d:\a\apps\rover>rover_v0.3.3.exe -workingDir "d:\a\prog\my-infra" -tfPath "d:/a/apps/terraform/1.3.3/terraform.exe" -standalone true

tip

다이어그램(diagram) 에서 entity 를 ’더블클릭’하면 그 화면을 고정시켜주고, 정보를 보여준다. 그리고 다이어그램 화면은 왼쪽마우스버튼 클릭을 하고, drag할 수 있다.

troubleshooting

아래처럼 profile 이 없다고 error 가 떴다. 그래서 그냥 provider.profile 부분을 주석 처리했더니, 잘 동작한다.

Error: error configuring Terraform AWS Provider: failed to get shared config profile, myproftest

[컴] Blast radius 사용

테라폼 다이어그램 / diagram / 그리기 / 구성도 자동 그려주는 / 그려주기 / 그리기

Blast radius 사용

terraform 내용에 대한 간단한 그림을 그려준다. 다만 지원하는 버전이 0.12.0 까지이다. 개인적인 판단으로는 see also. 2 에 이야기한 rover가 나은듯 싶다.

Prerequisites

pip install blastradius
blast-radius --serve /path/to/terraform/directory

그냥 docker 가 편하다. 다음은 windows 용으로 command를 적었다. d:\a\apps\blastradius\data\tf 에 .tf file(terraform file) 을 놓고 작업하면 된다.

docker run --rm -it -p 5000:5000 -v d:\\a\\apps\\blastradius:/data:rw --security-opt apparmor:unconfined --cap-add=SYS_ADMIN 28mm/blast-radius --serve /data/tf/

See Also

  1. GitHub - cycloidio/inframap: Read your tfstate or HCL to generate a graph specific for each provider, showing only the resources that are most important/relevant. : inframap 이것은 좀 더 간단한 그림을 그려준다. 그런데 더 간단히 사용할 수 있다.
  2. 쿠...sal: [컴] rover, terraform visualizer 사용

Reference

  1. GitHub - 28mm/blast-radius: Interactive visualizations of Terraform dependency graphs using d3.js
  2. Tools to Visualize your Terraform plan - DEV Community 👩‍💻👨‍💻