From 05b0d1f882892fd4599b9b51e2e6095474dbfb19 Mon Sep 17 00:00:00 2001 From: Tokuhiro Matsuno Date: Mon, 24 Jul 2023 13:29:07 +0900 Subject: [PATCH] Add backward compatible method for LIFF APIs https://github.com/line/line-openapi/pull/26 see also: https://github.com/line/line-bot-sdk-python/pull/486 --- .../bot/codegen/LineJavaCodegenGenerator.java | 34 +++-- .../main/resources/body/api/LiffClient.java | 21 +++ .../body/{ => model}/AudioMessage.java | 0 .../resources/body/{ => model}/Event.java | 0 .../body/{ => model}/FlexMessage.java | 0 .../body/{ => model}/ImageMessage.java | 0 .../body/{ => model}/LocationMessage.java | 0 .../body/{ => model}/QuickReplyItem.java | 0 .../resources/body/{ => model}/Source.java | 0 .../body/{ => model}/StickerMessage.java | 0 .../body/{ => model}/TemplateMessage.java | 0 .../body/{ => model}/TextMessage.java | 0 .../body/{ => model}/VideoMessage.java | 0 .../LiffClientBackwardCompatibilityTest.java | 138 ++++++++++++++++++ templates/api.mustache | 1 + 15 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 buildSrc/src/main/resources/body/api/LiffClient.java rename buildSrc/src/main/resources/body/{ => model}/AudioMessage.java (100%) rename buildSrc/src/main/resources/body/{ => model}/Event.java (100%) rename buildSrc/src/main/resources/body/{ => model}/FlexMessage.java (100%) rename buildSrc/src/main/resources/body/{ => model}/ImageMessage.java (100%) rename buildSrc/src/main/resources/body/{ => model}/LocationMessage.java (100%) rename buildSrc/src/main/resources/body/{ => model}/QuickReplyItem.java (100%) rename buildSrc/src/main/resources/body/{ => model}/Source.java (100%) rename buildSrc/src/main/resources/body/{ => model}/StickerMessage.java (100%) rename buildSrc/src/main/resources/body/{ => model}/TemplateMessage.java (100%) rename buildSrc/src/main/resources/body/{ => model}/TextMessage.java (100%) rename buildSrc/src/main/resources/body/{ => model}/VideoMessage.java (100%) create mode 100644 clients/line-liff-client/src/test/java/com/linecorp/bot/liff/client/LiffClientBackwardCompatibilityTest.java diff --git a/buildSrc/src/main/java/com/linecorp/bot/codegen/LineJavaCodegenGenerator.java b/buildSrc/src/main/java/com/linecorp/bot/codegen/LineJavaCodegenGenerator.java index ca2c60b7d..1f9ff3065 100644 --- a/buildSrc/src/main/java/com/linecorp/bot/codegen/LineJavaCodegenGenerator.java +++ b/buildSrc/src/main/java/com/linecorp/bot/codegen/LineJavaCodegenGenerator.java @@ -107,20 +107,29 @@ public ModelsMap postProcessModels(ModelsMap objs) { } // fill src/main/resources/body/*.java to the body of the class. - try (InputStream inputStream = getClass().getClassLoader() - .getResourceAsStream("body/" + codegenModel.name + ".java")) { - if (inputStream != null) { - String src = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); - codegenModel.vendorExtensions.put("x-body", indent4(src)); - } - } catch (IOException e) { - // do nothing. - } + String body = readPartialBody("body/model/" + codegenModel.name + ".java"); + codegenModel.vendorExtensions.put("x-body", body); } return modelsMap; } + private String readPartialBody(String path) { + // fill src/main/resources/body/*.java to the body of the class. + try (InputStream inputStream = getClass().getClassLoader() + .getResourceAsStream(path)) { + if (inputStream != null) { + System.out.println("Partial body file found: " + path); + String src = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + return indent4(src); + } + } catch (IOException e) { + // do nothing. + } + System.out.println("Partial body file NOT found: " + path); + return null; + } + @Override public Map postProcessAllModels(Map objs) { final Map processed = super.postProcessAllModels(objs); @@ -203,6 +212,13 @@ protected ImmutableMap.Builder addMustacheLambdas() { .replace("Client", "") + "ExceptionBuilder" ); + }) + .put("injectbody", (fragment, writer) -> { + String text = fragment.execute(); + String body = readPartialBody("body/api/" + text + ".java"); + if (body != null) { + writer.write(body); + } }); } diff --git a/buildSrc/src/main/resources/body/api/LiffClient.java b/buildSrc/src/main/resources/body/api/LiffClient.java new file mode 100644 index 000000000..4f185dce7 --- /dev/null +++ b/buildSrc/src/main/resources/body/api/LiffClient.java @@ -0,0 +1,21 @@ +@Deprecated +default CompletableFuture> liffV1AppsGet() { + return getAllLIFFApps(); +} + +@Deprecated +default CompletableFuture> liffV1AppsLiffIdDelete(@Path("liffId") String liffId) { + return deleteLIFFApp(liffId); +} + +@Deprecated +default CompletableFuture> liffV1AppsLiffIdPut( + @Path("liffId") String liffId, + @Body UpdateLiffAppRequest updateLiffAppRequest) { + return updateLIFFApp(liffId, updateLiffAppRequest); +} + +@Deprecated +default CompletableFuture> liffV1AppsPost(@Body AddLiffAppRequest addLiffAppRequest) { + return addLIFFApp(addLiffAppRequest); +} diff --git a/buildSrc/src/main/resources/body/AudioMessage.java b/buildSrc/src/main/resources/body/model/AudioMessage.java similarity index 100% rename from buildSrc/src/main/resources/body/AudioMessage.java rename to buildSrc/src/main/resources/body/model/AudioMessage.java diff --git a/buildSrc/src/main/resources/body/Event.java b/buildSrc/src/main/resources/body/model/Event.java similarity index 100% rename from buildSrc/src/main/resources/body/Event.java rename to buildSrc/src/main/resources/body/model/Event.java diff --git a/buildSrc/src/main/resources/body/FlexMessage.java b/buildSrc/src/main/resources/body/model/FlexMessage.java similarity index 100% rename from buildSrc/src/main/resources/body/FlexMessage.java rename to buildSrc/src/main/resources/body/model/FlexMessage.java diff --git a/buildSrc/src/main/resources/body/ImageMessage.java b/buildSrc/src/main/resources/body/model/ImageMessage.java similarity index 100% rename from buildSrc/src/main/resources/body/ImageMessage.java rename to buildSrc/src/main/resources/body/model/ImageMessage.java diff --git a/buildSrc/src/main/resources/body/LocationMessage.java b/buildSrc/src/main/resources/body/model/LocationMessage.java similarity index 100% rename from buildSrc/src/main/resources/body/LocationMessage.java rename to buildSrc/src/main/resources/body/model/LocationMessage.java diff --git a/buildSrc/src/main/resources/body/QuickReplyItem.java b/buildSrc/src/main/resources/body/model/QuickReplyItem.java similarity index 100% rename from buildSrc/src/main/resources/body/QuickReplyItem.java rename to buildSrc/src/main/resources/body/model/QuickReplyItem.java diff --git a/buildSrc/src/main/resources/body/Source.java b/buildSrc/src/main/resources/body/model/Source.java similarity index 100% rename from buildSrc/src/main/resources/body/Source.java rename to buildSrc/src/main/resources/body/model/Source.java diff --git a/buildSrc/src/main/resources/body/StickerMessage.java b/buildSrc/src/main/resources/body/model/StickerMessage.java similarity index 100% rename from buildSrc/src/main/resources/body/StickerMessage.java rename to buildSrc/src/main/resources/body/model/StickerMessage.java diff --git a/buildSrc/src/main/resources/body/TemplateMessage.java b/buildSrc/src/main/resources/body/model/TemplateMessage.java similarity index 100% rename from buildSrc/src/main/resources/body/TemplateMessage.java rename to buildSrc/src/main/resources/body/model/TemplateMessage.java diff --git a/buildSrc/src/main/resources/body/TextMessage.java b/buildSrc/src/main/resources/body/model/TextMessage.java similarity index 100% rename from buildSrc/src/main/resources/body/TextMessage.java rename to buildSrc/src/main/resources/body/model/TextMessage.java diff --git a/buildSrc/src/main/resources/body/VideoMessage.java b/buildSrc/src/main/resources/body/model/VideoMessage.java similarity index 100% rename from buildSrc/src/main/resources/body/VideoMessage.java rename to buildSrc/src/main/resources/body/model/VideoMessage.java diff --git a/clients/line-liff-client/src/test/java/com/linecorp/bot/liff/client/LiffClientBackwardCompatibilityTest.java b/clients/line-liff-client/src/test/java/com/linecorp/bot/liff/client/LiffClientBackwardCompatibilityTest.java new file mode 100644 index 000000000..f71e516c5 --- /dev/null +++ b/clients/line-liff-client/src/test/java/com/linecorp/bot/liff/client/LiffClientBackwardCompatibilityTest.java @@ -0,0 +1,138 @@ +/* + * Copyright 2023 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.linecorp.bot.liff.client; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; +import static com.github.tomakehurst.wiremock.client.WireMock.delete; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.put; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathTemplate; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URI; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.slf4j.bridge.SLF4JBridgeHandler; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.ocadotechnology.gembus.test.Arranger; + +import com.linecorp.bot.liff.model.AddLiffAppRequest; +import com.linecorp.bot.liff.model.AddLiffAppResponse; +import com.linecorp.bot.liff.model.GetAllLiffAppsResponse; +import com.linecorp.bot.liff.model.UpdateLiffAppRequest; + +/** + * line-openapi introduce the breaking change in line-openapi#26. + * This test checks this SDK is backward compatible. + */ +@SuppressWarnings("deprecation") +@Timeout(5) +public class LiffClientBackwardCompatibilityTest { + static { + SLF4JBridgeHandler.removeHandlersForRootLogger(); + SLF4JBridgeHandler.install(); + } + + private WireMockServer wireMockServer; + private LiffClient api; + + @BeforeEach + public void setUp() { + wireMockServer = new WireMockServer(wireMockConfig().dynamicPort()); + wireMockServer.start(); + configureFor("localhost", wireMockServer.port()); + + api = LiffClient.builder("MY_OWN_TOKEN") + .apiEndPoint(URI.create(wireMockServer.baseUrl())) + .build(); + } + + @AfterEach + public void tearDown() { + wireMockServer.stop(); + } + + @Test + public void liffV1AppsGetTest() { + stubFor(get(urlPathTemplate("/liff/v1/apps")).willReturn( + aResponse() + .withStatus(200) + .withHeader("content-type", "application/json") + .withBody("{}"))); + + GetAllLiffAppsResponse response = api.liffV1AppsGet().join().body(); + + assertThat(response).isNotNull(); + // TODO: test validations + } + + @Test + public void liffV1AppsLiffIdDeleteTest() { + stubFor(delete(urlPathTemplate("/liff/v1/apps/{liffId}")).willReturn( + aResponse() + .withStatus(200) + .withHeader("content-type", "application/json") + .withBody("{}"))); + + String liffId = Arranger.some(String.class); + + api.liffV1AppsLiffIdDelete(liffId).join().body(); + + // TODO: test validations + } + + @Test + public void liffV1AppsLiffIdPutTest() { + stubFor(put(urlPathTemplate("/liff/v1/apps/{liffId}")).willReturn( + aResponse() + .withStatus(200) + .withHeader("content-type", "application/json") + .withBody("{}"))); + + String liffId = Arranger.some(String.class); + UpdateLiffAppRequest updateLiffAppRequest = Arranger.some(UpdateLiffAppRequest.class); + + api.liffV1AppsLiffIdPut(liffId, updateLiffAppRequest).join().body(); + + // TODO: test validations + } + + @Test + public void liffV1AppsPostTest() { + stubFor(post(urlPathTemplate("/liff/v1/apps")).willReturn( + aResponse() + .withStatus(200) + .withHeader("content-type", "application/json") + .withBody("{}"))); + + AddLiffAppRequest addLiffAppRequest = Arranger.some(AddLiffAppRequest.class); + + AddLiffAppResponse response = api.liffV1AppsPost(addLiffAppRequest).join().body(); + + assertThat(response).isNotNull(); + // TODO: test validations + } + +} diff --git a/templates/api.mustache b/templates/api.mustache index db521f617..e7e45cf21 100644 --- a/templates/api.mustache +++ b/templates/api.mustache @@ -86,5 +86,6 @@ public interface {{classname}} { return new ApiClientBuilder<>(URI.create("{{#lambda.endpoint}}{{classname}}{{/lambda.endpoint}}"), {{classname}}.class, new {{#lambda.exceptionbuilderclassname}}{{classname}}{{/lambda.exceptionbuilderclassname}}()); } {{/authenticated}} +{{#lambda.injectbody}}{{classname}}{{/lambda.injectbody}} } {{/operations}}