From b7cdd64c36d67d1ae372e7fd83fb1b620c2a62ff Mon Sep 17 00:00:00 2001 From: Thibault Pensec <39826516+symphony-thibault@users.noreply.github.com> Date: Mon, 5 Oct 2020 14:19:59 +0200 Subject: [PATCH 1/7] APP-3082 Architecture Overview (#258) * APP-3082 SVG Rendering in Markdown test * APP-3082 Updated diagram * APP-3082 Removed unused Jersey dependency * APP-3082 WIP * APP-3110 arch doc * APP-3110 removed unused javax.ws.rs.core.GenericType import from ApiException class * APP-3082 fixes * APP-3082 Link to Architecture Presentation from ./docs/index.md (cherry picked from commit 0fa637b21c4b92c48bcc99d003392dd8cc3f0cf1) --- CONTRIBUTING.md | 2 +- docs/index.md | 2 + docs/internal/bdk-architecture.md | 18 -------- docs/spring-boot/core-starter.md | 3 ++ docs/tech/architecture.md | 46 +++++++++++++++++++ docs/tech/architecture.svg | 1 + .../symphony-bdk-http-api/build.gradle | 2 +- .../symphony/bdk/http/api/ApiException.java | 6 +-- .../symphony/bdk/http/api/package-info.java | 9 ++++ 9 files changed, 66 insertions(+), 23 deletions(-) delete mode 100644 docs/internal/bdk-architecture.md create mode 100644 docs/tech/architecture.md create mode 100644 docs/tech/architecture.svg create mode 100644 symphony-bdk-http/symphony-bdk-http-api/src/main/java/com/symphony/bdk/http/api/package-info.java diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 852c92bee..984c69087 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ New feature requests on the legacy SDK will not be accepted. This repository contains both the legacy Java SDK under the [symphony-bdk-legacy module](symphony-bdk-legacy) and the BDK2.0 under all other root modules. Please check the [legacy module readme file](symphony-bdk-legacy/README.md) and the -[BDK2.0 architecture file](docs/internal/bdk-architecture.md) for more information. +[BDK architecture](docs/tech/architecture.md) documentation for more information. ## Testing diff --git a/docs/index.md b/docs/index.md index 833a75c9e..0f885a56a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -21,3 +21,5 @@ The reference documentation consists of the following sections: Getting Started guides are also available for Spring Boot: - [Core Starter](./spring-boot/core-starter.md) +### Technical Documentation +You can find an overview of the BDK Architecture [here](./tech/architecture.md). diff --git a/docs/internal/bdk-architecture.md b/docs/internal/bdk-architecture.md deleted file mode 100644 index c1716083a..000000000 --- a/docs/internal/bdk-architecture.md +++ /dev/null @@ -1,18 +0,0 @@ -# BDK2.0 - Project Architecture - -The BDK project is composed in a set of different modules. The approach consists in having one module per BDK -"layer". - -## The layers - -The BDK is divided in 3 different layers: -- `core` that contains the minimal set of classes to configure, authenticate and use -the main APIs -- `advanced` that contains additional features on top of the core module such as the -command API, the template API or even an NLP integration -- `framework` that provides connectors (or starters) for the main Java frameworks -such as [SpringBoot](https://spring.io/projects/spring-boot), -[MicroProfile](https://projects.eclipse.org/projects/technology.microprofile), -[Micronaut](https://micronaut.io/) or [Quarkus](https://quarkus.io/) - -### Core diff --git a/docs/spring-boot/core-starter.md b/docs/spring-boot/core-starter.md index 9fc9e148b..97b9351c8 100644 --- a/docs/spring-boot/core-starter.md +++ b/docs/spring-boot/core-starter.md @@ -252,3 +252,6 @@ public class GifFormActivity extends FormReplyActivity { } } ``` + +---- +[Home :house:](../index.md) diff --git a/docs/tech/architecture.md b/docs/tech/architecture.md new file mode 100644 index 000000000..885058944 --- /dev/null +++ b/docs/tech/architecture.md @@ -0,0 +1,46 @@ +# BDK Architecture Presentation +The Symphony BDK for Java is a multi-module library that uses [Gradle](https://gradle.org/) as build system. +This page will help to clearly understand how the library has been designed. This can be also useful for new contributors +aiming to provide additional features or implementations or existing APIs. + +## Architecture Overview +The following diagram aims to give an overview of the different layers and modules provided by the BDK library. +![Architecture Overview Diagram](architecture.svg) + +### symphony-bdk-core +The `symphony-bdk-core` is the main module that allows developers to write bots from a pure Java main application. It contains +all necessary BDK features such as: +- [configuration](../configuration.md) +- [authentication](../authentication.md) +- [datafeed](../datafeed.md) +- [services](../message.md) +- [activity API](../activity-api.md) + +#### Code Generation +The `symphony-bdk-core` module relies on the [openapi-generator-maven-plugin](https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator-maven-plugin/README.md) +to generate API clients and models from official Symphony's [Swagger specifications](https://github.com/symphonyoss/symphony-api-spec). +API's clients are located under package `com.symphony.bdk.gen.api` and models under `com.symphony.bdk.gen.api.model`. + +### symphony-bdk-http +The `symphony-bdk-http-api` module defines a generic interface for performing HTTP calls. Along with this interface, it +also provides a utility `com.symphony.bdk.http.api.HttpClient` class helping developers to perform calls to external systems. +> :warning: It is important to notice that interface `com.symphony.bdk.http.api.ApiClient` is used by generated code. +> Changing contract would break the build. See [Code Generation](#code-generation). + +At the moment, two different implementations have been created for the `com.symphony.bdk.http.api.ApiClient` interface: +- `com.symphony.bdk.http.jersey2.ApiClientJersey2` contained in module `symphony-bdk-http-jersey2` (default implementation for [Core](#symphony-bdk-core)) +- `com.symphony.bdk.http.webclient.ApiClientWebClient` contained in module `symphony-bdk-http-webclient` (default implementation for [Spring Boot](#symphony-bdk-spring)) + +### symphony-bdk-template +The `symphony-bdk-template-api` module defines a set of interfaces that allows developers to load and fill text files with +data. This API is especially useful for complex MessageML templating. + +At the moment, two different module implementations have been created: +- `symphony-bdk-template-freemarker` +- `symphony-bdk-template-handlebars` + +### symphony-bdk-spring +The Symphony BDK comes also with two _starter_ modules to ease integration with the Spring Boot framework: +- `symphony-bdk-core-spring-boot-starter` that is basically a wrapper around the [symphony-bdk-core](#symphony-bdk-core) module +- `symphony-bdk-app-spring-boot-starter` that is a foundation for [Extension Applications](https://developers.symphony.com/symphony-developer/docs/overview-of-extension-applications) +backend development diff --git a/docs/tech/architecture.svg b/docs/tech/architecture.svg new file mode 100644 index 000000000..655ec7418 --- /dev/null +++ b/docs/tech/architecture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/symphony-bdk-http/symphony-bdk-http-api/build.gradle b/symphony-bdk-http/symphony-bdk-http-api/build.gradle index 39c5d13c1..72cddda6a 100644 --- a/symphony-bdk-http/symphony-bdk-http-api/build.gradle +++ b/symphony-bdk-http/symphony-bdk-http-api/build.gradle @@ -1,10 +1,10 @@ description = 'Symphony Java BDK Core Http API' dependencies { + compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' implementation 'org.apiguardian:apiguardian-api' - implementation 'org.glassfish.jersey.core:jersey-client' } diff --git a/symphony-bdk-http/symphony-bdk-http-api/src/main/java/com/symphony/bdk/http/api/ApiException.java b/symphony-bdk-http/symphony-bdk-http-api/src/main/java/com/symphony/bdk/http/api/ApiException.java index 91323934c..a62e282da 100644 --- a/symphony-bdk-http/symphony-bdk-http-api/src/main/java/com/symphony/bdk/http/api/ApiException.java +++ b/symphony-bdk-http/symphony-bdk-http-api/src/main/java/com/symphony/bdk/http/api/ApiException.java @@ -1,5 +1,7 @@ package com.symphony.bdk.http.api; +import com.symphony.bdk.http.api.util.TypeReference; + import lombok.Getter; import org.apiguardian.api.API; @@ -7,10 +9,8 @@ import java.util.List; import java.util.Map; -import javax.ws.rs.core.GenericType; - /** - * Main exception raised when invoking {@link ApiClient#invokeAPI(String, String, List, Object, Map, Map, Map, String, String, String[], GenericType)}. + * Main exception raised when invoking {@link ApiClient#invokeAPI(String, String, List, Object, Map, Map, Map, String, String, String[], TypeReference)}. * * Initially generated by the OpenAPI Maven Generator */ diff --git a/symphony-bdk-http/symphony-bdk-http-api/src/main/java/com/symphony/bdk/http/api/package-info.java b/symphony-bdk-http/symphony-bdk-http-api/src/main/java/com/symphony/bdk/http/api/package-info.java new file mode 100644 index 000000000..6ea592e51 --- /dev/null +++ b/symphony-bdk-http/symphony-bdk-http-api/src/main/java/com/symphony/bdk/http/api/package-info.java @@ -0,0 +1,9 @@ +/** + * This module provides contract for performing HTTP calls. + * + *

+ * WARNING: The interface {@link com.symphony.bdk.http.api.ApiClient} is used by generated code. + * Changing the contract will break code generation. + *

+ */ +package com.symphony.bdk.http.api; From ee8c96cd76230c07910232eb0c513c1b8a293445 Mon Sep 17 00:00:00 2001 From: Thibault Pensec <39826516+symphony-thibault@users.noreply.github.com> Date: Mon, 5 Oct 2020 15:28:04 +0200 Subject: [PATCH 2/7] APP-3110 Handlebars template implementation (#260) * APP-3110 Handlebars template engine implementation * APP-3110 doc * APP-3110 Post merge, updated getting-started guide * APP-3110 http and template implementations as runtime dependencies * APP-3110 reverted ./docs/index.md * APP-3110 Updates implementation selection * APP-3110 :symphony-bdk-http-api and :symphony-bdk-template-api as :symphony-bdk-core transitive dependencies (cherry picked from commit edb1844b7eac3cc88827df3d8a4d19c7d0f58e82) --- docs/getting-started.md | 10 +- docs/message.md | 111 +++++++++++++----- settings.gradle | 2 +- symphony-bdk-core/build.gradle | 4 +- .../com/symphony/bdk/core/ServiceFactory.java | 21 +++- .../bdk/core/service/MessageService.java | 46 ++++---- .../bdk/core/service/MessageServiceTest.java | 16 +-- .../bdk-core-examples/build.gradle | 14 +-- .../bdk/examples/MessageExampleMain.java | 4 +- .../bdk/examples/TemplateExampleMain.java | 32 +++++ .../src/main/resources/complex-message.ftl | 3 + .../src/main/resources/customTemplate.ftl | 1 - .../bdk-template-examples/build.gradle | 14 --- .../examples/template/FreeMarkerExample.java | 37 ------ .../resources/templates/customTemplate.ftl | 1 - .../bdk/template/api/TemplateEngine.java | 23 ---- .../bdk/template/api/TemplateResolver.java | 40 +------ .../template/api/TemplateResolverTest.java | 63 ++-------- .../build.gradle | 1 - .../template/freemarker/FreeMarkerEngine.java | 87 ++------------ .../freemarker/UrlTemplateLoader.java | 40 ------- .../bdk/template/freemarker/simpleMML.ftl | 1 - .../freemarker/FreeMarkerTemplateTest.java | 42 +------ .../build.gradle | 17 +++ .../template/handlebars/HandlebarsEngine.java | 56 +++++++++ .../handlebars/HandlebarsTemplate.java | 34 ++++++ ...m.symphony.bdk.template.api.TemplateEngine | 1 + .../handlebars/HandlebarsEngineTest.java | 44 +++++++ .../src/test/resources/test.hbs | 3 + 29 files changed, 359 insertions(+), 409 deletions(-) create mode 100644 symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/TemplateExampleMain.java create mode 100644 symphony-bdk-examples/bdk-core-examples/src/main/resources/complex-message.ftl delete mode 100644 symphony-bdk-examples/bdk-core-examples/src/main/resources/customTemplate.ftl delete mode 100644 symphony-bdk-examples/bdk-template-examples/build.gradle delete mode 100644 symphony-bdk-examples/bdk-template-examples/src/main/java/com/symphony/bdk/examples/template/FreeMarkerExample.java delete mode 100644 symphony-bdk-examples/bdk-template-examples/src/main/resources/templates/customTemplate.ftl delete mode 100644 symphony-bdk-template/symphony-bdk-template-freemarker/src/main/java/com/symphony/bdk/template/freemarker/UrlTemplateLoader.java delete mode 100644 symphony-bdk-template/symphony-bdk-template-freemarker/src/main/resources/com/symphony/bdk/template/freemarker/simpleMML.ftl create mode 100644 symphony-bdk-template/symphony-bdk-template-handlebars/build.gradle create mode 100644 symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsEngine.java create mode 100644 symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsTemplate.java create mode 100644 symphony-bdk-template/symphony-bdk-template-handlebars/src/main/resources/META-INF/services/com.symphony.bdk.template.api.TemplateEngine create mode 100644 symphony-bdk-template/symphony-bdk-template-handlebars/src/test/java/com/symphony/bdk/template/handlebars/HandlebarsEngineTest.java create mode 100644 symphony-bdk-template/symphony-bdk-template-handlebars/src/test/resources/test.hbs diff --git a/docs/getting-started.md b/docs/getting-started.md index d84d6ee57..6577a3ce1 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -53,11 +53,13 @@ If you want to use [Maven](https://maven.apache.org/) as build system, you have com.symphony.platformsolutions - symphony-bdk-core-invoker-jersey2 + symphony-bdk-http-jersey2 + runtime com.symphony.platformsolutions - symphony-bdk-template-freemarker + symphony-bdk-template-freemarker + runtime @@ -88,8 +90,8 @@ dependencies { // define dependencies without versions implementation 'com.symphony.platformsolutions:symphony-bdk-core' - implementation 'com.symphony.platformsolutions:symphony-bdk-core-invoker-jersey2' - implementation 'com.symphony.platformsolutions:symphony-bdk-template-freemarker' + runtimeOnly 'com.symphony.platformsolutions:symphony-bdk-http-jersey2' // or symphony-bdk-http-webclient + runtimeOnly 'com.symphony.platformsolutions:symphony-bdk-template-freemarker' // or symphony-bdk-http-handlebars implementation 'ch.qos.logback:logback-classic' } diff --git a/docs/message.md b/docs/message.md index d089ed345..0b2494af6 100644 --- a/docs/message.md +++ b/docs/message.md @@ -17,54 +17,103 @@ More precisely: ## How to use The central component for the Message API is the `MessageService`. -It exposes all the services mentioned above and is accessible from the `SymphonyBdk` object by calling the `messages()` method. -For instance: - +It exposes all the services mentioned above and is accessible from the `SymphonyBdk` object by calling the `messages()` method: ```java -import com.symphony.bdk.core.MessageService; - public class Example { public static final String STREAM_ID = "gXFV8vN37dNqjojYS_y2wX___o2KxfmUdA"; public static void main(String[] args) throws Exception { // Create BDK entry point final SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath("/config.yaml")); - // Get the MessageService object - final MessageService messageService = bdk.message(); - - //send a regular message - final V4Message regularMessage = messageService.send(STREAM_ID, "Hello, World!"); - System.out.println("Message sent, id: " + regularMessage.getMessageId()); + // send a regular message + final V4Message regularMessage = bdk.message().send(STREAM_ID, "Hello, World!"); + log.info("Message sent, id: " + regularMessage.getMessageId()); } } ``` -A more detailed example with all exposed services can be found [here](../symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/MessageExampleMain.java). +## Using templates +The `MessageService` also allows you to send messages using templates. So far, the BDK supports two different template +engine implementations: +- [FreeMarker](https://freemarker.apache.org/) (through dependency `com.symphony.platformsolutions:symphony-bdk-template-freemarker`) +- [Handlebars](https://github.com/jknack/handlebars.java) (through dependency `com.symphony.platformsolutions:symphony-bdk-template-handlebars`) + +### How to send a message from a template +> In the code examples below, we will assume that FreeMarker as been selected as template engine implementation. +> See [how to select the template engine implementation](#select-your-template-engine-implementation). -## Send messages with templates -The Message service also allows you to send messages using templates. So far, we only support [FreeMarker templates](https://freemarker.apache.org/), -but we may add support for other template engines. -For instance, if you have the following template file: +First you need to define your message template file. Here `src/main/resources/templates/simple.ftl`: ``` -${message} +Hello, ${name}! ``` you will be able to use it when sending message: ```java -final SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath("/config.yaml")); -final V4Message regularMessage = bdk().message().send(streamId, "path/to/template.ftl", Collections.singletonMap("message", "Hello!")); +public class Example { + public static final String STREAM_ID = "gXFV8vN37dNqjojYS_y2wX___o2KxfmUdA"; + + public static void main(String[] args) { + final SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath("/config.yaml")); + + final V4Message regularMessage = bdk.message().send(streamId, "/templates/simple.ftl", Collections.singletonMap("name", "User")); + } +} +``` +The above will send the message `Hello, User!` as expected. + +> Please note that the `MessageService` will try fetch template from different locations ordered by: +> 1. classpath +> 2. file system + +It is also possible to get direct access to the `TemplateEngine` through the `MessageService`: +```java +public class Example { + + public static void main(String[] args) { + final SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath("/config.yaml")); + + // load template from classpath location + final Template template = bdk.messages().templates().newTemplateFromClasspath("/complex-message.ftl"); + + // process template with some vars and retrieve content + // any POJO can also be processed by the template + final String content = template.process(Collections.singletonMap("name", "Freemarker")); + + // display processed template content + log.info(content); + } +} +``` + +#### Select your template engine implementation +Developers are free to select the underlying template engine implementation. This can be done importing the right +dependency in your classpath. + +With [Maven](./getting-started.md#maven-based-project): +```xml + + + com.symphony.platformsolutions + symphony-bdk-template-freemarker + runtime + + + + com.symphony.platformsolutions + symphony-bdk-template-handlebars + runtime + + +``` +With [Gradle](./getting-started.md#gradle-based-project): +```groovy +dependencies { + runtimeOnly 'com.symphony.platformsolutions:symphony-bdk-template-freemarker' + // or + runtimeOnly 'com.symphony.platformsolutions:symphony-bdk-template-handlebars' +} ``` -The above will send the message `Hello!` as expected. -Please check the [FreeMarker documentation](https://freemarker.apache.org/docs/pgui_quickstart_createdatamodel.html) -to know more about the data model you can use in templates and about the corresponding object structure you need to pass as parameter. - -The template name passed as parameter can be the name of a built-in template -(only ["simpleMML"](../symphony-bdk-template/symphony-bdk-template-freemarker/src/main/resources/com/symphony/bdk/template/freemarker/simpleMML.ftl) -available so far), the path to a template file or a URL to a template file. -The templates will be looked for in this order: -* in built-in templates -* in the classpath -* in the file system -* lastly as a URL +> :warning: If multiple implementations found in classpath, an exception is throw in order to help you to define which one +> your project really needs to use. ---- [Home :house:](./index.md) diff --git a/settings.gradle b/settings.gradle index dcd5a0edc..d17f06f5d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,10 +9,10 @@ include(':symphony-bdk-http:symphony-bdk-http-webclient') include(':symphony-bdk-template:symphony-bdk-template-api') include(':symphony-bdk-template:symphony-bdk-template-freemarker') +include(':symphony-bdk-template:symphony-bdk-template-handlebars') include(':symphony-bdk-spring:symphony-bdk-core-spring-boot-starter') include(':symphony-bdk-spring:symphony-bdk-app-spring-boot-starter') include(':symphony-bdk-examples:bdk-core-examples') include(':symphony-bdk-examples:bdk-spring-boot-example') -include(':symphony-bdk-examples:bdk-template-examples') diff --git a/symphony-bdk-core/build.gradle b/symphony-bdk-core/build.gradle index 3933aad32..a1a3e6013 100644 --- a/symphony-bdk-core/build.gradle +++ b/symphony-bdk-core/build.gradle @@ -29,8 +29,8 @@ jacocoTestCoverageVerification { } dependencies { - implementation project(':symphony-bdk-http:symphony-bdk-http-api') - implementation project(':symphony-bdk-template:symphony-bdk-template-api') + api project(':symphony-bdk-http:symphony-bdk-http-api') + api project(':symphony-bdk-template:symphony-bdk-template-api') compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/ServiceFactory.java b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/ServiceFactory.java index 484fe5e40..3c802fd19 100644 --- a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/ServiceFactory.java +++ b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/ServiceFactory.java @@ -29,6 +29,8 @@ import com.symphony.bdk.http.api.ApiException; +import com.symphony.bdk.template.api.TemplateEngine; + import org.apiguardian.api.API; /** @@ -49,13 +51,15 @@ class ServiceFactory { private final ApiClient agentClient; private final AuthSession authSession; private final BdkConfig config; - private final RetryWithRecoveryBuilder retryBuilder; + private final TemplateEngine templateEngine; + private final RetryWithRecoveryBuilder retryBuilder; public ServiceFactory(ApiClientFactory apiClientFactory, AuthSession authSession, BdkConfig config) { this.podClient = apiClientFactory.getPodClient(); this.agentClient = apiClientFactory.getAgentClient(); this.authSession = authSession; this.config = config; + this.templateEngine = TemplateEngine.getDefaultImplementation(); this.retryBuilder = new RetryWithRecoveryBuilder<>() .retryConfig(config.getRetry()) .recoveryStrategy(ApiException::isUnauthorized, authSession::refresh); @@ -108,8 +112,17 @@ public DatafeedService getDatafeedService() { * @return an new {@link MessageService} instance. */ public MessageService getMessageService() { - return new MessageService(new MessagesApi(agentClient), new MessageApi(podClient), - new MessageSuppressionApi(podClient), new StreamsApi(podClient), new PodApi(podClient), - new AttachmentsApi(agentClient), new DefaultApi(podClient), authSession, retryBuilder); + return new MessageService( + new MessagesApi(this.agentClient), + new MessageApi(this.podClient), + new MessageSuppressionApi(this.podClient), + new StreamsApi(this.podClient), + new PodApi(this.podClient), + new AttachmentsApi(this.agentClient), + new DefaultApi(this.podClient), + this.authSession, + this.templateEngine, + this.retryBuilder + ); } } diff --git a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/service/MessageService.java b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/service/MessageService.java index 18bc8f89c..d9432b70f 100644 --- a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/service/MessageService.java +++ b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/service/MessageService.java @@ -55,26 +55,22 @@ public class MessageService { private final AttachmentsApi attachmentsApi; private final DefaultApi defaultApi; private final AuthSession authSession; + private final TemplateEngine templateEngine; private final TemplateResolver templateResolver; - private final RetryWithRecoveryBuilder retryBuilder; - - public MessageService(MessagesApi messagesApi, MessageApi messageApi, MessageSuppressionApi messageSuppressionApi, - StreamsApi streamsApi, PodApi podApi, AttachmentsApi attachmentsApi, DefaultApi defaultApi, - AuthSession authSession, RetryWithRecoveryBuilder retryBuilder) { - this(messagesApi, messageApi, messageSuppressionApi, streamsApi, podApi, attachmentsApi, defaultApi, authSession, - new TemplateResolver(), retryBuilder); - } - - public MessageService(MessagesApi messagesApi, MessageApi messageApi, MessageSuppressionApi messageSuppressionApi, - StreamsApi streamsApi, PodApi podApi, AttachmentsApi attachmentsApi, DefaultApi defaultApi, - AuthSession authSession, TemplateEngine templateEngine, RetryWithRecoveryBuilder retryBuilder) { - this(messagesApi, messageApi, messageSuppressionApi, streamsApi, podApi, attachmentsApi, defaultApi, authSession, - new TemplateResolver(templateEngine), retryBuilder); - } - - private MessageService(MessagesApi messagesApi, MessageApi messageApi, MessageSuppressionApi messageSuppressionApi, - StreamsApi streamsApi, PodApi podApi, AttachmentsApi attachmentsApi, DefaultApi defaultApi, - AuthSession authSession, TemplateResolver templateResolver, RetryWithRecoveryBuilder retryBuilder) { + private final RetryWithRecoveryBuilder retryBuilder; + + public MessageService( + final MessagesApi messagesApi, + final MessageApi messageApi, + final MessageSuppressionApi messageSuppressionApi, + final StreamsApi streamsApi, + final PodApi podApi, + final AttachmentsApi attachmentsApi, + final DefaultApi defaultApi, + final AuthSession authSession, + final TemplateEngine templateEngine, + final RetryWithRecoveryBuilder retryBuilder + ) { this.messagesApi = messagesApi; this.messageApi = messageApi; this.messageSuppressionApi = messageSuppressionApi; @@ -82,11 +78,21 @@ private MessageService(MessagesApi messagesApi, MessageApi messageApi, MessageSu this.podApi = podApi; this.attachmentsApi = attachmentsApi; this.authSession = authSession; - this.templateResolver = templateResolver; + this.templateEngine = templateEngine; + this.templateResolver = new TemplateResolver(templateEngine); this.defaultApi = defaultApi; this.retryBuilder = retryBuilder; } + /** + * Returns the {@link TemplateEngine} that can be used to load templates from classpath or file system. + * + * @return the template engine + */ + public TemplateEngine templates() { + return templateEngine; + } + /** * Get messages from an existing stream. Additionally returns any attachments associated with the message. * diff --git a/symphony-bdk-core/src/test/java/com/symphony/bdk/core/service/MessageServiceTest.java b/symphony-bdk-core/src/test/java/com/symphony/bdk/core/service/MessageServiceTest.java index 2c32de29e..ad0fe241f 100644 --- a/symphony-bdk-core/src/test/java/com/symphony/bdk/core/service/MessageServiceTest.java +++ b/symphony-bdk-core/src/test/java/com/symphony/bdk/core/service/MessageServiceTest.java @@ -14,11 +14,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.symphony.bdk.http.api.ApiClient; -import com.symphony.bdk.http.api.ApiException; -import com.symphony.bdk.http.api.ApiRuntimeException; import com.symphony.bdk.core.auth.AuthSession; -import com.symphony.bdk.core.config.model.BdkRetryConfig; import com.symphony.bdk.core.retry.RetryWithRecoveryBuilder; import com.symphony.bdk.core.service.stream.constant.AttachmentSort; import com.symphony.bdk.core.test.JsonHelper; @@ -40,6 +36,9 @@ import com.symphony.bdk.gen.api.model.V4ImportResponse; import com.symphony.bdk.gen.api.model.V4Message; import com.symphony.bdk.gen.api.model.V4Stream; +import com.symphony.bdk.http.api.ApiClient; +import com.symphony.bdk.http.api.ApiException; +import com.symphony.bdk.http.api.ApiRuntimeException; import com.symphony.bdk.template.api.TemplateEngine; import com.symphony.bdk.template.api.TemplateException; @@ -169,8 +168,7 @@ void testSendWithStreamObjectCallsSendWithStreamId() { @Test void testSendWithTemplateAndStreamObjectCallsSendWithCorrectStreamIdAndMessage() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.singleton(TEMPLATE_NAME)); - when(templateEngine.newBuiltInTemplate(eq(TEMPLATE_NAME))).thenReturn(parameters -> MESSAGE); + when(templateEngine.newTemplateFromClasspath(eq(TEMPLATE_NAME))).thenReturn(parameters -> MESSAGE); MessageService service = spy(messageService); doReturn(new V4Message()).when(service).send(anyString(), anyString()); @@ -183,8 +181,7 @@ void testSendWithTemplateAndStreamObjectCallsSendWithCorrectStreamIdAndMessage() @Test void testSendWithTemplateCallsSendWithCorrectMessage() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.singleton(TEMPLATE_NAME)); - when(templateEngine.newBuiltInTemplate(eq(TEMPLATE_NAME))).thenReturn(parameters -> MESSAGE); + when(templateEngine.newTemplateFromClasspath(eq(TEMPLATE_NAME))).thenReturn(parameters -> MESSAGE); MessageService service = spy(messageService); doReturn(new V4Message()).when(service).send(anyString(), anyString()); @@ -195,8 +192,7 @@ void testSendWithTemplateCallsSendWithCorrectMessage() throws TemplateException @Test void testSendWithTemplateThrowingTemplateException() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.singleton(TEMPLATE_NAME)); - when(templateEngine.newBuiltInTemplate(eq(TEMPLATE_NAME))).thenThrow(new TemplateException("error")); + when(templateEngine.newTemplateFromClasspath(eq(TEMPLATE_NAME))).thenThrow(new TemplateException("error")); assertThrows(TemplateException.class, () -> messageService.send(STREAM_ID, TEMPLATE_NAME, Collections.emptyMap())); } diff --git a/symphony-bdk-examples/bdk-core-examples/build.gradle b/symphony-bdk-examples/bdk-core-examples/build.gradle index 640bd9921..4c8a9dc9a 100644 --- a/symphony-bdk-examples/bdk-core-examples/build.gradle +++ b/symphony-bdk-examples/bdk-core-examples/build.gradle @@ -1,22 +1,20 @@ description = 'Symphony Java BDK Examples - Core' dependencies { + implementation project(':symphony-bdk-core') - implementation project(':symphony-bdk-template:symphony-bdk-template-api') - implementation project(':symphony-bdk-http:symphony-bdk-http-api') - implementation project(':symphony-bdk-http:symphony-bdk-http-webclient') - implementation project(':symphony-bdk-template:symphony-bdk-template-freemarker') - implementation 'org.slf4j:slf4j-api' + runtimeOnly project(':symphony-bdk-http:symphony-bdk-http-webclient') + runtimeOnly project(':symphony-bdk-template:symphony-bdk-template-freemarker') + runtimeOnly 'ch.qos.logback:logback-classic' + + implementation 'org.slf4j:slf4j-api' implementation 'commons-io:commons-io' implementation 'org.apache.commons:commons-lang3' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' - - testCompileOnly 'org.projectlombok:lombok' - testAnnotationProcessor 'org.projectlombok:lombok' } uploadArchives.enabled = false diff --git a/symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/MessageExampleMain.java b/symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/MessageExampleMain.java index d9c9884f5..6e115f262 100644 --- a/symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/MessageExampleMain.java +++ b/symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/MessageExampleMain.java @@ -38,11 +38,9 @@ public static void main(String[] args) throws Exception { final V4Message regularMessage = bdk.messages().send(STREAM_ID, MESSAGE); //use templates - final V4Message sentWithBuiltInTemplate = bdk.messages().send(STREAM_ID, "simpleMML", - Collections.singletonMap("message", "Hello from a built-in template!")); final V4Message sendWithCustomTemplate = bdk.messages() - .send(STREAM_ID, "customTemplate.ftl", Collections.emptyMap()); + .send(STREAM_ID, "/complex-message.ftl", Collections.singletonMap("name", "Freemarker")); //retrieve the details of existing messages final V4Message message = bdk.messages().getMessage(regularMessage.getMessageId()); diff --git a/symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/TemplateExampleMain.java b/symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/TemplateExampleMain.java new file mode 100644 index 000000000..6b72e8246 --- /dev/null +++ b/symphony-bdk-examples/bdk-core-examples/src/main/java/com/symphony/bdk/examples/TemplateExampleMain.java @@ -0,0 +1,32 @@ +package com.symphony.bdk.examples; + +import static com.symphony.bdk.core.config.BdkConfigLoader.loadFromSymphonyDir; + +import com.symphony.bdk.core.SymphonyBdk; +import com.symphony.bdk.template.api.Template; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Collections; + +/** + * Template API usage. + */ +@Slf4j +public class TemplateExampleMain { + + public static void main(String[] args) throws Exception { + + // load TemplateEngine implementation using SPI + final SymphonyBdk bdk = new SymphonyBdk(loadFromSymphonyDir("config.yaml")); + + // load template from classpath location + final Template template = bdk.messages().templates().newTemplateFromClasspath("/complex-message.ftl"); + + // process template with some vars and retrieve content + final String content = template.process(Collections.singletonMap("name", "Freemarker")); + + // display processed template content + log.info(content); + } +} diff --git a/symphony-bdk-examples/bdk-core-examples/src/main/resources/complex-message.ftl b/symphony-bdk-examples/bdk-core-examples/src/main/resources/complex-message.ftl new file mode 100644 index 000000000..b6cab14ea --- /dev/null +++ b/symphony-bdk-examples/bdk-core-examples/src/main/resources/complex-message.ftl @@ -0,0 +1,3 @@ + + This is a complex message, that supports ${name} templating + diff --git a/symphony-bdk-examples/bdk-core-examples/src/main/resources/customTemplate.ftl b/symphony-bdk-examples/bdk-core-examples/src/main/resources/customTemplate.ftl deleted file mode 100644 index 2256c68a9..000000000 --- a/symphony-bdk-examples/bdk-core-examples/src/main/resources/customTemplate.ftl +++ /dev/null @@ -1 +0,0 @@ -Hello from custom template ! diff --git a/symphony-bdk-examples/bdk-template-examples/build.gradle b/symphony-bdk-examples/bdk-template-examples/build.gradle deleted file mode 100644 index 887eef1ca..000000000 --- a/symphony-bdk-examples/bdk-template-examples/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -description = 'Symphony Java BDK Examples for the Template module' - -dependencies { - implementation project(':symphony-bdk-core') - implementation project(':symphony-bdk-template:symphony-bdk-template-api') - runtimeOnly project(':symphony-bdk-template:symphony-bdk-template-freemarker') - - implementation 'org.slf4j:slf4j-api' - - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' -} - -uploadArchives.enabled = false diff --git a/symphony-bdk-examples/bdk-template-examples/src/main/java/com/symphony/bdk/examples/template/FreeMarkerExample.java b/symphony-bdk-examples/bdk-template-examples/src/main/java/com/symphony/bdk/examples/template/FreeMarkerExample.java deleted file mode 100644 index 7b7460adc..000000000 --- a/symphony-bdk-examples/bdk-template-examples/src/main/java/com/symphony/bdk/examples/template/FreeMarkerExample.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.symphony.bdk.examples.template; - -import com.symphony.bdk.template.api.Template; -import com.symphony.bdk.template.api.TemplateEngine; -import com.symphony.bdk.template.api.TemplateException; - -import lombok.extern.slf4j.Slf4j; - -import java.util.HashMap; - -/** - * Sample class showing usage of FreeMarker templates. - */ -@Slf4j -public class FreeMarkerExample { - public static void main(String[] args) throws TemplateException { - log.info("String generated from built-in template: {}", getStringFromBuiltInTemplate()); - log.info("String generated from custom template: {}", getStringFromCustomTemplate()); - } - - private static String getStringFromBuiltInTemplate() throws TemplateException { - Template template = TemplateEngine.getDefaultImplementation().newBuiltInTemplate("simpleMML"); - final String message = template.process(new HashMap() {{ - put("message", "Hello World !"); - }}); - return message; - } - - private static String getStringFromCustomTemplate() throws TemplateException { - Template template = TemplateEngine.getDefaultImplementation() - .newTemplateFromClasspath("templates/customTemplate.ftl"); - final String message = template.process(new HashMap() {{ - put("message", "Hello World"); - }}); - return message; - } -} diff --git a/symphony-bdk-examples/bdk-template-examples/src/main/resources/templates/customTemplate.ftl b/symphony-bdk-examples/bdk-template-examples/src/main/resources/templates/customTemplate.ftl deleted file mode 100644 index 8dd7b7358..000000000 --- a/symphony-bdk-examples/bdk-template-examples/src/main/resources/templates/customTemplate.ftl +++ /dev/null @@ -1 +0,0 @@ -${message} from custom template ! diff --git a/symphony-bdk-template/symphony-bdk-template-api/src/main/java/com/symphony/bdk/template/api/TemplateEngine.java b/symphony-bdk-template/symphony-bdk-template-api/src/main/java/com/symphony/bdk/template/api/TemplateEngine.java index 1b69ff2b9..8d4c4ce55 100644 --- a/symphony-bdk-template/symphony-bdk-template-api/src/main/java/com/symphony/bdk/template/api/TemplateEngine.java +++ b/symphony-bdk-template/symphony-bdk-template-api/src/main/java/com/symphony/bdk/template/api/TemplateEngine.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.ServiceLoader; -import java.util.Set; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -16,20 +15,6 @@ @API(status = API.Status.STABLE) public interface TemplateEngine { - /** - * Returns the names of built-in templates which can be retrieved by calling {@link #newBuiltInTemplate(String)} - * @return the names of available built-in templates - */ - Set getBuiltInTemplates(); - - /** - * Creates a new {@link Template} from the built-in template name. - * @param template the name of one of the built-in templates returned by {@link #getBuiltInTemplates()} - * @return a new {@link Template} instantiated from the provided template name - * @throws TemplateException if template not found - */ - Template newBuiltInTemplate(String template) throws TemplateException; - /** * Create a {@link Template} instance from a file on the file system * @param templatePath path to a template file on the file system @@ -46,14 +31,6 @@ public interface TemplateEngine { */ Template newTemplateFromClasspath(String templatePath) throws TemplateException; - /** - * Creates a template from a URL to a template file - * @param url the url where to fetch the template file - * @return a new {@link Template} instantiated from the provided url, should be a valid {@link java.net.URL} string. - * @throws TemplateException when template cannot be loaded, e.g. url not accessible - */ - Template newTemplateFromUrl(String url) throws TemplateException; - static TemplateEngine getDefaultImplementation() { final ServiceLoader engineServiceLoader = ServiceLoader.load(TemplateEngine.class); diff --git a/symphony-bdk-template/symphony-bdk-template-api/src/main/java/com/symphony/bdk/template/api/TemplateResolver.java b/symphony-bdk-template/symphony-bdk-template-api/src/main/java/com/symphony/bdk/template/api/TemplateResolver.java index 867ff27cd..413fa07be 100644 --- a/symphony-bdk-template/symphony-bdk-template-api/src/main/java/com/symphony/bdk/template/api/TemplateResolver.java +++ b/symphony-bdk-template/symphony-bdk-template-api/src/main/java/com/symphony/bdk/template/api/TemplateResolver.java @@ -30,49 +30,24 @@ public TemplateResolver(TemplateEngine templateEngine) { } /** - * Looks for a template in this order : in the built-in templates, in the classpath, in the filesystem and from a URL. - * @param template can be the name of a built-in template, a path to a template file in the classpath or in the file system - * or a URL to a template file + * Looks for a template in this order : in the classpath, in the filesystem. + * @param template can be the name of a file in the classpath or in the file system * @return a new {@link Template} instance corresponding to the template parameter * @throws TemplateException if no template has been found. */ public Template resolve(String template) throws TemplateException { - Template resolved = null; - if (isBuiltInTemplate(template)) { - resolved = tryFetchBuiltInTemplate(template); - } - - if (resolved == null) { - resolved = tryFetchTemplateFromClasspath(template); - } + Template resolved = tryFetchTemplateFromClasspath(template); if (resolved == null) { resolved = tryFetchTemplateFromFileSystem(template); } - if (resolved == null) { - resolved = tryFetchTemplateFromUrl(template); - } - if (resolved == null) { throw new TemplateException("Template " + template + " not found"); } return resolved; } - private boolean isBuiltInTemplate(String template) { - return this.templateEngine.getBuiltInTemplates().contains(template); - } - - private Template tryFetchBuiltInTemplate(String template) { - try { - return this.templateEngine.newBuiltInTemplate(template); - } catch (TemplateException e) { - log.debug("{} is not a built-in template", template); - } - return null; - } - private Template tryFetchTemplateFromClasspath(String template) { try { return this.templateEngine.newTemplateFromClasspath(template); @@ -90,13 +65,4 @@ private Template tryFetchTemplateFromFileSystem(String template) { } return null; } - - private Template tryFetchTemplateFromUrl(String template) { - try { - return this.templateEngine.newTemplateFromUrl(template); - } catch (TemplateException e) { - log.debug("{} is not found from URL", template); - } - return null; - } } diff --git a/symphony-bdk-template/symphony-bdk-template-api/src/test/java/com/symphony/bdk/template/api/TemplateResolverTest.java b/symphony-bdk-template/symphony-bdk-template-api/src/test/java/com/symphony/bdk/template/api/TemplateResolverTest.java index 5bd7c7b20..b1cc6a241 100644 --- a/symphony-bdk-template/symphony-bdk-template-api/src/test/java/com/symphony/bdk/template/api/TemplateResolverTest.java +++ b/symphony-bdk-template/symphony-bdk-template-api/src/test/java/com/symphony/bdk/template/api/TemplateResolverTest.java @@ -1,5 +1,7 @@ package com.symphony.bdk.template.api; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; @@ -7,15 +9,12 @@ import static org.mockito.Mockito.when; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import java.util.Collections; - -import static org.junit.jupiter.api.Assertions.*; - /** * Test class for {@link TemplateResolver} */ @@ -36,80 +35,34 @@ void setUp() { } @Test - void testBuiltInTemplate() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.singleton(TEMPLATE_NAME)); - when(templateEngine.newBuiltInTemplate(anyString())).thenReturn(TEMPLATE); - - assertEquals(TEMPLATE, templateResolver.resolve(TEMPLATE_NAME)); - verify(templateEngine).getBuiltInTemplates(); - verify(templateEngine).newBuiltInTemplate(eq(TEMPLATE_NAME)); - verifyNoMoreInteractions(templateEngine); - } - - @Test - void testNotInBuiltInTemplatesButInClasspath() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.emptySet()); - when(templateEngine.newTemplateFromClasspath(anyString())).thenReturn(TEMPLATE); - - assertEquals(TEMPLATE, templateResolver.resolve(TEMPLATE_NAME)); - verify(templateEngine).getBuiltInTemplates(); - verify(templateEngine).newTemplateFromClasspath(eq(TEMPLATE_NAME)); - verifyNoMoreInteractions(templateEngine); - } - - @Test - void testNewBuiltInTemplatesThrowsTemplateExceptionButTemplateInClasspath() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.singleton(TEMPLATE_NAME)); - when(templateEngine.newBuiltInTemplate(anyString())).thenThrow(new TemplateException("")); - when(templateEngine.newTemplateFromClasspath(anyString())).thenReturn(TEMPLATE); - - assertEquals(TEMPLATE, templateResolver.resolve(TEMPLATE_NAME)); - verify(templateEngine).getBuiltInTemplates(); - verify(templateEngine).newBuiltInTemplate(eq(TEMPLATE_NAME)); - verify(templateEngine).newTemplateFromClasspath(eq(TEMPLATE_NAME)); - verifyNoMoreInteractions(templateEngine); - } - - @Test - void testNotBuiltInNotInClasspathButInFileSystem() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.emptySet()); + @DisplayName("Template is in file system but absent from classpath") + void no_cp_in_fs() throws TemplateException { when(templateEngine.newTemplateFromClasspath(anyString())).thenThrow(new TemplateException("")); when(templateEngine.newTemplateFromFile(anyString())).thenReturn(TEMPLATE); assertEquals(TEMPLATE, templateResolver.resolve(TEMPLATE_NAME)); - verify(templateEngine).getBuiltInTemplates(); verify(templateEngine).newTemplateFromClasspath(eq(TEMPLATE_NAME)); verify(templateEngine).newTemplateFromFile(eq(TEMPLATE_NAME)); verifyNoMoreInteractions(templateEngine); } @Test - void testNotBuiltInNotInClasspathNotInFileSystemButFromUrl() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.emptySet()); - when(templateEngine.newTemplateFromClasspath(anyString())).thenThrow(new TemplateException("")); - when(templateEngine.newTemplateFromFile(anyString())).thenThrow(new TemplateException("")); - when(templateEngine.newTemplateFromUrl(anyString())).thenReturn(TEMPLATE); + @DisplayName("Template is in classpath but absent from file system") + void no_fs_in_cp() throws TemplateException { + when(templateEngine.newTemplateFromClasspath(anyString())).thenReturn(TEMPLATE); assertEquals(TEMPLATE, templateResolver.resolve(TEMPLATE_NAME)); - verify(templateEngine).getBuiltInTemplates(); verify(templateEngine).newTemplateFromClasspath(eq(TEMPLATE_NAME)); - verify(templateEngine).newTemplateFromFile(eq(TEMPLATE_NAME)); - verify(templateEngine).newTemplateFromUrl(eq(TEMPLATE_NAME)); verifyNoMoreInteractions(templateEngine); } @Test void testTemplateNotFound() throws TemplateException { - when(templateEngine.getBuiltInTemplates()).thenReturn(Collections.emptySet()); when(templateEngine.newTemplateFromClasspath(anyString())).thenThrow(new TemplateException("")); when(templateEngine.newTemplateFromFile(anyString())).thenThrow(new TemplateException("")); - when(templateEngine.newTemplateFromUrl(anyString())).thenThrow(new TemplateException("")); - assertThrows(TemplateException.class, () -> templateResolver.resolve(TEMPLATE_NAME)); - verify(templateEngine).getBuiltInTemplates(); verify(templateEngine).newTemplateFromClasspath(eq(TEMPLATE_NAME)); verify(templateEngine).newTemplateFromFile(eq(TEMPLATE_NAME)); - verify(templateEngine).newTemplateFromUrl(eq(TEMPLATE_NAME)); verifyNoMoreInteractions(templateEngine); } } diff --git a/symphony-bdk-template/symphony-bdk-template-freemarker/build.gradle b/symphony-bdk-template/symphony-bdk-template-freemarker/build.gradle index 28c8009d1..58a973bff 100644 --- a/symphony-bdk-template/symphony-bdk-template-freemarker/build.gradle +++ b/symphony-bdk-template/symphony-bdk-template-freemarker/build.gradle @@ -6,7 +6,6 @@ dependencies { implementation 'org.apiguardian:apiguardian-api' implementation 'org.freemarker:freemarker' implementation 'commons-io:commons-io' - implementation 'org.reflections:reflections' testImplementation 'org.junit.jupiter:junit-jupiter' } diff --git a/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/java/com/symphony/bdk/template/freemarker/FreeMarkerEngine.java b/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/java/com/symphony/bdk/template/freemarker/FreeMarkerEngine.java index 35c1dae1f..10624d948 100644 --- a/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/java/com/symphony/bdk/template/freemarker/FreeMarkerEngine.java +++ b/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/java/com/symphony/bdk/template/freemarker/FreeMarkerEngine.java @@ -8,53 +8,31 @@ import freemarker.template.TemplateExceptionHandler; import org.apache.commons.io.FilenameUtils; import org.apiguardian.api.API; -import org.reflections.Reflections; -import org.reflections.scanners.ResourcesScanner; import java.io.File; import java.io.IOException; -import java.util.Map; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; /** * FreeMarker specific implementation of {@link TemplateEngine}. Instantiates {@link FreeMarkerTemplate} objects. + * + *

+ * This class is thread-safe. + *

*/ @API(status = API.Status.INTERNAL) public class FreeMarkerEngine implements TemplateEngine { - public static final String FREEMARKER_EXTENSION = ".ftl"; - - private static Configuration configuration = createConfiguration(); - private static Map builtInTemplates = getBuiltInTemplateMap(); - - /** - * {@inheritDoc} - */ - @Override - public Set getBuiltInTemplates() { - return builtInTemplates.keySet(); - } - - /** - * {@inheritDoc} - */ - @Override - public Template newBuiltInTemplate(String template) throws TemplateException { - if (!builtInTemplates.containsKey(template)) { - throw new TemplateException("Template " + template + " not found"); - } - return newTemplateFromClasspath(builtInTemplates.get(template)); - } - /** * {@inheritDoc} */ @Override public Template newTemplateFromFile(String templatePath) throws TemplateException { try { - return getTemplateFromFile(templatePath); + final String directory = FilenameUtils.getFullPathNoEndSeparator(templatePath); + final String file = FilenameUtils.getName(templatePath); + final Configuration configuration = createConfiguration(); // for thread-safety, we need to re-create configuration + configuration.setDirectoryForTemplateLoading(new File(directory)); + return new FreeMarkerTemplate(configuration.getTemplate(file)); } catch (IOException e) { throw new TemplateException("Unable to open template file", e); } @@ -66,44 +44,16 @@ public Template newTemplateFromFile(String templatePath) throws TemplateExceptio @Override public Template newTemplateFromClasspath(String templatePath) throws TemplateException { try { - configuration.setClassForTemplateLoading(getClass(), "/"); + final Configuration configuration = createConfiguration(); // for thread-safety, we need to re-create configuration + configuration.setClassForTemplateLoading(this.getClass(), "/"); return new FreeMarkerTemplate(configuration.getTemplate(templatePath)); } catch (IOException e) { throw new TemplateException("Unable to load template from classpath", e); } } - /** - * {@inheritDoc} - */ - @Override - public Template newTemplateFromUrl(String url) throws TemplateException { - try { - return getTemplateFromUrl(url); - } catch (IOException e) { - throw new TemplateException("Unable to load template from url", e); - } - } - - - private FreeMarkerTemplate getTemplateFromFile(String templatePath) throws IOException { - String directory = FilenameUtils.getFullPathNoEndSeparator(templatePath); - String file = FilenameUtils.getName(templatePath); - - configuration.setDirectoryForTemplateLoading(new File(directory)); - return new FreeMarkerTemplate(configuration.getTemplate(file)); - } - - private Template getTemplateFromUrl(String url) throws IOException { - String baseUrl = FilenameUtils.getFullPathNoEndSeparator(url); - String file = FilenameUtils.getName(url); - - configuration.setTemplateLoader(new UrlTemplateLoader(baseUrl)); - return new FreeMarkerTemplate(configuration.getTemplate(file)); - } - private static Configuration createConfiguration() { - Configuration cfg = new Configuration(Configuration.VERSION_2_3_29); + final Configuration cfg = new Configuration(Configuration.VERSION_2_3_29); cfg.setDefaultEncoding("UTF-8"); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); cfg.setLogTemplateExceptions(false); @@ -111,17 +61,4 @@ private static Configuration createConfiguration() { cfg.setFallbackOnNullLoopVariable(false); return cfg; } - - private static Map getBuiltInTemplateMap() { - Reflections reflections = new Reflections(FreeMarkerEngine.class.getPackage().getName(), new ResourcesScanner()); - - final Set resources = reflections.getResources(n -> n.endsWith(FREEMARKER_EXTENSION)); - return resources.stream().collect(Collectors.toMap(r -> extractTemplateName(r), Function.identity())); - } - - private static String extractTemplateName(String templatePath) { - // remove the path part until the last '/' and the FREEMARKER_EXTENSION - return templatePath.substring(templatePath.lastIndexOf('/') + 1, - templatePath.length() - FREEMARKER_EXTENSION.length()); - } } diff --git a/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/java/com/symphony/bdk/template/freemarker/UrlTemplateLoader.java b/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/java/com/symphony/bdk/template/freemarker/UrlTemplateLoader.java deleted file mode 100644 index 9db8bb2bb..000000000 --- a/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/java/com/symphony/bdk/template/freemarker/UrlTemplateLoader.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.symphony.bdk.template.freemarker; - -import freemarker.cache.URLTemplateLoader; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; - -/** - * Internal class used when instantiating a {@link FreeMarkerTemplate} with {@link FreeMarkerEngine#newTemplateFromUrl(String)} - */ -class UrlTemplateLoader extends URLTemplateLoader { - - private String baseUrl; - - public UrlTemplateLoader(String baseUrl) { - this.baseUrl = baseUrl; - } - - @Override - protected URL getURL(String s) { - try { - URL url = new URL(baseUrl + "/" + s); - if (resourceCanBeAccessed(url)) { - return url; - } - } catch (MalformedURLException e) { - } - return null; - } - - private boolean resourceCanBeAccessed(URL url) { - try (InputStream ignored = url.openStream()) { - } catch (IOException e) { - return false; - } - return true; - } -} diff --git a/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/resources/com/symphony/bdk/template/freemarker/simpleMML.ftl b/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/resources/com/symphony/bdk/template/freemarker/simpleMML.ftl deleted file mode 100644 index 8dd569228..000000000 --- a/symphony-bdk-template/symphony-bdk-template-freemarker/src/main/resources/com/symphony/bdk/template/freemarker/simpleMML.ftl +++ /dev/null @@ -1 +0,0 @@ -${message} diff --git a/symphony-bdk-template/symphony-bdk-template-freemarker/src/test/java/com/symphony/bdk/template/freemarker/FreeMarkerTemplateTest.java b/symphony-bdk-template/symphony-bdk-template-freemarker/src/test/java/com/symphony/bdk/template/freemarker/FreeMarkerTemplateTest.java index b58e3e152..b674fe540 100644 --- a/symphony-bdk-template/symphony-bdk-template-freemarker/src/test/java/com/symphony/bdk/template/freemarker/FreeMarkerTemplateTest.java +++ b/symphony-bdk-template/symphony-bdk-template-freemarker/src/test/java/com/symphony/bdk/template/freemarker/FreeMarkerTemplateTest.java @@ -9,8 +9,6 @@ import org.junit.jupiter.api.Test; -import java.net.URL; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -63,7 +61,7 @@ public void testFromClasspathRelativePathNoSlash() throws TemplateException { } @Test - public void testFromClasspatWithInclude() throws TemplateException { + public void testFromClasspathWithInclude() throws TemplateException { Template freeMarkerTemplate = new FreeMarkerEngine().newTemplateFromClasspath("/subFolder/testWithInclude.ftl"); assertTemplateProducesOutput(freeMarkerTemplate, new HashMap<>(), "Template with include\nHello from included file!\n"); @@ -74,28 +72,6 @@ public void testWithNotFoundResource() { assertThrows(TemplateException.class, () -> new FreeMarkerEngine().newTemplateFromClasspath("./not/found.ftl")); } - @Test - public void testFromUrl() throws TemplateException { - URL baseUrl = getClass().getResource("/subFolder/test.ftl"); - - Template freeMarkerTemplate = new FreeMarkerEngine().newTemplateFromUrl(baseUrl.toString()); - assertTemplateProducesOutput(freeMarkerTemplate); - } - - @Test - public void testFromUrlWithInclude() throws TemplateException { - URL baseUrl = getClass().getResource("/subFolder/testWithInclude.ftl"); - - Template freeMarkerTemplate = new FreeMarkerEngine().newTemplateFromUrl(baseUrl.toString()); - assertTemplateProducesOutput(freeMarkerTemplate, new HashMap<>(), - "Template with include\nHello from included file!\n"); - } - - @Test - public void testFromUrlWithNotFoundResource() { - assertThrows(TemplateException.class, () -> new FreeMarkerEngine().newTemplateFromUrl("file:/not/found/file.ftl")); - } - private void assertTemplateProducesOutput(Template freeMarkerTemplate) throws TemplateException { Map parameters = new HashMap<>(); parameters.put("message", "Hello World!"); @@ -103,22 +79,6 @@ private void assertTemplateProducesOutput(Template freeMarkerTemplate) throws Te assertTemplateProducesOutput(freeMarkerTemplate, parameters, "Hello World!\n"); } - @Test - public void testgetBuiltInTemplates() { - assertEquals(Collections.singleton("simpleMML"), new FreeMarkerEngine().getBuiltInTemplates()); - } - - @Test - public void testFromBuiltInTemplate() throws TemplateException { - final Template simpleMML = new FreeMarkerEngine().newBuiltInTemplate("simpleMML"); - assertTemplateProducesOutput(simpleMML); - } - - @Test - public void testFromNonExistingBuiltInTemplate() { - assertThrows(TemplateException.class, () -> new FreeMarkerEngine().newBuiltInTemplate("notFound")); - } - private void assertTemplateProducesOutput(Template freeMarkerTemplate, Object parameters, String expectedOutput) throws TemplateException { assertEquals(FreeMarkerTemplate.class, freeMarkerTemplate.getClass()); diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/build.gradle b/symphony-bdk-template/symphony-bdk-template-handlebars/build.gradle new file mode 100644 index 000000000..0b2b230d1 --- /dev/null +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/build.gradle @@ -0,0 +1,17 @@ +plugins { + id 'java-library' +} + +description = 'Symphony Java BDK Template Handlebars Module' + +dependencies { + api project(':symphony-bdk-template:symphony-bdk-template-api') + + implementation 'org.apiguardian:apiguardian-api' + + implementation 'com.github.jknack:handlebars:4.2.0' + implementation 'commons-io:commons-io' + + testImplementation 'org.junit.jupiter:junit-jupiter' + testImplementation 'ch.qos.logback:logback-classic' +} diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsEngine.java b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsEngine.java new file mode 100644 index 000000000..3d29f99bb --- /dev/null +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsEngine.java @@ -0,0 +1,56 @@ +package com.symphony.bdk.template.handlebars; + +import com.symphony.bdk.template.api.Template; +import com.symphony.bdk.template.api.TemplateEngine; +import com.symphony.bdk.template.api.TemplateException; + +import com.github.jknack.handlebars.Handlebars; +import com.github.jknack.handlebars.io.FileTemplateLoader; +import com.github.jknack.handlebars.io.TemplateLoader; +import org.apache.commons.io.FilenameUtils; +import org.apiguardian.api.API; + +import java.io.IOException; + +/** + * {@link Handlebars} implementation of the {@link TemplateEngine} interface. + * + *

+ * This class is thread-safe. + *

+ */ +@API(status = API.Status.INTERNAL) +public class HandlebarsEngine implements TemplateEngine { + + /** Handlebars for classpath loading. Ok for thread-safety. */ + private static final Handlebars HANDLEBARS = new Handlebars(); + + /** + * {@inheritDoc} + */ + @Override + public Template newTemplateFromFile(String templatePath) throws TemplateException { + final String basedir = FilenameUtils.getFullPathNoEndSeparator(templatePath); + final String file = FilenameUtils.getName(templatePath); + // for thread-safety, we need to create a specific Handlebars object + final TemplateLoader templateLoader = new FileTemplateLoader(basedir); + final Handlebars handlebars = new Handlebars(templateLoader); + try { + return new HandlebarsTemplate(handlebars.compile(file)); + } catch (IOException e) { + throw new TemplateException("Unable to compile Handlebars template from file location: " + templatePath, e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Template newTemplateFromClasspath(String templatePath) throws TemplateException { + try { + return new HandlebarsTemplate(HANDLEBARS.compile(templatePath)); + } catch (IOException e) { + throw new TemplateException("Unable to compile Handlebars template from classpath location: " + templatePath, e); + } + } +} diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsTemplate.java b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsTemplate.java new file mode 100644 index 000000000..b498d10a2 --- /dev/null +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsTemplate.java @@ -0,0 +1,34 @@ +package com.symphony.bdk.template.handlebars; + +import com.symphony.bdk.template.api.Template; +import com.symphony.bdk.template.api.TemplateException; + +import com.github.jknack.handlebars.Handlebars; +import org.apiguardian.api.API; + +import java.io.IOException; + +/** + * {@link Handlebars} implementation of the {@link Template} interface. + */ +@API(status = API.Status.INTERNAL) +public class HandlebarsTemplate implements Template { + + private final com.github.jknack.handlebars.Template template; + + public HandlebarsTemplate(com.github.jknack.handlebars.Template template) { + this.template = template; + } + + /** + * {@inheritDoc} + */ + @Override + public String process(Object parameters) throws TemplateException { + try { + return this.template.apply(parameters); + } catch (IOException e) { + throw new TemplateException("Could not generate string from template", e); + } + } +} diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/resources/META-INF/services/com.symphony.bdk.template.api.TemplateEngine b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/resources/META-INF/services/com.symphony.bdk.template.api.TemplateEngine new file mode 100644 index 000000000..ec4ee8cc3 --- /dev/null +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/resources/META-INF/services/com.symphony.bdk.template.api.TemplateEngine @@ -0,0 +1 @@ +com.symphony.bdk.template.handlebars.HandlebarsEngine diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/java/com/symphony/bdk/template/handlebars/HandlebarsEngineTest.java b/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/java/com/symphony/bdk/template/handlebars/HandlebarsEngineTest.java new file mode 100644 index 000000000..b33a1e996 --- /dev/null +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/java/com/symphony/bdk/template/handlebars/HandlebarsEngineTest.java @@ -0,0 +1,44 @@ +package com.symphony.bdk.template.handlebars; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.symphony.bdk.template.api.Template; +import com.symphony.bdk.template.api.TemplateException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; + +class HandlebarsEngineTest { + + private static final String EXPECTED_TEST_HBS = "\nhello\n\n"; + + private HandlebarsEngine engine; + + @BeforeEach + void init() { + this.engine = new HandlebarsEngine(); + } + + @Test + void should_load_template_from_classpath() throws TemplateException { + final Template template = this.engine.newTemplateFromClasspath("/test"); + final String content = template.process(Collections.singletonMap("message", "hello")); + assertEquals(EXPECTED_TEST_HBS, content); + } + + @Test + void should_load_template_from_file(@TempDir Path tempDir) throws Exception { + + final Path templatePath = tempDir.resolve("test.hbs"); + Files.copy(this.getClass().getResourceAsStream("/test.hbs"), templatePath); + + final Template template = this.engine.newTemplateFromFile(tempDir.resolve("test").toAbsolutePath().toString()); + final String content = template.process(Collections.singletonMap("message", "hello")); + assertEquals(EXPECTED_TEST_HBS, content); + } +} diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/resources/test.hbs b/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/resources/test.hbs new file mode 100644 index 000000000..b3d3e78b4 --- /dev/null +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/resources/test.hbs @@ -0,0 +1,3 @@ + +{{message}} + From 9ced27c41ad97357e717c927461646e9d58024ac Mon Sep 17 00:00:00 2001 From: symphony-hong <65538951+symphony-hong@users.noreply.github.com> Date: Mon, 5 Oct 2020 12:55:08 +0200 Subject: [PATCH 3/7] APP-3078: Add java-library plugin to http and template submodules (#261) * Add internal dependencies version to bom module * Update missing dependencies * Adding plugin to http and template submodule (cherry picked from commit f5c7df011aa6be50d679e404403c23aa3dd1b849) --- symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle | 6 +++++- symphony-bdk-http/symphony-bdk-http-webclient/build.gradle | 6 +++++- .../symphony-bdk-template-freemarker/build.gradle | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle b/symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle index 5b69b64e9..570458b33 100644 --- a/symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle +++ b/symphony-bdk-http/symphony-bdk-http-jersey2/build.gradle @@ -1,7 +1,11 @@ +plugins { + id 'java-library' +} + description = 'Symphony Java BDK Core Http Jersey2' dependencies { - implementation project(':symphony-bdk-http:symphony-bdk-http-api') + api project(':symphony-bdk-http:symphony-bdk-http-api') implementation 'org.apiguardian:apiguardian-api' implementation 'io.jsonwebtoken:jjwt' diff --git a/symphony-bdk-http/symphony-bdk-http-webclient/build.gradle b/symphony-bdk-http/symphony-bdk-http-webclient/build.gradle index fb4c0cf01..52079b5a6 100644 --- a/symphony-bdk-http/symphony-bdk-http-webclient/build.gradle +++ b/symphony-bdk-http/symphony-bdk-http-webclient/build.gradle @@ -1,3 +1,7 @@ +plugins { + id 'java-library' +} + description = 'Symphony Java BDK Core Http Spring WebClient' jacocoTestCoverageVerification { @@ -14,7 +18,7 @@ jacocoTestCoverageVerification { } dependencies { - implementation project(':symphony-bdk-http:symphony-bdk-http-api') + api project(':symphony-bdk-http:symphony-bdk-http-api') implementation 'org.apiguardian:apiguardian-api' implementation 'org.springframework.boot:spring-boot-starter-webflux' diff --git a/symphony-bdk-template/symphony-bdk-template-freemarker/build.gradle b/symphony-bdk-template/symphony-bdk-template-freemarker/build.gradle index 58a973bff..1785bd890 100644 --- a/symphony-bdk-template/symphony-bdk-template-freemarker/build.gradle +++ b/symphony-bdk-template/symphony-bdk-template-freemarker/build.gradle @@ -1,7 +1,11 @@ +plugins { + id 'java-library' +} + description = 'Symphony Java BDK Template Freemarker Module' dependencies { - implementation project(':symphony-bdk-template:symphony-bdk-template-api') + api project(':symphony-bdk-template:symphony-bdk-template-api') implementation 'org.apiguardian:apiguardian-api' implementation 'org.freemarker:freemarker' From cf72cfff4af3abda1a0ed31b5b5d26d77c88d4cf Mon Sep 17 00:00:00 2001 From: symphony-thibault Date: Mon, 5 Oct 2020 17:42:58 +0200 Subject: [PATCH 4/7] Bump release version to 1.3.1.BETA --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d45eda7c7..7e38b79c2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -ext.projectVersion = project.properties['projectVersion'] ?: '1.3.0.BETA' +ext.projectVersion = project.properties['projectVersion'] ?: '1.3.1.BETA' ext.isReleaseVersion = !ext.projectVersion.endsWith('SNAPSHOT') ext.symphonyRepoUrl = project.properties['symphonyRepoUrl'] ?: 'Symphony repository URL' From a40b8dcc47fbc6e4b01bd5b82952a8d17839476f Mon Sep 17 00:00:00 2001 From: symphony-thibault Date: Mon, 5 Oct 2020 17:44:07 +0200 Subject: [PATCH 5/7] Updated current version in getting-started.md --- docs/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 6577a3ce1..639ef7e63 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -38,7 +38,7 @@ If you want to use [Maven](https://maven.apache.org/) as build system, you have com.symphony.platformsolutions symphony-bdk-bom - 1.2.1.BETA + 1.3.1.BETA pom import @@ -86,7 +86,7 @@ repositories { dependencies { // import a BOM - implementation platform('com.symphony.platformsolutions:symphony-bdk-bom:1.2.1.BETA') + implementation platform('com.symphony.platformsolutions:symphony-bdk-bom:1.3.1.BETA') // define dependencies without versions implementation 'com.symphony.platformsolutions:symphony-bdk-core' From 1ffb9f7c0cd110646231889f577903e33ec81a4e Mon Sep 17 00:00:00 2001 From: symphony-thibault Date: Mon, 5 Oct 2020 17:45:00 +0200 Subject: [PATCH 6/7] APP-3110 Handlebars template implementation (#260) * APP-3110 Handlebars template engine implementation * APP-3110 doc * APP-3110 Post merge, updated getting-started guide * APP-3110 http and template implementations as runtime dependencies * APP-3110 reverted ./docs/index.md * APP-3110 Updates implementation selection * APP-3110 :symphony-bdk-http-api and :symphony-bdk-template-api as :symphony-bdk-core transitive dependencies (cherry picked from commit edb1844b7eac3cc88827df3d8a4d19c7d0f58e82) --- .../symphony/bdk/template/handlebars/HandlebarsEngine.java | 7 +++---- .../bdk/template/handlebars/HandlebarsTemplate.java | 3 +-- .../bdk/template/handlebars/HandlebarsEngineTest.java | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsEngine.java b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsEngine.java index 3d29f99bb..6298da399 100644 --- a/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsEngine.java +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsEngine.java @@ -1,12 +1,11 @@ package com.symphony.bdk.template.handlebars; -import com.symphony.bdk.template.api.Template; -import com.symphony.bdk.template.api.TemplateEngine; -import com.symphony.bdk.template.api.TemplateException; - import com.github.jknack.handlebars.Handlebars; import com.github.jknack.handlebars.io.FileTemplateLoader; import com.github.jknack.handlebars.io.TemplateLoader; +import com.symphony.bdk.template.api.Template; +import com.symphony.bdk.template.api.TemplateEngine; +import com.symphony.bdk.template.api.TemplateException; import org.apache.commons.io.FilenameUtils; import org.apiguardian.api.API; diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsTemplate.java b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsTemplate.java index b498d10a2..7fcb8e91a 100644 --- a/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsTemplate.java +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/src/main/java/com/symphony/bdk/template/handlebars/HandlebarsTemplate.java @@ -1,9 +1,8 @@ package com.symphony.bdk.template.handlebars; +import com.github.jknack.handlebars.Handlebars; import com.symphony.bdk.template.api.Template; import com.symphony.bdk.template.api.TemplateException; - -import com.github.jknack.handlebars.Handlebars; import org.apiguardian.api.API; import java.io.IOException; diff --git a/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/java/com/symphony/bdk/template/handlebars/HandlebarsEngineTest.java b/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/java/com/symphony/bdk/template/handlebars/HandlebarsEngineTest.java index b33a1e996..ad19a4240 100644 --- a/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/java/com/symphony/bdk/template/handlebars/HandlebarsEngineTest.java +++ b/symphony-bdk-template/symphony-bdk-template-handlebars/src/test/java/com/symphony/bdk/template/handlebars/HandlebarsEngineTest.java @@ -1,10 +1,7 @@ package com.symphony.bdk.template.handlebars; -import static org.junit.jupiter.api.Assertions.assertEquals; - import com.symphony.bdk.template.api.Template; import com.symphony.bdk.template.api.TemplateException; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -13,6 +10,8 @@ import java.nio.file.Path; import java.util.Collections; +import static org.junit.jupiter.api.Assertions.assertEquals; + class HandlebarsEngineTest { private static final String EXPECTED_TEST_HBS = "\nhello\n\n"; From 158bc3eba9838bde90ac5ad120f50b99cc2d07ef Mon Sep 17 00:00:00 2001 From: symphony-thibault Date: Mon, 5 Oct 2020 17:50:44 +0200 Subject: [PATCH 7/7] Bumped legacy version --- symphony-bdk-legacy/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/symphony-bdk-legacy/build.gradle b/symphony-bdk-legacy/build.gradle index b6d8ff6d3..4594f30ac 100644 --- a/symphony-bdk-legacy/build.gradle +++ b/symphony-bdk-legacy/build.gradle @@ -1,6 +1,6 @@ description = 'Symphony Java BDK Legacy Module' -ext.projectVersion = project.properties['projectVersion'] ?: '1.3.0' +ext.projectVersion = project.properties['projectVersion'] ?: '1.3.1' ext.isReleaseVersion = !ext.projectVersion.endsWith('SNAPSHOT') allprojects {