{"id":25128,"date":"2019-12-17T08:00:26","date_gmt":"2019-12-16T23:00:26","guid":{"rendered":"https:\/\/www.techscore.com\/blog\/?p=25128"},"modified":"2019-12-17T17:13:40","modified_gmt":"2019-12-17T08:13:40","slug":"openapi-generator-oauth2-accesstoken","status":"publish","type":"post","link":"https:\/\/www.techscore.com\/blog\/2019\/12\/17\/openapi-generator-oauth2-accesstoken\/","title":{"rendered":"OpenAPI Generator \u3067 OAuth2 \u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c\u306e\u30b3\u30fc\u30c9\u307e\u3067\u751f\u6210\u3057\u3066\u307f\u308b"},"content":{"rendered":"
\u3053\u308c\u306f TECHSCORE Advent Calendar 2019<\/a> \u306e17\u65e5\u76ee\u306e\u8a18\u4e8b\u3067\u3059\u3002<\/p>\n OpenAPI Generator<\/a> \u306f OpenAPI Specification<\/a> \u306e\u5b9a\u7fa9\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308c\u3070\u3001API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3084\u30b5\u30fc\u30d0\u306e\u30b9\u30bf\u30d6\u306e\u30b3\u30fc\u30c9\u3092\u81ea\u52d5\u751f\u6210\u3057\u3066\u304f\u308c\u308b\u3068\u3044\u3046\u4fbf\u5229\u306a\u4ee3\u7269\u3067\u3059\u3002<\/p>\n \u305f\u3060\u3001\u751f\u6210\u3055\u308c\u305f\u30b3\u30fc\u30c9\u304c\u305d\u306e\u307e\u307e\u4f7f\u3048\u308b\u3068\u306f\u8a00\u3048\u307e\u305b\u3093\u3002\u4f8b\u3048\u3070\u3001OAuth2 \u3067\u4fdd\u8b77\u3055\u308c\u3066\u3044\u308b API \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u5834\u5408\u3001\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u306e\u767a\u884c\u304c\u5fc5\u8981\u3067\u3059\u304c\u3001OpenAPI Generator \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u751f\u6210\u3067\u306f\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c\u306e\u30b3\u30fc\u30c9\u306f\u751f\u6210\u3057\u3066\u304f\u308c\u307e\u305b\u3093\u3002 \u307e\u305f\u3001Spring WebFlux<\/a> \u3092\u30e9\u30a4\u30d6\u30e9\u30ea\u3068\u3057\u3066\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u751f\u6210\u3082\u53ef\u80fd\u3067\u3059\u304c\u3001\u3053\u308c\u306b\u95a2\u3057\u3066\u306f\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c\u306f\u304a\u308d\u304b\u3001\u305d\u306e\u307e\u307e\u30d3\u30eb\u30c9\u3082\u901a\u3089\u306a\u3044\u3068\u3044\u3046\u72b6\u6cc1\u3067\u3059\u3002<\/p>\n \u4eca\u56de\u306f\u3001 OpenAPI Generator \u3067 Spring WebFlux \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u3092 OAuth2 \u306e\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c\u4ed8\u304d\u3067\u751f\u6210\u3059\u308b\u3068\u3053\u308d\u307e\u3067\u3092\u8a66\u3057\u3066\u307f\u307e\u3057\u305f\u3002 \u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u306f\u3053\u3061\u3089<\/a>\u306b\u3042\u308a\u307e\u3059\u3002 OpenAPI Generator \u304c\u751f\u6210\u3059\u308b\u30b3\u30fc\u30c9\u3092\u5909\u66f4\u3057\u305f\u3044\u5834\u5408\u3001\u666e\u901a\u306a\u3089 Github \u30ea\u30dd\u30b8\u30c8\u30ea<\/a> \u304b\u3089\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u843d\u3068\u3057\u3066\u304d\u3066\u3001Java \u306e\u30b3\u30fc\u30c9\u3092\u4fee\u6b63\u3057\u3066 Maven \u3067\u30d3\u30eb\u30c9\u3057\u3066..\u3068\u3044\u3046\u611f\u3058\u306b\u306a\u308b\u3068\u601d\u3044\u307e\u3059\u304c\u3001 Clone \u3059\u308b\u624b\u9593\u3084 Maven \u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u305f\u308a\u3061\u3087\u3063\u3068\u9762\u5012\u3067\u3059\u3002<\/p>\n Groovy<\/a> \u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u5fc5\u8981\u306a\u30af\u30e9\u30b9\u306f @Grab \u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u3067\u5b9f\u884c\u6642\u306b\u89e3\u6c7a\u3067\u304d\u3001Maven \u306f\u4e0d\u8981\u306b\u306a\u308b\u306e\u3067\u3001Groovy \u3092\u4f7f\u3044\u307e\u3059\u3002\u79c1\u306f\u666e\u6bb5 Mac \u3067\u958b\u767a\u3057\u3066\u3044\u308b\u305f\u3081\u3001Homebrew \u3067 Groovy \u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3057\u305f\u3002<\/p>\n \u624b\u59cb\u3081\u3068\u3057\u3066\u3001JavaClientCodegen<\/a> \u3092\u7d99\u627f\u3057\u305f\u30af\u30e9\u30b9\u3092\u5b9f\u884c\u3059\u308b Groovy \u30b9\u30af\u30ea\u30d7\u30c8\u3092\u4f5c\u308a\u307e\u3059\u3002<\/p>\n \u4e0a\u8a18\u3092\u30d5\u30a1\u30a4\u30eb\u540d techscore-client-codegen.groovy \u3068\u3057\u3066\u4fdd\u5b58\u5f8c\u3001\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u5b9f\u884c\u3067\u3001output \u30d5\u30a9\u30eb\u30c0\u306b Spring WebFlux \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u304c\u751f\u6210\u3055\u308c\u307e\u3059\u3002<\/p>\n \u4e0a\u8a18\u3067\u751f\u6210\u3055\u308c\u308b\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u306f\u3001\u524d\u8ff0\u3057\u305f\u3068\u304a\u308a\u305d\u306e\u307e\u307e\u3067\u306f\u30d3\u30eb\u30c9\u304c\u901a\u3089\u306a\u3044\u3001\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c\u306e\u30b3\u30fc\u30c9\u304c\u751f\u6210\u3055\u308c\u306a\u3044\u306a\u3069\u3068\u3044\u3063\u305f\u72b6\u614b\u3067\u3059\u3002<\/p>\n \u30d3\u30eb\u30c9\u304c\u901a\u3089\u306a\u3044\u306e\u306f\u3001\u751f\u6210\u3055\u308c\u308b build.gradle \u306b Spring \u95a2\u4fc2\u306e\u4f9d\u5b58\u95a2\u4fc2\u306b\u3064\u3044\u3066\u4e00\u5207\u8a18\u8f09\u304c\u7121\u3044\u3053\u3068\u304c\u539f\u56e0\u3067\u3059\u3002 Java \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306f\u3001\u3053\u3061\u3089<\/a> \u304b\u3089\u53d6\u5f97\u3067\u304d\u307e\u3059\u3002 template \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4e2d\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u69cb\u6210\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u62e1\u5f35\u5b50 .mustcache \u306f OpenAPI Generator \u304c\u5229\u7528\u3057\u3066\u3044\u308b\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30a8\u30f3\u30b8\u30f3 Mustache<\/a> \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u3067\u3059\u3002<\/p>\n \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u751f\u6210\u6642\u3001 \u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c\u306e\u30b3\u30fc\u30c9\u3092\u751f\u6210\u3059\u308b\u305f\u3081\u306b\u306f\u3001\u65b0\u3057\u304f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u8ffd\u52a0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 \u307e\u305f\u3001ApiClient.mustache<\/a>, api.mustache<\/a> \u3082\u3001\u4e0a\u8a18 WebClient \u3092 DI \u3067\u304d\u308b\u3088\u3046\u306b\u5c11\u3057\u305a\u3064\u5185\u5bb9\u3092\u5909\u66f4\u3057\u3066\u3044\u307e\u3059\u3002\u3053\u3061\u3089\u3082\u5185\u5bb9\u306f\u30ea\u30f3\u30af\u5148\u3092\u53c2\u7167\u304f\u3060\u3055\u3044\u3002<\/p>\n \u305f\u3060\u3057\u3001\u65b0\u3057\u3044\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u8ffd\u52a0\u3057\u3066\u3082\u3001\u305d\u308c\u3060\u3051\u3067\u306f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u8aad\u307f\u53d6\u3063\u3066\u304f\u308c\u307e\u305b\u3093\u3002Groovy \u306b\u4ee5\u4e0b\u306e Override \u30e1\u30bd\u30c3\u30c9\u3092\u8ffd\u52a0\u3057\u3066\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u8aad\u307f\u53d6\u308b\u3088\u3046\u306b\u3057\u307e\u3059\u3002<\/p>\n \u5148\u307b\u3069\u89e6\u308c\u307e\u305b\u3093\u3067\u3057\u305f\u304c\u3001\u4e0a\u8a18\u306e WebClientConfig.mustache \u3092\u5143\u306b\u751f\u6210\u3055\u308c\u308b WebClientConfig.java \u306f\u3001Spring Boot \u306e\u5b9a\u7fa9\u30d5\u30a1\u30a4\u30eb\u3067\u3042\u308b application.yml \u304b\u3089 OAuth2 \u95a2\u9023\u306e\u8a2d\u5b9a\u5185\u5bb9\u3092\u8aad\u307f\u53d6\u308b\u3053\u3068\u3092\u524d\u63d0\u3068\u3057\u3066\u3044\u307e\u3059\u3002(\u3053\u306e\u8fba\u308a<\/a>\u3084\u3001\u3053\u306e\u8fba\u308a<\/a>\u3067\u3059\u3002)<\/p>\n application.yml \u3082\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u304c\u5b58\u5728\u3057\u306a\u3044\u305f\u3081\u3001\u5148\u307b\u3069\u540c\u69d8\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u3066\u3001\u305d\u308c\u3092\u8aad\u307f\u53d6\u308b\u30b3\u30fc\u30c9\u3092 Groovy \u30b9\u30af\u30ea\u30d7\u30c8\u306b\u8ffd\u8a18\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n \u5148\u307b\u3069\u306e application.yml \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306f\u3001\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c URL \u3084\u30b9\u30b3\u30fc\u30d7\u3001audience \u3092\u56fa\u5b9a\u3067\u8a18\u8f09\u3057\u3066\u3044\u307e\u3057\u305f\u3002\uff08\u4ee5\u4e0b\u306e\u2605\u30de\u30fc\u30af\u3092\u3064\u3051\u3066\u3044\u308b\u90e8\u5206\u3067\u3059\u3002\uff09<\/p>\n \u3069\u3046\u305b\u306a\u3089\u3001OpenAPI \u306e\u5b9a\u7fa9\u30d5\u30a1\u30a4\u30eb\u306e SecuritySchemes \u304b\u3089\u8aad\u307f\u53d6\u3063\u305f\u5185\u5bb9\u3067\u7f6e\u63db\u3057\u305f\u3044\u3067\u3059\u3002<\/p>\n \u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c URL \u3084\u30b9\u30b3\u30fc\u30d7\u306f\u3001\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u72b6\u614b\u3067 OpenAPI \u5b9a\u7fa9\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u5185\u5bb9\u3092\u8aad\u307f\u53d6\u3063\u3066\u304f\u308c\u307e\u3059\u3002 audience \u306b\u95a2\u3057\u3066\u306f\u3001 OpenAPI \u306e\u6a19\u6e96\u4ed5\u69d8\u306b\u306f\u542b\u307e\u308c\u3066\u3044\u306a\u3044\u5185\u5bb9\u3068\u306a\u308a\u3001Specification Extensions<\/a> \u3068\u3057\u3066\u5b9a\u7fa9\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u3001\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u306f OpenAPI Generator \u3067\u306f\u8aad\u307f\u53d6\u3063\u3066\u304f\u308c\u307e\u305b\u3093\u3002<\/p>\n OpenAPI Generator \u3067\u306e SecuritySchemes \u306e\u8aad\u307f\u53d6\u308a\u306f\u3001DefaultCodegen#fromSecurity<\/a> \u304c\u884c\u306a\u3063\u3066\u3044\u307e\u3059\u3002 fromSecurity \u304b\u3089\u3055\u3089\u306b\u3001 DefaultCodegen#setOAuth2Info<\/a> \u3068\u3044\u3046 private \u30e1\u30bd\u30c3\u30c9\u304c\u547c\u3070\u308c\u3066\u3044\u307e\u3059\u3002 \u3055\u3089\u306b\u8aad\u307f\u9032\u3081\u308b\u3068\u3001OAuthFlow \u306b getExtensions<\/a> \u3068\u3044\u3046\u30e1\u30bd\u30c3\u30c9\u304c\u3042\u308a\u3001 \u5b9f\u969b\u306b Groovy \u30b9\u30af\u30ea\u30d7\u30c8\u3092\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u5909\u66f4\u3057\u3066\u307f\u3066\u8a66\u3057\u3066\u307f\u307e\u3059\u3002setOAuth2Info \u306f private \u30b9\u30b3\u30fc\u30d7\u306a\u306e\u3067\u3001\u5185\u5bb9\u3092 DefaultCodegen \u304b\u3089\u305d\u306e\u307e\u307e\u6301\u3063\u3066\u304d\u3066 getExtension \u3059\u308b\u30b3\u30fc\u30c9\u3092\u8ffd\u8a18\u3057\u3066\u3044\u307e\u3059\u3002 \u6b21\u306b application.yml \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u3092\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u5909\u66f4\u3057\u307e\u3059\u3002<\/p>\n \u3053\u306e\u72b6\u614b\u3067 Groovy \u3092\u5b9f\u884c\u3059\u308b\u3068\u3001SecuritySchemes \u304b\u3089\u5185\u5bb9\u3092\u8aad\u307f\u53d6\u3063\u305f src\/main\/resources\/application.yml \u3092\u5f97\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n \u4eca\u56de\u306f Java + Spring WebFlux \u306e\u4f8b\u3067 OpenAPI Generator \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u751f\u6210\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002ClientCodegen \u3092\u7d99\u627f\u3057\u305f\u30af\u30e9\u30b9\u3092\u4f5c\u308a\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4fee\u6b63\u30fb\u8ffd\u8a18\u3059\u308b\u3053\u3068\u3067\u3001\u4ed6\u306e\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u308b\u8a00\u8a9e\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u3082\u81ea\u5206\u306e\u597d\u304d\u306a\u3088\u3046\u306b\u5909\u66f4\u3059\u308b\u3053\u3068\u304c\u53ef\u80fd\u3068\u601d\u3044\u307e\u3059\u3002\uff08OpenAPI Generator \u306e\u30b3\u30fc\u30c9\u306f\u8aad\u307f\u89e3\u304f\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u304c\uff09OpenAPI Generator \u306e\u30b3\u30fc\u30c9\u751f\u6210\u306b\u3064\u3044\u3066<\/h2>\n
\nJava \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u3092\u751f\u6210\u3057\u305f\u5834\u5408\u3001README \u306b\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u304c\u51fa\u529b\u3055\u308c\u307e\u3059\u304c\u3001 setAccessToken \u3057\u3066\u306d\u3001\u3068\u3044\u3046\u3053\u3068\u304f\u3089\u3044\u3057\u304b\u66f8\u304b\u308c\u3066\u304a\u3089\u305a\u3001\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u306e\u767a\u884c\u306e\u90e8\u5206\u306b\u306f\u89e6\u308c\u3089\u308c\u3066\u3044\u307e\u305b\u3093\u3002
\n(Java \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u751f\u6210\u3067\u306f\u3001\u30c7\u30d5\u30a9\u30eb\u30c8\u3067 OkHttp 3<\/a> \u3092\u5229\u7528\u3057\u305f\u30b3\u30fc\u30c9\u304c\u751f\u6210\u3055\u308c\u307e\u3059\u3002OkHttp 3 \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u306e\u5834\u5408\u3001\u4e00\u5fdc\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c\u306e\u30b3\u30fc\u30c9\u306f\u751f\u6210\u3055\u308c\u307e\u3059\u304c\u3001Apache Oltu<\/a> \u3068\u3044\u3046\u65e2\u306b\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u7d42\u4e86\u3057\u305f\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u4f7f\u3063\u305f\u30b3\u30fc\u30c9\u306a\u306e\u3067\u3001\u3042\u307e\u308a\u5b9f\u6848\u4ef6\u3067\u306f\u4f7f\u3044\u305f\u304f\u3042\u308a\u307e\u305b\u3093\uff09<\/p>\n public static void main(String[] args) {\n ApiClient defaultClient = Configuration.getDefaultApiClient();\n defaultClient.setBasePath(\"https:\/\/mail.paas.crmstyle.com\/e\");\n \n \/\/ Configure OAuth2 access token for authorization: mail_oauth\n OAuth mail_oauth = (OAuth) defaultClient.getAuthentication(\"mail_oauth\");\n mail_oauth.setAccessToken(\"YOUR ACCESS TOKEN\");\n\n DefaultApi apiInstance = new DefaultApi(defaultClient);\n String user = \"user_example\"; \/\/ String | user name\n DeliverySettingRequest deliverySettingRequest = new DeliverySettingRequest(); \/\/ DeliverySettingRequest | \n try {\n DeliveryResponse result = apiInstance.createMailDeliverySetting(user, deliverySettingRequest);\n System.out.println(result);\n } catch (ApiException e) {\n System.err.println(\"Exception when calling DefaultApi#createMailDeliverySetting\");\n System.err.println(\"Status code: \" + e.getCode());\n System.err.println(\"Reason: \" + e.getResponseBody());\n System.err.println(\"Response headers: \" + e.getResponseHeaders());\n e.printStackTrace();\n }\n }\n<\/pre>\n
\n\u5b9f\u884c\u74b0\u5883\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002OpenAPI Generator \u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u3001\u73fe\u6642\u70b9\u306e\u6700\u65b0\u5b89\u5b9a\u7248\u306e 4.2.2 \u3092\u4f7f\u3044\u307e\u3057\u305f\u3002<\/p>\n$ java -version\njava version \"1.8.0_144\"\nJava(TM) SE Runtime Environment (build 1.8.0_144-b01)\nJava HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)\n<\/pre>\n
\nOpenAPI \u306e\u5b9a\u7fa9\u30d5\u30a1\u30a4\u30eb\u306f\u3001Synergy! \u30e1\u30fc\u30ebAPI<\/a> \u3092\u30d9\u30fc\u30b9\u306b\u3057\u305f\u3082\u306e\u3092\u4f7f\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\nGroovy \u3092\u4f7f\u3046<\/h2>\n
@Grab(group = 'org.openapitools', module = 'openapi-generator-cli', version = '4.2.2')\nimport org.openapitools.codegen.*\nimport org.openapitools.codegen.languages.*\n\nclass TechscoreJavaClientCodegen extends JavaClientCodegen {\n\n static main(String[] args) {\n OpenAPIGenerator.main(args)\n }\n\n TechscoreJavaClientCodegen() {\n super()\n }\n\n String name = \"techscore-codegen\"\n}\n<\/pre>\n
groovy \\\n .\/techscore-client-codegen.groovy \\\n generate \\\n -i .\/openapi.yml \\\n -g TechscoreJavaClientCodegen \\\n -o .\/output \\\n --library webclient\n<\/pre>\n
\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba<\/h2>\n
\u751f\u6210\u3055\u308c\u308b\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u30fb\u8ffd\u52a0\u3059\u308b<\/h3>\n
\n\u3053\u308c\u3092\u89e3\u6d88\u3059\u308b\u305f\u3081\u306b\u3001OpenAPI Generator \u306f\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u304b\u3089\u30b3\u30fc\u30c9\u751f\u6210\u3059\u308b\u305f\u3081\u3001OpenAPI Generator \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n
\n\u3053\u308c\u3092\u30b3\u30d4\u30fc\u3057\u3066\u3001\u30d5\u30a1\u30a4\u30eb\u3092\u4fee\u6b63\u30fb\u8ffd\u52a0\u3059\u308b\u3053\u3068\u3067\u751f\u6210\u3055\u308c\u308b\u30b3\u30fc\u30c9\u3092\u5909\u66f4\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002
\n\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u3057\u3066\u3001template \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u914d\u4e0b\u306b\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002<\/p>\nmkdir -p {repodir,template} && cd repodir\ngit init\ngit remote add origin https:\/\/github.com\/OpenAPITools\/openapi-generator.git\ngit config core.sparsecheckout true\nvi .git\/info\/sparse-checkout \u2190 modules\/openapi-generator\/src\/main\/resources\/Java\/ \u3092\u8ffd\u8a18 \ngit fetch origin\ngit checkout v4.2.2\ngit pull origin v4.2.2\ncp -pR modules\/openapi-generator\/src\/main\/resources\/Java\/* ..\/template\/\ncd ..\/ && rm -Rf repodir\n<\/pre>\n
$ tree -L 3 template\ntemplate\n\u251c\u2500\u2500 auth\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 ApiKeyAuth.mustache\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 Authentication.mustache\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 HttpBasicAuth.mustache\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 HttpBearerAuth.mustache\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 OAuth.mustache\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 OAuthFlow.mustache\n\u251c\u2500\u2500 libraries\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 feign\n\u2502\u00a0\u00a0 (\u7565)\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 webclient\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 auth\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 ApiClient.mustache\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 README.mustache\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 api.mustache\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 api_test.mustache\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 pom.mustache\n\u251c\u2500\u2500 ApiClient.mustache\n(\u7565)\n\u251c\u2500\u2500 build.gradle.mustache\n\u251c\u2500\u2500 build.sbt.mustache\n(\u7565)\n\u2514\u2500\u2500 xmlAnnotation.mustache\n<\/pre>\n
--library webclient<\/code> (Spring WebFlux\u306e\u30b3\u30fc\u30c9\u751f\u6210)\u3092\u6307\u5b9a\u3059\u308b\u3068\u3001 libraries\/webclient \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u304c\u4f7f\u308f\u308c\u308b\u3053\u3068\u306b\u306a\u308a\u307e\u3059\u3002
\n\u4eca\u56de\u306e\u5834\u5408\u3001 libraries\/webclient\/build.gradle.mustache \u3092\u4f5c\u6210\u3059\u308c\u3070\u3001build.gradle \u3092\u5909\u66f4\u3067\u304d\u307e\u3059\u3002
\nbuild.gradle.mustache \u306e\u5185\u5bb9\u306f\u3053\u3061\u3089<\/a>\u3092\u53c2\u7167\u304f\u3060\u3055\u3044\u3002
\n\u4ee5\u4e0b\u306e\u3088\u3046\u306b -t \u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8ffd\u52a0\u3057\u3066\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u6307\u5b9a\u3059\u308b\u3053\u3068\u3067\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u5dee\u3057\u66ff\u3048\u304c\u53ef\u80fd\u3067\u3059\u3002<\/p>\ngroovy \\\n .\/techscore-client-codegen.groovy \\\n generate \\\n -i .\/openapi.yml \\\n -g TechscoreJavaClientCodegen \\\n -o .\/output \\\n -t .\/template \\\n --library webclient\n<\/pre>\n
\n\u4eca\u56de\u306f\u3001Spring WebFlux \u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30b3\u30fc\u30c9\u306e\u305f\u3081\u3001WebClient<\/a> \u3092 DI \u3067\u304d\u308b\u3088\u3046\u306b\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4f5c\u6210\u3057 libraries\/webclient\/WebClientConfig.mustache<\/a> \u306b\u767b\u9332\u3057\u307e\u3057\u305f\u3002
\nSynergy! \u30e1\u30fc\u30ebAPI<\/a> \u3067\u306f\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u767a\u884c\u6642\u306b scope \u3068 audience \u3092\u30ea\u30af\u30a8\u30b9\u30c8\u30dc\u30c7\u30a3\u306b\u542b\u3081\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u3001\u305d\u306e\u3088\u3046\u306a\u5b9f\u88c5\u3092\u3057\u3066\u3044\u307e\u3059\u3002\u307e\u305f\u3001\u30a2\u30af\u30bb\u30b9\u30c8\u30fc\u30af\u30f3\u306f\u3042\u308b\u7a0b\u5ea6\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u5229\u7528\u3059\u308b\u3088\u3046\u306b\u3057\u3066\u3044\u307e\u3059\u3002\u5b9f\u88c5\u5185\u5bb9\u306f\u30ea\u30f3\u30af\u5148<\/a>\u3092\u53c2\u7167\u3044\u305f\u3060\u3051\u308c\u3070\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n @Override\n public void processOpts() {\n final String invokerFolder = (sourceFolder + '\/' + invokerPackage).replace(\".\", \"\/\");\n final String apiFolder = (sourceFolder + '\/' + apiPackage).replace(\".\", \"\/\");\n super.processOpts()\n\n if (WEBCLIENT.equals(getLibrary())) {\n \/\/ add WebClientConfig\n supportingFiles.add(new SupportingFile(\"WebClientConfig.mustache\", invokerFolder, \"WebClientConfig.java\"))\n }\n }\n<\/pre>\n
Spring Boot \u306e\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb application.yml \u3092\u8ffd\u52a0\u3059\u308b<\/h3>\n
{{#authMethods}}{{#isOAuth}}\nspring:\n security.oauth2.client:\n provider:\n paas:\n token-uri: https:\/\/auth.paas.crmstyle.com\/oauth2\/token\n registration:\n paas:\n authorization-grant-type: client_credentials\n client-id: your-client-id\n client-secret: your-client-secret\n scope:\n - mail:send\n - mail:result\n audience: https:\/\/mail.paas.crmstyle.com{{\/isOAuth}}{{\/authMethods}}\nlogging:\n level:\n reactor.netty: DEBUG\n<\/pre>\n
@Override\n public void processOpts() {\n final String invokerFolder = (sourceFolder + '\/' + invokerPackage).replace(\".\", \"\/\");\n final String apiFolder = (sourceFolder + '\/' + apiPackage).replace(\".\", \"\/\");\n super.processOpts()\n\n if (WEBCLIENT.equals(getLibrary())) {\n \/\/ add WebClientConfig\n supportingFiles.add(new SupportingFile(\"WebClientConfig.mustache\", invokerFolder, \"WebClientConfig.java\"))\n \/\/ add application.yml \u2605\u8ffd\u8a18\n supportingFiles.add(new SupportingFile(\"application.yml.mustache\", projectFolder + '\/resources', \"application.yml\"))\n }\n }\n<\/pre>\n
SecuritySchemes \u3092\u8aad\u307f\u53d6\u3063\u3066\u7f6e\u63db\u3059\u308b<\/h3>\n
{{#authMethods}}{{#isOAuth}}\nspring:\n security.oauth2.client:\n provider:\n paas:\n token-uri: https:\/\/auth.paas.crmstyle.com\/oauth2\/token \u2605\u3053\u3053\n registration:\n paas:\n authorization-grant-type: client_credentials\n client-id: your-client-id\n client-secret: your-client-secret\n scope: \u2605\u3053\u3053\n - mail:send\n - mail:result\n audience: https:\/\/mail.paas.crmstyle.com \u2605\u3053\u3053{{\/isOAuth}}{{\/authMethods}}\nlogging:\n level:\n reactor.netty: DEBUG\n<\/pre>\n
securitySchemes:\n mail_oauth:\n type: oauth2\n description: mail auth\n flows:\n clientCredentials:\n tokenUrl: \"https:\/\/auth.paas.crmstyle.com\/oauth2\/token\" \u2605\u3053\u308c\u306b\u52d5\u7684\u306b\u5dee\u3057\u66ff\u3048\u305f\u3044\n scopes: \u2605\u3053\u308c\u306b\u52d5\u7684\u306b\u5dee\u3057\u66ff\u3048\u305f\u3044\n mail:send: \"delivery\"\n mail:result: \"get the delivery results\"\n x-audience: \"https:\/\/mail.paas.crmstyle.com\" \u2605\u3053\u308c\u306b\u52d5\u7684\u306b\u5dee\u3057\u66ff\u3048\u305f\u3044\n<\/pre>\n
\napplication.yml \u306e\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u5909\u66f4\u3059\u308b\u3053\u3068\u3067\u3001\u5dee\u3057\u66ff\u3048\u304c\u53ef\u80fd\u3067\u3059\u3002<\/p>\n{{#authMethods}}{{#isOAuth}}\nspring:\n security.oauth2.client:\n provider:\n paas:\n token-uri: {{tokenUrl}} \u2605\u3053\u308c\u3067\u5dee\u3057\u66ff\u3048\u53ef\u80fd\n registration:\n paas:\n authorization-grant-type: client_credentials\n client-id: your-client-id\n client-secret: your-client-secret\n scope: \u2605\u3053\u308c\u3067\u5dee\u3057\u66ff\u3048\u53ef\u80fd\n {{#scopes}}\n - \"{{scope}}\"\n {{\/scopes}}\n audience: https:\/\/mail.paas.crmstyle.com \u2605\u307e\u3060\u7f6e\u63db\u3067\u304d\u306a\u3044 {{\/isOAuth}}{{\/authMethods}}\nlogging:\n level:\n reactor.netty: DEBUG\n<\/pre>\n
\nDefaultCodegen \u306f\u3001 JavaClientCodegen \u306e\u4e00\u756a\u7956\u5148\u306e\u7d99\u627f\u5143\u3067\u3059\u3002
\n\u5185\u5bb9\u3092\u898b\u308b\u3068\u3001SecuritySchemes \u304b\u3089\u8aad\u307f\u53d6\u3063\u305f\u5185\u5bb9\u3092\u3001CodegenSecurity \u3068\u3044\u3046\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u8a70\u3081\u3066\u3044\u3063\u3066\u3044\u308b\u3088\u3046\u306b\u898b\u3048\u307e\u3059\u3002<\/p>\n \/**\n * Convert map of OAS SecurityScheme objects to a list of Codegen Security objects\n *\n * @param securitySchemeMap a map of OAS SecuritySchemeDefinition object\n * @return a list of Codegen Security objects\n *\/\n @SuppressWarnings(\"static-method\")\n public List fromSecurity(Map<String, SecurityScheme> securitySchemeMap) {\n if (securitySchemeMap == null) {\n return Collections.emptyList();\n }\n\n List codegenSecurities = new ArrayList(securitySchemeMap.size());\n for (String key : securitySchemeMap.keySet()) {\n final SecurityScheme securityScheme = securitySchemeMap.get(key);\n\n CodegenSecurity cs = CodegenModelFactory.newInstance(CodegenModelType.SECURITY);\n cs.name = key;\n cs.type = securityScheme.getType().toString();\n cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = false;\n cs.isBasicBasic = cs.isBasicBearer = false;\n cs.scheme = securityScheme.getScheme();\n\n if (SecurityScheme.Type.APIKEY.equals(securityScheme.getType())) {\n cs.isBasic = cs.isOAuth = false;\n cs.isApiKey = true;\n cs.keyParamName = securityScheme.getName();\n cs.isKeyInHeader = securityScheme.getIn() == SecurityScheme.In.HEADER;\n cs.isKeyInQuery = securityScheme.getIn() == SecurityScheme.In.QUERY;\n cs.isKeyInCookie = securityScheme.getIn() == SecurityScheme.In.COOKIE; \/\/it assumes a validation step prior to generation. (cookie-auth supported from OpenAPI 3.0.0)\n } else if (SecurityScheme.Type.HTTP.equals(securityScheme.getType())) {\n cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isOAuth = false;\n cs.isBasic = true;\n if (\"basic\".equals(securityScheme.getScheme())) {\n cs.isBasicBasic = true;\n } else if (\"bearer\".equals(securityScheme.getScheme())) {\n cs.isBasicBearer = true;\n cs.bearerFormat = securityScheme.getBearerFormat();\n }\n } else if (SecurityScheme.Type.OAUTH2.equals(securityScheme.getType())) {\n cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isBasic = false;\n cs.isOAuth = true;\n final OAuthFlows flows = securityScheme.getFlows();\n if (securityScheme.getFlows() == null) {\n throw new RuntimeException(\"missing oauth flow in \" + cs.name);\n }\n if (flows.getPassword() != null) {\n setOauth2Info(cs, flows.getPassword());\n cs.isPassword = true;\n cs.flow = \"password\";\n } else if (flows.getImplicit() != null) {\n setOauth2Info(cs, flows.getImplicit());\n cs.isImplicit = true;\n cs.flow = \"implicit\";\n } else if (flows.getClientCredentials() != null) {\n setOauth2Info(cs, flows.getClientCredentials());\n cs.isApplication = true;\n cs.flow = \"application\";\n } else if (flows.getAuthorizationCode() != null) {\n setOauth2Info(cs, flows.getAuthorizationCode());\n cs.isCode = true;\n cs.flow = \"accessCode\";\n } else {\n throw new RuntimeException(\"Could not identify any oauth2 flow in \" + cs.name);\n }\n }\n\n codegenSecurities.add(cs);\n }\n }\n<\/pre>\n
\n\u5b9f\u88c5\u3092\u898b\u308b\u3068\u3001OAuth Flow Object<\/a> \u306e\u5185\u5bb9\u3092\u3001CodegenSecurity \u306b\u8a70\u3081\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u3002<\/p>\n private void setOauth2Info(CodegenSecurity codegenSecurity, OAuthFlow flow) {\n codegenSecurity.authorizationUrl = flow.getAuthorizationUrl();\n codegenSecurity.tokenUrl = flow.getTokenUrl();\n\n if (flow.getScopes() != null && !flow.getScopes().isEmpty()) {\n List<Map<String, Object>> scopes = new ArrayList<Map<String, Object>>();\n int count = 0, numScopes = flow.getScopes().size();\n for (Map.Entry<String, String> scopeEntry : flow.getScopes().entrySet()) {\n Map<String, Object> scope = new HashMap<String, Object>();\n scope.put(\"scope\", scopeEntry.getKey());\n scope.put(\"description\", escapeText(scopeEntry.getValue()));\n\n count += 1;\n if (count < numScopes) {\n scope.put(\"hasMore\", \"true\");\n } else {\n scope.put(\"hasMore\", null);\n }\n\n scopes.add(scope);\n }\n codegenSecurity.scopes = scopes;\n }\n }\n<\/pre>\n
\nCodegenSecurity \u306b\u3001 vendorExtensions<\/a> \u3068\u3044\u3046\u30d7\u30ed\u30d1\u30c6\u30a3\u304c\u7528\u610f\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u304c\u5206\u304b\u308a\u307e\u3059\u3002
\nSpecification Extensions \u306e\u5185\u5bb9\u3092 OAuthFlow#getExtensions\u304b\u3089\u8aad\u307f\u53d6\u3063\u3066\u3001 CodegenSecurity \u306e vendorExtensions \u306b\u30bb\u30c3\u30c8\u3059\u308c\u3070\u3001\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb\u306e\u7f6e\u63db\u304c\u53ef\u80fd\u3068\u306a\u308b\u306e\u3067\u306f\u3068\u63a8\u6e2c\u3067\u304d\u307e\u3059\u3002<\/p>\n
\nfromSecurity \u304c setOAuth2Info \u3092\u547c\u3076\u4f5c\u308a\u306b\u306a\u3063\u3066\u3044\u308b\u305f\u3081\u3001fromSecurity \u3082\u5185\u5bb9\u306f\u5909\u66f4\u305b\u305a\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n@Grab(group = 'org.openapitools', module = 'openapi-generator-cli', version = '4.2.2')\nimport org.openapitools.codegen.*\nimport org.openapitools.codegen.languages.*\nimport io.swagger.v3.oas.models.security.*;\n\nclass TechscoreJavaClientCodegen extends JavaClientCodegen {\n\n static main(String[] args) {\n OpenAPIGenerator.main(args)\n }\n\n TechscoreJavaClientCodegen() {\n super()\n }\n\n String name = \"techscore-codegen\"\n \n @Override\n public void processOpts() {\n final String invokerFolder = (sourceFolder + '\/' + invokerPackage).replace(\".\", \"\/\");\n final String apiFolder = (sourceFolder + '\/' + apiPackage).replace(\".\", \"\/\");\n super.processOpts()\n\n if (WEBCLIENT.equals(getLibrary())) {\n \/\/ add WebClientConfig\n supportingFiles.add(new SupportingFile(\"WebClientConfig.mustache\", invokerFolder, \"WebClientConfig.java\"))\n \/\/ add application.yml\n supportingFiles.add(new SupportingFile(\"application.yml.mustache\", projectFolder + '\/resources', \"application.yml\"))\n }\n }\n\n @Override\n @SuppressWarnings(\"static-method\")\n public List fromSecurity(Map<String, SecurityScheme> securitySchemeMap) {\n if (securitySchemeMap == null) {\n return Collections.emptyList();\n } \n (\u7565)\n return codegenSecurities;\n }\n\n private void setOauth2Info(CodegenSecurity codegenSecurity, OAuthFlow flow) {\n codegenSecurity.authorizationUrl = flow.getAuthorizationUrl();\n codegenSecurity.tokenUrl = flow.getTokenUrl();\n\n if (flow.getScopes() != null && !flow.getScopes().isEmpty()) {\n List<Map<String, Object>> scopes = new ArrayList<Map<String, Object>>();\n int count = 0, numScopes = flow.getScopes().size();\n for (Map.Entry<String, String> scopeEntry : flow.getScopes().entrySet()) {\n Map<String, Object> scope = new HashMap<String, Object>();\n scope.put(\"scope\", scopeEntry.getKey());\n scope.put(\"description\", escapeText(scopeEntry.getValue()));\n\n count += 1;\n if (count < numScopes) {\n scope.put(\"hasMore\", \"true\");\n } else {\n scope.put(\"hasMore\", null);\n }\n\n scopes.add(scope);\n }\n codegenSecurity.scopes = scopes;\n }\n \/\/ Specification Extensions \u3092\u30bb\u30c3\u30c8\n if (flow.getExtensions() != null) {\n Map<String, Object> extensions = flow.getExtensions();\n codegenSecurity.vendorExtensions = extensions;\n }\n }\n}\n<\/pre>\n
{{#authMethods}}{{#isOAuth}}\nspring:\n security.oauth2.client:\n provider:\n paas:\n token-uri: {{tokenUrl}}\n registration:\n paas:\n authorization-grant-type: client_credentials\n client-id: your-client-id\n client-secret: your-client-secret\n scope:\n {{#scopes}}\n - \"{{scope}}\"\n {{\/scopes}}\n {{#vendorExtensions}} \u2605 \u5909\u66f4\n audience: {{x-audience}}{{\/vendorExtensions}}{{\/isOAuth}}{{\/authMethods}}\nlogging:\n level:\n reactor.netty: DEBUG\n<\/pre>\n
spring:\n security.oauth2.client:\n provider:\n paas:\n token-uri: https:\/\/auth.paas.crmstyle.com\/oauth2\/token\n registration:\n paas:\n authorization-grant-type: client_credentials\n client-id: your-client-id\n client-secret: your-client-secret\n scope:\n - \"mail:send\"\n - \"mail:result\"\n audience: https:\/\/mail.paas.crmstyle.com\nlogging:\n level:\n reactor.netty: DEBUG\n<\/pre>\n
\u7d42\u308f\u308a\u306b<\/h2>\n
\n\u7686\u3055\u3093\u3082\u662f\u975e\u4e00\u5ea6\u8a66\u3057\u3066\u307f\u3066\u306f\u3044\u304b\u304c\u3067\u3057\u3087\u3046\u304b\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"