Upgrade to Pro — share decks privately, control downloads, hide ads and more …

決済サービスのSpring Bootのバージョンを2系に上げた話

決済サービスのSpring Bootのバージョンを2系に上げた話

JSUG勉強会 2020その2 Spring Boot 1.xから2.xへの移行

Ryosuke Uchitate

February 12, 2020
Tweet

More Decks by Ryosuke Uchitate

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ ໊લ ಺ཱ ྑհʢ͏ͪͨͯ Γΐ͏͚͢ʣ ॴଐ ίΠχʔגࣜձࣾ Fashion Charity Project

    Triangle Sauce ࠷ۙͷ࢓ࣄ Reactॻ͍ͨΓɺՃໍళ͞Μʹخ͍͠ػೳ࣮૷ͨ͠Γ
  2. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  3. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  4. CoineyͷγεςϜߏ੒ • admin-api • ࣾ಺ઐ༻αʔϏε͕ݺͿAPI • web-api • Ճໍళ͕ར༻͢ΔWeb؅ཧαʔ Ϗε͕ݺͿAPI

    • mobile-api • Ճໍళ͕ར༻͢ΔϞόΠϧΞϓ Ϧ͕ݺͿAPI • partner-api • ύʔτφʔاۀ؅ཧʹؔ͢Δ API • antisocial-force- checker • ൓ࣾνΣοΫʹؔ͢ΔAPI • emoney-api • ిࢠϚωʔʹؔ͢ΔAPI ઃఆϑΝΠϧ͸Cloud ConfigͰ؅ཧ
  5. ϨϙδτϦͱόʔδϣϯ Spring Boot Gradle આ໌ coiney-api 1.5.18 3.5.1 ϝΠϯͷAPI ʢadmin-api,

    web-api, mobile- apiʣ coiney-api- config-server 1.5.9 2.9 Spring Cloud Config Server coiney-emoney 1.5.16 3.5.1 ిࢠϚωʔܾࡁʹؔ͢ΔAPI antisocial- force-checker 1.4.1 3.3 ൓ࣾνΣοΫʹؔ͢ΔAPI Spring Boot 2.0.x͸Gradle 4+
  6. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  7. Gradle 4.xͷ࠷৽ʹ͢Δ // build.gradle wrapper { gradleVersion = "4.10.2" distributionType

    = Wrapper.DistributionType.ALL } $ ./gradlew wrapper // Gradle 5.0Ͱඇޓ׵ʹͳΔػೳΛར༻͍ͯ͠Δͱϝοηʔδ͕ग़ྗ͞ΕΔ // —-warning-mode allΦϓγϣϯΛ࢖͏ͱৄࡉΛ֬ೝͰ͖Δ $ ./gradlew build —-warning-mode all
  8. build.gradleͷॻ͖׵͑ dependencies { - compile "com.fasterxml.jackson.dataformat:jackson-dataformat-csv" + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-csv" }

    Gradle4.7͔ΒcompileͳͲ͕ඇਪ঑ʹ 4.6·Ͱ 4.7Ҏ߱ compile implementation runtime runtimeOnly testCompile testImplementation testRuntime testRuntimeOnly
  9. implementationʹॻ͖׵͑Δͱ // fooϞδϡʔϧ dependencies { implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-csv" } // barϞδϡʔϧ

    dependencies { implementation project (":foo") } barϞδϡʔϧʹ͸jackson-dataformat-csv͕఻೻͠ͳ͍
  10. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  11. औಘ͢Δִ࣌ؒؒΛઃఆՄೳʹͳͬͨ // લͷϦΫΤετ͔Β60ඵޙҎ߱ͷϦΫΤετͰऔಘ // σϑΥϧτ͸0ඵɻʢϦΫΤετͷ౓ʹऔಘʣ spring.cloud.config.server.git.refresh-rate=60 Git Refresh Rate You

    can control how often the config server will fetch updated configuration data from your Git backend by using spring.cloud.config.server.git.refreshRate. The value of this property is specified in seconds. By default the value is 0, meaning the config server will fetch updated configuration from the Git repo every time it is requested. [ެࣜυΩϡϝϯτΑΓൈਮ] Spring Cloud Config Server 2.0.2͔Β
  12. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  13. Spring Boot Starter Json • JacksonͷͨΊͷAuto-configuration͕ఏڙ͞ΕΔ • ࣍ͷϥΠϒϥϦؚ͕·Ε͍ͯΔ • jackson-databind

    • jackson-datatype-jdk8 • jackson-datatype-jsr310 • jackson-module-parameter-names
  14. HtmlUtils.htmlEscape()ͷ࣮૷มߋ // 4.3.x public static String htmlEscape(String input, String encoding)

    { Assert.notNull(encoding, "Encoding is required"); if (input == null) { return null; } // 5.0.x public static String htmlEscape(String input, String encoding) { Assert.notNull(input, "Input is required"); Assert.notNull(encoding, "Encoding is required"); input͕nullͷͱ͖ExceptionΛ౤͛ΔΑ͏ʹͳͬͨ
  15. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  16. ίϯετϥΫλ͕ඇਪ঑ - new PageRequest(1, 10); + PageRequest.of(1, 10); - new

    Sort(orders); + Sort.by(orders); ίϯετϥΫλ͕ඇਪ঑ʹͳͬͨɻ2.2.0͔ΒpublicίϯετϥΫλ͡Όͳ͘ͳΔ
  17. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  18. JpaRepository.javaͷ࣮૷มߋ // ϝιουͷ໭Γ஋ʹOptional͕࢖͑ΔΑ͏ʹͳͬͨ - User fidyByName(String name); + Optional<User> findByName(String

    name); // ϝιου໊ͷมߋʢҰ෦ʣ - <S extends T> List<S> save(Iterable<S> entities); + <S extends T> List<S> saveAll(Iterable<S> entities);
  19. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  20. FlywayΛมߋͳ͠Ͱ3 -> 5΁ 2019-09-11 03:43:15.152 ERROR --- Application startup failed

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Validate failed: Migration checksum mismatch for migration 1 -> Applied to database : 1750005324 -> Resolved locally : -558371367 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.jav a:1583) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java: 545) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java: 482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java: 230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java: 851) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371) at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) at com.b1a9idps.sample.view.Application.main(Application.java:19) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ϚΠάϨʔγϣϯࣦഊ
  21. Flyway 3 -> 5ͷओͳมߋ఺ Important note for users upgrading from

    Flyway 3.x: This release no longer supports a schema history table upgrade from Flyway 3.x. You must upgrade to Flyway 4.2.0 first before upgrading to Flyway 5.0.0. 3 -> 4 νΣοΫαϜͷܭࢉํ๏ͷมߋɻνΣοΫαϜܭࢉ࣌ʹɺվߦίʔυΛແࢹ͢ΔΑ͏ʹͳͬͨɻ 4 -> 5 FlywayͷϝλσʔλΛ؅ཧ͢Δςʔϒϧ໊͕ schema_version͔Βflyway_schema_historyʹͳͬͨɻ
  22. Flyway4ܥʹ্͛ͯىಈ dependencies { compile "org.flywaydb:flyway-core:4.2.0" } $ gradle bootRun =====

    2019-09-11 03:43:14.467 INFO --- Upgrading metadata table `sample`.`schema_version` to the Flyway 4.0 format ... 2019-09-11 03:43:15.329 INFO --- Repairing metadata for version 1 (Description: CREATE TABLE SAMPLE DATA, Checksum: -558371367) ... 2019-09-11 03:43:15.349 INFO --- Repairing metadata for version 2 (Description: MODIFY SAMPLE DATA LENGTH, Checksum: -1031537806) ... 2019-09-11 03:43:15.370 INFO --- Repairing metadata for version 3 (Description: SAMPLE DATA ADD INDEX, Checksum: 194652164) ... 2019-09-11 03:43:15.412 INFO --- Metadata table schema_version successfully upgraded to the Flyway 4.0 format. ॳճىಈ࣌ʹطଘͷschema_versionςʔϒϧΛΞοϓάϨʔυͯ͘͠ΕΔ
  23. ϝλςʔϒϧ໊Λมߋ͠ͳ͔ͬͨ৔߹ 2019-09-25 23:05:33.882 WARN --- Could not find schema history

    table `sample`.`flyway_schema_history`, but found `sample`.`schema_version` instead. You are seeing this message because Flyway changed its default for flyway.table in version 5.0.0 to flyway_schema_history and you are still relying on the old default (schema_version). Set flyway.table=schema_version in your configuration to fix this. This fallback mechanism will be removed in Flyway 6.0.0. 6ܥ͔ΒϑΥʔϧόοΫػೳ͕ͳ͘ͳΔ͔Βςʔϒϧ໊มߋ͠ͳΑͱ஫ҙ͞ΕΔ
  24. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  25. ϥΠϒϥϦ౳ͷมߋ఺ JUnit JUnit 5͕࢖͑ΔΑ͏ʹͳ͕ͬͨɺSpring Boot Starter Test͸JUnit 4ɻ Spring Boot

    2.2.x͔ΒJUnit 5͕σϑΥϧτʹͳͬͨɻ Mockito 1ܥ͔Β2ܥʹͳͬͨ AssertJ 2ܥ͔Β3ܥʹͳͬͨ
  26. ෆཁͳελϒͷ࡟আ @ExtendWith(MockitoExtension.class) class StubTest { @Mock Hoge hoge; @Test void

    test() { when(hoge.getName()).thenReturn("uchitate"); } class Hoge { String getName() { return "";} } } Unnecessary stubbings detected. Clean & maintainable test code requires zero unnecessary code. Following stubbings are unnecessary (click to navigate to relevant line of code): 1. -> at com.coiney.StubTest.test(StubTest.java:18) Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class. org.mockito.exceptions.misusing.UnnecessaryStubbingException: Unnecessary stubbings detected. Clean & maintainable test code requires zero unnecessary code. Following stubbings are unnecessary (click to navigate to relevant line of code): 1. -> at com.coiney.StubTest.test(StubTest.java:18) Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class. ग़ྗ͞Εͨߦ൪߸ͷίʔυΛ࡟আ͢Δ
  27. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ
  28. EnvironmentΠϯλʔϑΣʔε͔ΒͷόΠϯυ͕Մೳʹ // Πϯελϯε΁ͷόΠϯυ JsugPropsBinder binder = new JsugPropsBinder(); Binder.get(environment) .bind("jsug.props-instance",

    Bindable.ofInstance(binder)) .get(); // ೚ҙͷΫϥε΁ͷόΠϯυ Binder.get(environment) .bind("jsug.props-simple", Bindable.of(JsugPropsBinder.class)) .get(); // List<JsugPropsBinder>΁ͷόΠϯυ Binder.get(environment) .bind("jsug.props", Bindable.listOf(JsugPropsBinder.class)) .get(); public class JsugPropsBinder { private List<String> speakerNames; private String theme; @DateTimeFormat(iso = DATE) private LocalDate date; }
  29. ProfileͰόΠϯυ͢Δ஋Λมߋ͢Δ jsug: props: list: - name: uchitate theme: SpringBoot2 ---

    spring: profiles: dev jsug: props: list: - name: uchitate-dev theme: SpringBoot2-dev @ConfigurationProperties("jsug.props") @ConstructorBinding public class JsugProps { private final List<Jsug> list; public static class Jsug { private String name; private String theme; } }
  30. ProfileͰόΠϯυ͢Δ஋Λมߋ͢Δ // profile=defaultͷͱ͖ { "list": [ { "name": "uchitate", "theme":

    "SpringBoot2" } ] } // profile=devͷͱ͖ { "list": [ { "name": "uchitate-dev", "theme": "SpringBoot2-dev" } ] } ௥Ճ͡Όͳ্ͯ͘ॻ͖͞ΕΔ
  31. ΞδΣϯμ • લஔ͖ • όʔδϣϯΞοϓ࡞ۀɹ • Gradle • Spring Cloud

    Config Server • Spring Web • Spring Data • Spring Data JPA • Flyway • Testing • Configuration Property Binding • ·ͱΊ