diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..270377064 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,52 @@ +name: Deploy Docs + +on: + push: + branches: + - "main" + paths: + - "docs/**" + +permissions: + contents: read + pages: write + id-token: write + +jobs: + build: + runs-on: ubuntu-latest + defaults: + run: + working-directory: docs + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.1' + bundler-cache: true + cache-version: 0 + working-directory: '${{ github.workspace }}/docs' + - name: Setup Pages + id: pages + uses: actions/configure-pages@v3 + - name: Build with Jekyll + run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" + env: + JEKYLL_ENV: production + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: "docs/_site/" + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 000000000..8615c68c2 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem "jekyll", "~> 4.3.2" +gem "just-the-docs", "0.5.2" +gem "jemoji" \ No newline at end of file diff --git a/docs/_config.yml b/docs/_config.yml index b95081f02..ff1acffbe 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,8 +1,10 @@ -# Theme -theme: jekyll-theme-cayman -# Site settings -name: Symphony BDK for Java -description: Symphony BDK (Bot Developer Kit) for Java developers -# Plugins +title: BDK 2.0 for Java +description: Reference documentation for using the Symphony BDK to build bots +theme: just-the-docs plugins: - - jemoji # https://docs.github.com/en/enterprise/2.13/user/articles/emoji-on-github-pages + - jemoji +url: https://symphony-bdk-java.finos.org +color_scheme: symphony +aux_links: + "BDK 2.0 on GitHub": + - "//github.com/finos/symphony-bdk-java" diff --git a/docs/_includes/anchor_headings.html b/docs/_includes/anchor_headings.html new file mode 100644 index 000000000..ee5c2a640 --- /dev/null +++ b/docs/_includes/anchor_headings.html @@ -0,0 +1,174 @@ +{% capture headingsWorkspace %} + {% comment %} + Copyright (c) 2018 Vladimir "allejo" Jimenez + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + {% endcomment %} + {% comment %} + Version 1.0.13 + https://github.com/allejo/jekyll-anchor-headings + + "Be the pull request you wish to see in the world." ~Ben Balter + + Usage: + {% include anchor_headings.html html=content anchorBody="#" %} + + Parameters: + * html (string) - the HTML of compiled markdown generated by kramdown in Jekyll + + Optional Parameters: + * beforeHeading (bool) : false - Set to true if the anchor should be placed _before_ the heading's content + * headerAttrs (string) : '' - Any custom HTML attributes that will be added to the heading tag; you may NOT use `id`; + the `%heading%` and `%html_id%` placeholders are available + * anchorAttrs (string) : '' - Any custom HTML attributes that will be added to the `` tag; you may NOT use `href`, `class` or `title`; + the `%heading%` and `%html_id%` placeholders are available + * anchorBody (string) : '' - The content that will be placed inside the anchor; the `%heading%` placeholder is available + * anchorClass (string) : '' - The class(es) that will be used for each anchor. Separate multiple classes with a space + * anchorTitle (string) : '' - The `title` attribute that will be used for anchors + * h_min (int) : 1 - The minimum header level to build an anchor for; any header lower than this value will be ignored + * h_max (int) : 6 - The maximum header level to build an anchor for; any header greater than this value will be ignored + * bodyPrefix (string) : '' - Anything that should be inserted inside of the heading tag _before_ its anchor and content + * bodySuffix (string) : '' - Anything that should be inserted inside of the heading tag _after_ its anchor and content + * generateId (true) : false - Set to true if a header without id should generate an id to use. + + Output: + The original HTML with the addition of anchors inside of all of the h1-h6 headings. + {% endcomment %} + + {% assign minHeader = include.h_min | default: 1 %} + {% assign maxHeader = include.h_max | default: 6 %} + {% assign beforeHeading = include.beforeHeading %} + {% assign headerAttrs = include.headerAttrs %} + {% assign nodes = include.html | split: ' + {% if headerLevel == 0 %} + + {% assign firstChunk = node | split: '>' | first %} + + + {% unless firstChunk contains '<' %} + {% capture node %}{% endcapture %} + {% assign _workspace = node | split: _closingTag %} + {% capture _hAttrToStrip %}{{ _workspace[0] | split: '>' | first }}>{% endcapture %} + {% assign header = _workspace[0] | replace: _hAttrToStrip, '' %} + {% assign escaped_header = header | strip_html | strip %} + + {% assign _classWorkspace = _workspace[0] | split: 'class="' %} + {% assign _classWorkspace = _classWorkspace[1] | split: '"' %} + {% assign _html_class = _classWorkspace[0] %} + + {% if _html_class contains "no_anchor" %} + {% assign skip_anchor = true %} + {% else %} + {% assign skip_anchor = false %} + {% endif %} + + {% assign _idWorkspace = _workspace[0] | split: 'id="' %} + {% if _idWorkspace[1] %} + {% assign _idWorkspace = _idWorkspace[1] | split: '"' %} + {% assign html_id = _idWorkspace[0] %} + {% assign h_attrs = headerAttrs %} + {% elsif include.generateId %} + + {% assign html_id = escaped_header | slugify %} + {% if html_id == "" %} + {% assign html_id = false %} + {% endif %} + + {% capture h_attrs %}{{ headerAttrs }} id="%html_id%"{% endcapture %} + {% endif %} + + + {% capture anchor %}{% endcapture %} + + {% if skip_anchor == false and html_id and headerLevel >= minHeader and headerLevel <= maxHeader %} + {% if h_attrs %} + {% capture _hAttrToStrip %}{{ _hAttrToStrip | split: '>' | first }} {{ h_attrs | strip | replace: '%heading%', escaped_header | replace: '%html_id%', html_id }}>{% endcapture %} + {% endif %} + + {% capture anchor %}href="#{{ html_id }}"{% endcapture %} + + {% if include.anchorClass %} + {% capture anchor %}{{ anchor }} class="{{ include.anchorClass }}"{% endcapture %} + {% endif %} + + {% if include.anchorTitle %} + {% capture anchor %}{{ anchor }} title="{{ include.anchorTitle | replace: '%heading%', escaped_header }}"{% endcapture %} + {% endif %} + + {% if include.anchorAttrs %} + {% capture anchor %}{{ anchor }} {{ include.anchorAttrs | replace: '%heading%', escaped_header | replace: '%html_id%', html_id }}{% endcapture %} + {% endif %} + + {% capture anchor %}{{ include.anchorBody | replace: '%heading%', escaped_header | default: '' }}{% endcapture %} + + + {% if beforeHeading %} + {% capture anchor %}{{ anchor }} {% endcapture %} + {% else %} + {% capture anchor %} {{ anchor }}{% endcapture %} + {% endif %} + {% endif %} + + {% capture new_heading %} + + {% endcapture %} + + + {% assign chunkCount = _workspace | size %} + {% if chunkCount > 1 %} + {% capture new_heading %}{{ new_heading }}{{ _workspace | last }}{% endcapture %} + {% endif %} + + {% capture edited_headings %}{{ edited_headings }}{{ new_heading }}{% endcapture %} + {% endfor %} +{% endcapture %}{% assign headingsWorkspace = '' %}{{ edited_headings | strip }} diff --git a/docs/_includes/nav_footer_custom.html b/docs/_includes/nav_footer_custom.html new file mode 100644 index 000000000..8083c7838 --- /dev/null +++ b/docs/_includes/nav_footer_custom.html @@ -0,0 +1 @@ +  \ No newline at end of file diff --git a/docs/_layouts/base.html b/docs/_layouts/base.html new file mode 100644 index 000000000..c3eabce9d --- /dev/null +++ b/docs/_layouts/base.html @@ -0,0 +1 @@ +{% include anchor_headings.html html=content anchorBody="#" %} diff --git a/docs/_sass/color_schemes/symphony.scss b/docs/_sass/color_schemes/symphony.scss new file mode 100644 index 000000000..fd1fef692 --- /dev/null +++ b/docs/_sass/color_schemes/symphony.scss @@ -0,0 +1 @@ +$link-color: #116fb9; diff --git a/docs/activity-api.md b/docs/activity-api.md index 00c0a55c1..20d68719f 100644 --- a/docs/activity-api.md +++ b/docs/activity-api.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Activity API +nav_order: 17 +--- + # Activity API The Activity API is an abstraction built on top of the Datafeed's [_Real Time Events_](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events). An Activity is basically a user interaction triggered from the chat. @@ -143,41 +149,6 @@ public class Example { 3. the command callback provides the `CommandContext` that allows to retrieve some information about the source of the event, or the event initiator (i.e. user that triggered the command) -### Async Slash Command -A slash command is synchronous by default. In case the process takes times, the others incoming commands will be queued -and get executed when the blocking process is released. If it is a concern, Slash command can be asynchronous by passing -`asynchronous` parameter to the annotation. - -```java -@Slf4j -public class AsyncCommandMain { - public static void main(String[] args) throws Exception { - - // setup SymphonyBdk facade object - final SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath("/config.yaml")); - - // displays the Gif form on /gif command with no params - bdk.activities().register(slash("/async", // (1) - false, // (2) - true, // (3) - context -> // (4) - bdk.messages().send(context.getStreamId(), - "This is an asynchronous command that should not block next commands"), - "Asynchronous command example" // (5) - )); - - // finally, start the datafeed loop - bdk.datafeed().start(); - } -} -``` -1. `/async` is the command pattern -2. `false` means that the bot should not be mentioned in the command -3. `true` means that the command will be executed asynchronously -4. the command callback provides the `CommandContext` that allows to retrieve some information about the source of the - event, or the event initiator (i.e. user that triggered the command) -5. the command description - ### Help Command _Help_ command is a BDK built-in command which will list out all the commands registered in the `ActivityRegistry` of the BDK by: @@ -275,4 +246,4 @@ submitted from the action button "**submit**" 2. The activity context allows to directly retrieve form values. Here the "**name**" `` value ---- -[Home :house:](./index.md) +[Home :house:](./index.html) diff --git a/docs/application.md b/docs/application.md index 1382b644b..a14ae14fd 100644 --- a/docs/application.md +++ b/docs/application.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Application API +nav_order: 12 +--- + # Application API The Application Service is a component at the service layer of the BDK which aims to cover the Applications part of the [REST API documentation](https://developers.symphony.com/restapi/reference). diff --git a/docs/authentication.md b/docs/authentication.md index 3fdd2096e..2c128edc3 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Authentication +nav_order: 5 +--- + # Authentication The Symphony BDK authentication API allows developers to authenticate their bots and apps using either RSA or certificate authentication modes. @@ -225,4 +231,4 @@ public class Example { ``` ---- -[Home :house:](./index.md) +[Home :house:](./index.html) diff --git a/docs/configuration.md b/docs/configuration.md index 7eaf74764..2428af49b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,6 +1,12 @@ +--- +layout: default +title: Configuration +nav_order: 4 +--- + # Configuration -The BDK configuration is one of the most essential feature of the Symphony BDK which allows developers to configure +The BDK configuration is one of the most essential feature of the Symphony BDK which allows developers to configure their bot environment. ## Minimal configuration example @@ -8,7 +14,7 @@ The minimal configuration file that can be provided look like: ```yaml host: acme.symphony.com # (1) -bot: +bot: username: bot-username # (2) privateKey: path: /path/to/bot/rsa-private-key.pem # (3) @@ -18,13 +24,13 @@ bot: 3. your bot RSA private key according to the RSA public key upload in your pod admin console (https://acme.symphony.com/admin-console) ## How to load configuration -The Symphony BDK provides a single way to configure your bot environment. +The Symphony BDK provides a single way to configure your bot environment. ```java public class Example { - + public static void main(String[] args) { - + final BdkConfig config01 = BdkConfigLoader.loadFromFile("/absolute/path/to/config.yaml"); // (1) final BdkConfig config02 = BdkConfigLoader.loadFromClasspath("/config.yaml"); // (2) @@ -51,7 +57,7 @@ public class Example { 1. Load configuration from a system location path 2. Load configuration from a classpath location 3. Load configuration from an [`InputStream`](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html) -4. Load configuration from the Symphony directory. The Symphony directory is located under your `${user.home}/.symphony` +4. Load configuration from the Symphony directory. The Symphony directory is located under your `${user.home}/.symphony` folder. It can be useful when you don't want to share your own Symphony credentials within your project codebase 5. Load configuration from [`Map`](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html) of properties 6. Load configuration from [`Properties`](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html) @@ -70,7 +76,7 @@ connectionPoolPerRoute: 20 defaultHeaders: Connection: Keep-Alive Keep-Alive: timeout=5, max=1000 - + proxy: host: proxy.symphony.com port: 1234 @@ -97,7 +103,7 @@ keyManager: defaultHeaders: Connection: Keep-Alive Keep-Alive: close - + sessionAuth: host: dev-session.symphony.com port: 8444 @@ -127,7 +133,7 @@ datafeed: initialIntervalMillis: 2000 multiplier: 1.5 maxIntervalMillis: 10000 - + retry: maxAttempts: 6 # set '-1' for an infinite number of attempts, default value is '10' initialIntervalMillis: 2000 @@ -144,16 +150,16 @@ user specify the dedicated `host`, `port`, `context`, `scheme` or custom connect - `proxy` contains proxy related information. This field is optional. If set, it will use the provided `host` (mandatory), `port` (mandatory), `username` and `password`. It can be overridden in each of the `pod`, `agent`, `keyManager` and `sessionAuth` fields. -- `pod` contains information like host, port, scheme, context, proxy... of the pod on which +- `pod` contains information like host, port, scheme, context, proxy... of the pod on which the service account using by the bot is created. -- `agent` contains information like host, port, scheme, context, proxy... of the agent which +- `agent` contains information like host, port, scheme, context, proxy... of the agent which the bot connects to. It can also contain a `loadBalancing` field: if defined, it should not any field among scheme, host, port, context. -- `keyManager` contains information like host, port, scheme, context, proxy... of the key +- `keyManager` contains information like host, port, scheme, context, proxy... of the key manager which manages the key token of the bot. -- `bot` contains information about the bot like the username, the private key or +- `bot` contains information about the bot like the username, the private key or the certificate for authenticating the service account on pod. -- `app` contains information about the extension app that the bot will use like +- `app` contains information about the extension app that the bot will use like the appId, the private key or the certificate for authenticating the extension app. - `ssl` contains trustStore and trustStore password for SSL communication. - `datafeed` contains information of the datafeed service to be used by the bot. @@ -169,10 +175,10 @@ Only absolute paths to classpath resources are supported (i.e. paths beginning w #### Retry Configuration The retry mechanism used by the bot will be configured by these following properties: - `maxAttempts`: maximum number of retry attempts that the bot is able to make. -- `multiplier`: after each attempt, the interval between two attempts will be multiplied by +- `multiplier`: after each attempt, the interval between two attempts will be multiplied by this factor. (Exponential backoff strategy) - `initialIntervalMillis`: the initial interval between two attempts. -- `maxIntervalMillis`: the limit of the interval between two attempts. For example: if the +- `maxIntervalMillis`: the limit of the interval between two attempts. For example: if the current interval is 1000 millis, multiplier is 2.0 and the maxIntervalMillis is 1500 millis, then the interval for next retry will be 1500 millis. @@ -183,14 +189,14 @@ default value: - `multiplier`: 2 - `maxIntervalMillis`: 300000 (5 mins) -This global retry configuration can be override by each service. We can define a specific retry +This global retry configuration can be override by each service. We can define a specific retry configuration inside service configuration to override the global one. #### DatafeedConfiguration The datafeed configuration will contain information about the datafeed service to be used by the bot: - `version`: the version of datafeed service to be used. By default, the bot will use the datafeed v2 -service. -- `idFilePath`: the path to the file which will be used to persist a created datafeed id in case the +service. +- `idFilePath`: the path to the file which will be used to persist a created datafeed id in case the datafeed service v1 is used. - `retry`: the specific retry configuration can be used to override the global retry configuration. If no retry configuration is defined, the global one will be used. @@ -243,19 +249,19 @@ datafeed: ``` ## Configuration format -Both of `JSON` and `YAML` formats are supported by BDK configuration. Using `JSON`, a minimal configuration file would -look like: +Both of `JSON` and `YAML` formats are supported by BDK configuration. Using `JSON`, a minimal configuration file would +look like: ```json { "host": "acme.symphony.com", - "bot": { + "bot": { "username": "bot-username", "privateKey": { "path": "/path/to/bot/rsa-private-key.pem" } } } -``` +``` ### Field interpolation using Java system properties or environment variables In both formats, you can use Java system properties and system environment variables as field values. For instance, `${user.home}` in any field will be @@ -279,18 +285,18 @@ Please mind that if you want to escape the `$` sign, `$${value}` will be replace And as the matching of environment variables is done after Java system properties, if you have a system property with **value** `${value}` and en environment variable with **key** `value`, it will substitute the value of the environment variable -Reading a `JSON` configuration file is completely transparent: +Reading a `JSON` configuration file is completely transparent: ```java public class Example { - + public static void main(String[] args) { - + final BdkConfig config = BdkConfigLoader.loadFromClasspath("/config.json"); } } ``` -## Backward Compatibility with legacy configuration file (experimental) +## Backward Compatibility with legacy configuration file (experimental) The legacy configuration using by the Java SDK v1 is also supported in BDK Configuration 2.0. @@ -298,4 +304,4 @@ This legacy configuration can be also read from a file, an inputstream, a classp translated to `BdkConfig` instance. ---- -[Home :house:](./index.md) +[Home :house:](./index.html) diff --git a/docs/connection.md b/docs/connection.md index 08e3d4c16..1fd4f40be 100644 --- a/docs/connection.md +++ b/docs/connection.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Connection API +nav_order: 14 +--- + # Connection API The Connection Service is a component at the service layer of the BDK which aims to cover the Connections part of the [REST API documentation](https://developers.symphony.com/restapi/reference). diff --git a/docs/datafeed.md b/docs/datafeed.md index 9ebb413b5..9d4e6e3f7 100644 --- a/docs/datafeed.md +++ b/docs/datafeed.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Datafeed +nav_order: 6 +--- + # Datafeed > :warning: The datafeed 1 service will be fully replaced by the datafeed 2 service in the future. > Please consider using datafeed 2. @@ -13,7 +19,7 @@ create a datafeed, list all created datafeeds or retrieve all the Real Time Even API. The datafeed loop is a core service built on top of the Datafeed API and provides a dedicated contract to bot developers to work with datafeed. -For more advanced interactions between users and bots, you can also read [Activity API](./activity-api.md). +For more advanced interactions between users and bots, you can also read [Activity API](./activity-api.html). ## How to use @@ -147,7 +153,7 @@ Events_](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed difference that *all* events of the pod are received. The datahose loop is a core service built on top of the events API and provide a dedicated contract to bot developers to work with datahose. This is compatible with agent version 22.5 onwards. -The [Activity API](./activity-api.md) is not meant to be used with datahose. +The [Activity API](./activity-api.html) is not meant to be used with datahose. ## How to use The central component for the contract between bot developers and the Datafeed API is the `DatahoseLoop`. This service @@ -297,7 +303,7 @@ event twice. This can be achieved by maintaining a short time lived cache of the ## Running multiple instances of a bot (DF v2 and datahose only) An example using datafeed v2 is provided in -[bdk-multi-instances-example](https://github.com/finos/symphony-bdk-java/blob/main/symphony-bdk-examples/bdk-multi-instances-example/README.md) module. +[bdk-multi-instances-example](https://github.com/finos/symphony-bdk-java/blob/main/symphony-bdk-examples/bdk-multi-instances-example) module. With datafeed v2, it is possible to run multiple instances of a bot. Each instance will receive events in turn. The examples also makes use of Hazelcast to keep a distributed cache of already processed events and avoid replying to a @@ -310,4 +316,4 @@ The same applies to datahose. To enable this behavior, make sure you have the sa (or no `tag` field) in the configuration of all your bot instances. ---- -[Home :house:](./index.md) +[Home :house:](./index.html) diff --git a/docs/disclaimer.md b/docs/disclaimer.md index ba022c34d..a0f678705 100644 --- a/docs/disclaimer.md +++ b/docs/disclaimer.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Disclaimer API +nav_order: 15 +--- + # Disclaimer API The Disclaimer Service is a component at the service layer of the BDK which aims to cover the Disclaimers part of the [REST API documentation](https://developers.symphony.com/restapi/reference). diff --git a/docs/extension.md b/docs/extension.md index c7113485e..28179bd6c 100644 --- a/docs/extension.md +++ b/docs/extension.md @@ -1,11 +1,17 @@ +--- +layout: default +title: Extending the BDK +nav_order: 18 +--- + # Extension Model > :bulb: since `2.6` -> :warning: The BDK Extension Mechanism is still an experimental feature, contracts might be subject to **breaking changes** +> :warning: The BDK Extension Mechanism is still an experimental feature, contracts might be subject to **breaking changes** > in following versions. ## Overview -The BDK extension model consists of a simple concept: the `BdkExtension` API. Note, however, that `BdkExtension` +The BDK extension model consists of a simple concept: the `BdkExtension` API. Note, however, that `BdkExtension` itself is just a marker interface. The `BdkExtension` API is available through the module `:symphony-bdk-extension-api` but other modules might be required @@ -15,23 +21,23 @@ depending on what your extension needs to use. Extensions are registered _programmatically_ via the `ExtensionService`: ```java class ExtensionExample { - + public static void main(String[] args) { // using the ExtensionService final SymphonyBdk bdk = new SymphonyBdk(loadFromSymphonyDir("config.yaml")); bdk.extensions().register(MyBdkExtension.class); - + // or using the SymphonyBdkBuilder final SymphonyBdk bdk = SymphonyBdk.builder() .config(loadFromSymphonyDir("config.yaml")) - .extension(MyBdkExtension.class) + .extension(MyBdkExtension.class) .build(); } } ``` ### Registering Extensions in Spring Boot -To use your extension in the [BDK Spring Boot Starter](./spring-boot/core-starter.md), you simply need to register your +To use your extension in the [BDK Spring Boot Starter](./spring-boot/core-starter.html), you simply need to register your extension as a bean added to the application context. Note that your extension class must implement `BdkExtension` in order to automatically be registered: ```java @@ -47,17 +53,17 @@ public class MyBdkExtensionConfig { This way, your extension will automatically be registered within the `ExtensionService`. ## Service Provider Extension -A _Service Provider_ extension is a specific type of extension loaded on demand when calling the +A _Service Provider_ extension is a specific type of extension loaded on demand when calling the `ExtensionService#service(Class)` method. To make your extension _Service Provider_, your extension definition class must implement the `BdkExtensionServiceProvider` -interface along with the `BdkExtension` marker interface: +interface along with the `BdkExtension` marker interface: ```java /** * The Service implementation class. */ public class MyBdkExtensionService implements BdkExtensionService { - + public void sayHello(String name) { System.out.println("Hello, %s!", name); // #noLog4Shell } @@ -68,7 +74,7 @@ public class MyBdkExtensionService implements BdkExtensionService { public class MyBdkExtension implements BdkExtension, BdkExtensionServiceProvider { private final MyBdkExtensionService service = new MyBdkExtensionService(); - + @Override public MyBdkExtensionService getService() { return this.service; @@ -84,7 +90,7 @@ class ExtensionExample { .config(loadFromSymphonyDir("config.yaml")) .extension(MyBdkExtension.class) .build(); - + final MyBdkExtensionService service = bdk.extensions().service(MyBdkExtension.class); service.sayHello("Symphony"); } @@ -113,7 +119,7 @@ public class ApiController { private MyBdkExtensionService groupService; } ``` -> :bulb: Note that your IDE might show an error like "_Could not autowire. No beans of 'MyBdkExtensionService' type found_". +> :bulb: Note that your IDE might show an error like "_Could not autowire. No beans of 'MyBdkExtensionService' type found_". > To disable this warning you can annotate your class with `@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")` ## BDK Aware Extensions @@ -121,12 +127,12 @@ The BDK Extension Model allows extensions to access to some core objects such as Developers that wish to use these objects a free to implement a set of interfaces all suffixed with the `Aware` keyword. ### `BdkConfigAware` -The interface `com.symphony.bdk.core.config.extension.BdkConfigAware` allows extensions to read the BDK configuration: +The interface `com.symphony.bdk.core.config.extension.BdkConfigAware` allows extensions to read the BDK configuration: ```java public class MyBdkExtension implements BdkExtension, BdkConfigAware { private BdkConfig config; - + @Override public void setConfiguration(BdkConfig config) { this.config = config; @@ -136,12 +142,12 @@ public class MyBdkExtension implements BdkExtension, BdkConfigAware { ### `BdkApiClientFactoryAware` The interface `com.symphony.bdk.core.extension.BdkApiClientFactoryAware` can be used by extensions that need to -use the `com.symphony.bdk.core.client.ApiClientFactory` class: +use the `com.symphony.bdk.core.client.ApiClientFactory` class: ```java public class MyBdkExtension implements BdkExtension, BdkApiClientFactoryAware { private ApiClientFactory apiClientFactory; - + @Override public void setApiClientFactory(ApiClientFactory apiClientFactory) { this.apiClientFactory = apiClientFactory; @@ -150,14 +156,14 @@ public class MyBdkExtension implements BdkExtension, BdkApiClientFactoryAware { ``` ### `BdkAuthenticationAware` -The interface `com.symphony.bdk.core.extension.BdkAuthenticationAware` can be used by extensions that need to rely on the -service account authentication session (`com.symphony.bdk.core.auth.AuthSession`), which provides the `sessionToken` and -`keyManagerToken` that are used to call the Symphony's APIs: +The interface `com.symphony.bdk.core.extension.BdkAuthenticationAware` can be used by extensions that need to rely on the +service account authentication session (`com.symphony.bdk.core.auth.AuthSession`), which provides the `sessionToken` and +`keyManagerToken` that are used to call the Symphony's APIs: ```java public class MyBdkExtension implements BdkExtension, BdkAuthenticationAware { private AuthSession authSession; - + @Override public void setAuthSession(AuthSession authSession) { this.authSession = authSession; @@ -166,8 +172,8 @@ public class MyBdkExtension implements BdkExtension, BdkAuthenticationAware { ``` ### `BdkRetryBuilderAware` -The interface `com.symphony.bdk.core.extension.BdkRetryBuilderAware` allows extensions to leverage the internal BDK retry API -through the `com.symphony.bdk.core.retry.RetryWithRecoveryBuilder` class: +The interface `com.symphony.bdk.core.extension.BdkRetryBuilderAware` allows extensions to leverage the internal BDK retry API +through the `com.symphony.bdk.core.retry.RetryWithRecoveryBuilder` class: ```java public class MyBdkExtension implements BdkExtension, BdkRetryBuilderAware { diff --git a/docs/fluent-api.md b/docs/fluent-api.md index 63dfede35..615741f70 100644 --- a/docs/fluent-api.md +++ b/docs/fluent-api.md @@ -1,18 +1,24 @@ +--- +layout: default +title: Fluent API +nav_order: 7 +--- + # Fluent API -The Fluent API is the most basic feature of the BDK. This component provides the developers very quickly an entry point -to discover all others features of the BDK, helps them to easily understand how to make a bot interacting with the +The Fluent API is the most basic feature of the BDK. This component provides the developers very quickly an entry point +to discover all others features of the BDK, helps them to easily understand how to make a bot interacting with the Symphony platform. ## SymphonyBdk The heart of the Fluent API is the [`SymphonyBdk`](../symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdk.java). -This component is an entry point for a developer to go through all the features of the BDK. A `SymphonyBdk` object is +This component is an entry point for a developer to go through all the features of the BDK. A `SymphonyBdk` object is built from the information extracted from the BDK configuration file. ```java public class Example { - + public static void main(String[] args) { // Initialize the BDK entry point final SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath("/config.yaml")); @@ -21,11 +27,11 @@ public class Example { ``` ### Advanced SymphonyBdk initialization -Another way to initialize the `SymphonyBdk` entry is to use the `SymphonyBdkBuilder`. +Another way to initialize the `SymphonyBdk` entry is to use the `SymphonyBdkBuilder`. ```java public class Example { - + public static void main(String[] args) { // Initialize the BDK entry point final SymphonyBdk bdk = SymphonyBdk.builder() @@ -39,12 +45,12 @@ public class Example { ## Using BDK services from SymphonyBdk -Once the `SymphonyBdk` instance is created, the bot is automatically authenticated and all the BDK services will be available +Once the `SymphonyBdk` instance is created, the bot is automatically authenticated and all the BDK services will be available for developers to use. ```java public class Example { - + public static void main(String[] args) { // Initialize the BDK entry point final SymphonyBdk bdk = new SymphonyBdk(loadFromClasspath("/config.yaml")); @@ -67,4 +73,4 @@ that is available in BDK is: - Activities Registry: `bdk.activities()` ---- -[Home :house:](./index.md) +[Home :house:](./index.html) diff --git a/docs/getting-started.md b/docs/getting-started.md index e43617afc..0d53dbb1a 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,6 +1,12 @@ +--- +layout: default +title: Getting Started +nav_order: 2 +--- + # Getting Started with Symphony BDK for Java -This guide provides detailed information for beginners who want to bootstrap their first Symphony BDK project +This guide provides detailed information for beginners who want to bootstrap their first Symphony BDK project in Java. Two different approaches will be detailed here: - using the Symphony Generator - from scratch @@ -105,28 +111,28 @@ dependencies { ``` ### Create configuration file -Before implementing any code, you need to create your `src/main/resources/config.yaml` configuration file according +Before implementing any code, you need to create your `src/main/resources/config.yaml` configuration file according to your Symphony environment: ```yaml host: acme.symphony.com # your own pod host name -bot: +bot: username: bot-username # your bot (or service account) username privateKey: path: /path/to/bot/rsa-private-key.pem # your bot RSA private key ``` -> Click [here](./configuration.md) for more detailed documentation about BDK configuration +> Click [here](./configuration.html) for more detailed documentation about BDK configuration ### Create a Simple Bot Application Now you can create a Simple Bot Application by creating main class `src/main/java/com/example/symphony/BotApplication.java`: - + ```java public class BotApplication { - + public static void main(String[] args) { - + final SymphonyBdk bdk = new SymphonyBdk(BdkConfigLoader.loadFromClasspath("/config.yaml")); // (1) - + bdk.datafeed().subscribe(new RealTimeEventListener() { // (2) @Override @@ -134,18 +140,18 @@ public class BotApplication { bdk.messages().send(event.getMessage().getStream(), "Hello, World!"); // (3) } }); - + bdk.datafeed().start(); // (4) } } ``` -1. The `SymphonyBdk` class acts as an entry point into the library and provides a [fluent API](./fluent-api.md) to access -to the main BDK features such as [Datafeed](./datafeed.md), services or [Activities](./activity-api.md) -2. Subscribe to the [`onMessageSent`](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events#message-sent) +1. The `SymphonyBdk` class acts as an entry point into the library and provides a [fluent API](./fluent-api.html) to access +to the main BDK features such as [Datafeed](./datafeed.html), services or [Activities](./activity-api.html) +2. Subscribe to the [`onMessageSent`](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events#message-sent) [Real Time Event](https://docs.developers.symphony.com/building-bots-on-symphony/datafeed/real-time-events) -3. When any message is sent into a stream where your bot is a member, it will reply by message `Hello, World`! +3. When any message is sent into a stream where your bot is a member, it will reply by message `Hello, World`! 4. Start the Datafeed read loop ---- -[Home :house:](./index.md) - +[Home :house:](./index.html) + diff --git a/docs/health.md b/docs/health.md index 561311b13..b8b4e327d 100644 --- a/docs/health.md +++ b/docs/health.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Health API +nav_order: 16 +--- + # Health API The Health Service is a component at the service layer of the BDK which covers the Health Service part of the [REST API documentation](https://developers.symphony.com/restapi/reference). More precisely: diff --git a/docs/index.md b/docs/index.md index 4a83b13dc..c10b5846b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,38 +1,44 @@ +--- +title: Home +layout: home +nav_order: 1 +--- + # Symphony BDK Reference Documentation This reference guide provides detailed information about the Symphony BDK. It provides a comprehensive documentation for all features and abstractions made on top of the [Symphony REST API](https://developers.symphony.com/restapi/reference/introduction). If you are just getting started with Symphony Bot developments, you may want to begin reading the -[Getting Started](./getting-started.md) guide. +[Getting Started](./getting-started.html) guide. The reference documentation consists of the following sections: | Section | Description | |------------------------------------------|:---------------------------------------------------------------------:| -| [Getting Started](./getting-started.md) | Introducing Symphony BDK for beginners | -| [Migration Guide](./migration.md) | Guide to migrate to Symphony BDK 2.0 | -| [Configuration](./configuration.md) | Configuration structure, formats, how to load from code | -| [Authentication](./authentication.md) | RSA or certificate authentication, OBO, extension app authentication | -| [Datafeed Loop](datafeed.md) | Receiving real time events | -| [Fluent API](fluent-api.md) | Java Fluent API usage | -| [Message API](message.md) | Sending or searching messages, usage of templates | -| [Stream API](stream.md) | Create and manage streams | -| [User API](user.md) | Manage users | -| [Presence API](presence.md) | Manage user presence status | -| [Application API](application.md) | Managing applications | -| [Signal API](signal.md) | Creating and managing signals | -| [Connection API](connection.md) | Managing connections | -| [Disclaimer API](disclaimer.md) | Managing disclaimers | -| [Health API](health.md) | Get health check status | -| [Activity API](activity-api.md) | The Activity Registry, creating custom activities | -| [Extending the BDK](extension.md) | How to use or develop BDK extensions | -| [Integration Test](test.md) | How to write the integration tests for Symphony BDK Bot application | +| [Getting Started](./getting-started.html) | Introducing Symphony BDK for beginners | +| [Migration Guide](./migration.html) | Guide to migrate to Symphony BDK 2.0 | +| [Configuration](./configuration.html) | Configuration structure, formats, how to load from code | +| [Authentication](./authentication.html) | RSA or certificate authentication, OBO, extension app authentication | +| [Datafeed Loop](datafeed.html) | Receiving real time events | +| [Fluent API](fluent-api.html) | Java Fluent API usage | +| [Message API](message.html) | Sending or searching messages, usage of templates | +| [Stream API](stream.html) | Create and manage streams | +| [User API](user.html) | Manage users | +| [Presence API](presence.html) | Manage user presence status | +| [Application API](application.html) | Managing applications | +| [Signal API](signal.html) | Creating and managing signals | +| [Connection API](connection.html) | Managing connections | +| [Disclaimer API](disclaimer.html) | Managing disclaimers | +| [Health API](health.html) | Get health check status | +| [Activity API](activity-api.html) | The Activity Registry, creating custom activities | +| [Extending the BDK](extension.html) | How to use or develop BDK extensions | +| [Integration Test](test.html) | How to write the integration tests for Symphony BDK Bot application | ### Spring Boot Getting Started guides are also available for Spring Boot: -- [Core Starter](./spring-boot/core-starter.md) -- [App Starter](./spring-boot/app-starter.md) +- [Core Starter](./spring-boot/core-starter.html) +- [App Starter](./spring-boot/app-starter.html) ### Technical Documentation -You can find an overview of the BDK Architecture [here](./tech/architecture.md). +You can find an overview of the BDK Architecture [here](./tech/architecture.html). diff --git a/docs/message.md b/docs/message.md index fa540c428..005e60fde 100644 --- a/docs/message.md +++ b/docs/message.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Message API +nav_order: 8 +--- + # Message API The Message API aims to cover the Messages part of the [REST API documentation](https://developers.symphony.com/restapi/reference/messages-v4). @@ -100,7 +106,7 @@ public class Example { 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): +With [Maven](./getting-started.html#maven-based-project): ```xml @@ -116,7 +122,7 @@ With [Maven](./getting-started.md#maven-based-project): ``` -With [Gradle](./getting-started.md#gradle-based-project): +With [Gradle](./getting-started.html#gradle-based-project): ```groovy dependencies { runtimeOnly 'org.finos.symphony.bdk:symphony-bdk-template-freemarker' @@ -145,4 +151,4 @@ public class Example { ``` ---- -[Home :house:](./index.md) +[Home :house:](./index.html) diff --git a/docs/migration.md b/docs/migration.md index d7f38de2d..65bb8bcd1 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Migration Guide +nav_order: 3 +--- + # Migration guide to Symphony BDK 2.0 This guide provides information about how to migrate from Symphony SDK 1.0 to BDK 2.0. Migration for the following topics will be detailed here: @@ -26,7 +32,7 @@ If your project is not framework based, dependencies such as *jersey* and *freem com.symphony.platformsolutions symphony-api-client-java 1.3.3 - + ``` @@ -121,7 +127,7 @@ If your bot is deployed on premise, the following properties are required as wel - `ssl.trustStore`: trust store path and password -> Click [here](./configuration.md) for more detailed documentation about BDK configuration +> Click [here](./configuration.html) for more detailed documentation about BDK configuration ### Minimal configuration example @@ -154,7 +160,7 @@ bot-config: /path/to/bot-config.json "authTokenRefreshPeriod": "30", "authenticationFilterUrlPattern": "/secure/", "showFirehoseErrors": false, - "connectionTimeout": 45000, + "connectionTimeout": 45000, "proxyURL": "proxy.symphony.com", "proxyUsername": "proxy.username", "proxyPassword": "proxy.password", @@ -191,7 +197,7 @@ Only `application.yaml` file is required. "username": "km.proxy.username", "password": "km.proxy.password" } - } + } } } ``` @@ -237,7 +243,7 @@ bdk: "authTokenRefreshPeriod": "30", "authenticationFilterUrlPattern": "/secure/", "showFirehoseErrors": false, - "connectionTimeout": 45000, + "connectionTimeout": 45000, "proxyURL": "proxy.symphony.com", "proxyUsername": "proxy.username", "proxyPassword": "proxy.password", @@ -300,9 +306,9 @@ keyManager: ``` ## Symphony BDK entry point -The `SymphonyBdk` class acts as an entry point into the library and provides a [fluent API](./fluent-api.md) to access to the main BDK features such as [Datafeed](./datafeed.md), services or [Activities](./activity-api.md). +The `SymphonyBdk` class acts as an entry point into the library and provides a [fluent API](./fluent-api.html) to access to the main BDK features such as [Datafeed](./datafeed.html), services or [Activities](./activity-api.html). With this class, all BDK services are auto-configured and can be directly accessed without any bot client. Examples of this class usage will be provided in next parts. -> Click [here](./fluent-api.md) for more detailed documentation about Symphony BDK fluent api +> Click [here](./fluent-api.html) for more detailed documentation about Symphony BDK fluent api ## BDK services @@ -336,19 +342,19 @@ public class PingPongBotService { @Slf4j public class PingPongBot { private static SymBotClient botClient; - + public PingPongBot(IMListenerImpl imListener, RoomListenerImpl roomListener, ElementsListenerImpl elementsListener) { try { // Bot init botClient = SymBotClient.initBotRsa("config.json"); - + // Bot listeners botClient.getDatafeedEventsService().addListeners(imListener, roomListener, elementsListener); } catch (Exception e) { log.error("Error: {}", e.getMessage()); } } - + public static void sendMessage(String streamId, String message) { botClient.getMessageClient.sendMessage(streamId, new OutboundMessage(message)); } @@ -405,19 +411,19 @@ public class GreetingsAllRoomsBot { final SymphonyBdk bdk = new SymphonyBdk(loadFromSymphonyDir("config.yaml")); // list all rooms Stream rooms = bdk.streams().listAllStreams(new StreamFilter()); - + rooms.forEach(streamAttributes -> { // send message to room bdk.messages().send(streamAttributes.getId(), "Hello world!"); log.info("Message sent to room with: id:{}, name:{}", streamAttributes.getId(), streamAttributes.getRoomAttributes().getName()); }); - + bdk.datafeed().start(); } } ```` -> A list of BDK available services can be found [here](./fluent-api.md) +> A list of BDK available services can be found [here](./fluent-api.html) ## Event listeners Java BDK 2.0 comes with a simplified way to handle event listeners. @@ -453,7 +459,7 @@ In Java BDK 2.0, only one component `RealTimeEventComponent` has to be implement public class RealTimeEventComponent { @EventListener public void onMessageSent(RealTimeEvent event) {...} - + @EventListener public onElementsAction(RealTimeEvent event) {...} } diff --git a/docs/presence.md b/docs/presence.md index 2ec30433b..7c86ca946 100644 --- a/docs/presence.md +++ b/docs/presence.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Presence API +nav_order: 11 +--- + # Presence API The Presence Service is a component at the service layer of the BDK which covers the Presence part of the [REST API documentation](https://developers.symphony.com/restapi/reference). diff --git a/docs/signal.md b/docs/signal.md index 06e77ac5c..da5e72c86 100644 --- a/docs/signal.md +++ b/docs/signal.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Signal API +nav_order: 13 +--- + # Signal API The Signal Service is a component at the service layer of the BDK which aims to cover the Signal part of the [REST API documentation](https://developers.symphony.com/restapi/reference). diff --git a/docs/spring-boot/app-starter.md b/docs/spring-boot/app-starter.md index 7ab87035d..bd30dff09 100644 --- a/docs/spring-boot/app-starter.md +++ b/docs/spring-boot/app-starter.md @@ -1,7 +1,14 @@ +--- +layout: default +title: Spring Boot App Starter +parent: Spring Boot Starters +nav_order: 2 +--- + # BDK Extension App Spring Boot Starter The Symphony BDK for Java provides a _Starter_ module that aims to ease extension app backend developments within a [Spring Boot](https://spring.io/projects/spring-boot) application. - + ## Features - Configure extension app through `application.yaml` - Application health info through Spring Boot standard actuator endpoint @@ -21,7 +28,7 @@ The following listing shows the `pom.xml` file that has to be created when using bdk-app-spring-boot 0.0.1-SNAPSHOT bdk-app-spring-boot - + UTF-8 @@ -44,7 +51,7 @@ The following listing shows the `pom.xml` file that has to be created when using symphony-bdk-app-spring-boot-starter - + @@ -67,13 +74,13 @@ plugins { dependencies { implementation platform('org.finos.symphony.bdk:symphony-bdk-bom:2.1.0') - + implementation 'org.finos.symphony.bdk:symphony-bdk-app-spring-boot-starter' } ``` ## Create a Simple Backend for Extension Application -As a first step, you have to initialize your environment through the Spring Boot `src/main/resources/application.yaml` file: +As a first step, you have to initialize your environment through the Spring Boot `src/main/resources/application.yaml` file: ```yaml bdk: host: acme.symphony.com @@ -81,7 +88,7 @@ bdk: username: bot-username privateKey: path: /path/to/rsa/privatekey.pem - + app: appId: app-id privateKey: @@ -93,7 +100,7 @@ bdk-app: jwtCookie: enabled: true # activate the jwt cookie storage (default is false) sameSite: Strict # same site configuration to restrict the jwt cookie from cross-site domain (default is Strict) - expireIn: 1d # jwt cookie duration (default value is 1d, see https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-conversion-duration) + expireIn: 1d # jwt cookie duration (default value is 1d, see https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-conversion-duration) cors: # enable Cross-Origin Resource Sharing (CORS) communication "[/**]": # url mapping allowed-origins: "*" # list of allowed origins path pattern that be specific origins, @@ -108,7 +115,7 @@ bdk-app: logging: level: com.symphony: debug # in development mode, it is strongly recommended to set the BDK logging level at DEBUG -``` +``` > You can notice here that the `bdk` property inherits from the [`BdkConfig`](https://javadoc.io/doc/org.finos.symphony.bdk/symphony-bdk-config/latest/com/symphony/bdk/core/config/model/BdkConfig.html) class. As required by Spring Boot, you have to create an `src/main/java/com/example/bot/ExtAppSpringApplication.java` class: @@ -146,4 +153,4 @@ management: include: 'symphonyBdk' health: show-details: "ALWAYS" -``` +``` diff --git a/docs/spring-boot/core-starter.md b/docs/spring-boot/core-starter.md index e2860ad6a..6132b69cf 100644 --- a/docs/spring-boot/core-starter.md +++ b/docs/spring-boot/core-starter.md @@ -1,6 +1,13 @@ +--- +layout: default +title: Spring Boot Core Starter +parent: Spring Boot Starters +nav_order: 1 +--- + # BDK Core Spring Boot Starter -The Symphony BDK for Java provides a _Starter_ module that aims to ease bot developments within a -[Spring Boot](https://spring.io/projects/spring-boot) application. +The Symphony BDK for Java provides a _Starter_ module that aims to ease bot developments within a +[Spring Boot](https://spring.io/projects/spring-boot) application. ## Features - Configure bot environment through `application.yaml` @@ -23,7 +30,7 @@ The following listing shows the `pom.xml` file that has to be created when using bdk-core-spring-boot 0.0.1-SNAPSHOT bdk-core-spring-boot - + UTF-8 @@ -57,7 +64,7 @@ The following listing shows the `pom.xml` file that has to be created when using test - + @@ -80,7 +87,7 @@ plugins { dependencies { implementation platform('org.finos.symphony.bdk:symphony-bdk-bom:2.12.0-SNAPSHOT') - + implementation 'org.finos.symphony.bdk:symphony-bdk-core-spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter' @@ -90,7 +97,7 @@ dependencies { ``` ## Create a Simple Bot Application -As a first step, you have to initialize your bot environment through the Spring Boot `src/main/resources/application.yaml` file: +As a first step, you have to initialize your bot environment through the Spring Boot `src/main/resources/application.yaml` file: ```yaml bdk: host: acme.symphony.com @@ -98,11 +105,11 @@ bdk: username: bot-username privateKey: path: /path/to/rsa/privatekey.pem - + logging: level: com.symphony: debug # in development mode, it is strongly recommended to set the BDK logging level at DEBUG -``` +``` > You can notice here that the `bdk` property inherits from the [`BdkConfig`](https://javadoc.io/doc/org.finos.symphony.bdk/symphony-bdk-config/latest/com/symphony/bdk/core/config/model/BdkConfig.html) class. As required by Spring Boot, you have to create an `src/main/java/com/example/bot/BotApplication.java` class: @@ -116,7 +123,7 @@ public class BotApplication { } ``` -Now you can create a component for a simple bot application, as the following listing (from `src/main/java/com/example/bot/HelloBot.java`) +Now you can create a component for a simple bot application, as the following listing (from `src/main/java/com/example/bot/HelloBot.java`) shows: ```java @Component @@ -126,12 +133,12 @@ public class HelloBot { private MessageService messageService; @EventListener - public void onMessageSent(RealTimeEvent event) { + public void onMessageSent(RealTimeEvent event) { log.info("event was triggered at {}", ((EventPayload) event.getSource()).getEventTimestamp()); this.messageService.send(event.getSource().getMessage().getStream(), "Hello!"); } } -``` +``` You can finally run your Spring Boot application and verify that your bot always replies with `Hello!`. It also worth noting that the event timestamp is only accessible from `EventPayload` type, you need simply cast the source event to it, and @@ -173,16 +180,16 @@ public class OboUsecase { Any attempt to use a non-OBO service endpoint will fail with an IllegalStateException. ## Subscribe to Real Time Events -The Core Starter uses [Spring Events](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationEventPublisher.html) +The Core Starter uses [Spring Events](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationEventPublisher.html) to deliver Real Time Events. -You can subscribe to any Real Time Event from anywhere in your application by creating a handler method that has to -respect two conditions: -- be annotated with [@EventListener](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/event/EventListener.html) +You can subscribe to any Real Time Event from anywhere in your application by creating a handler method that has to +respect two conditions: +- be annotated with [@EventListener](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/event/EventListener.html) - have `com.symphony.bdk.spring.events.RealTimeEvent` parameter -The listener methods will be called with events from the [datafeed loop](../datafeed.md#datafeed) or the -[datahose loop](../datafeed.md#datahose) (or both) depending on your configuration: +The listener methods will be called with events from the [datafeed loop](../datafeed.html#datafeed) or the +[datahose loop](../datafeed.html#datahose) (or both) depending on your configuration: ```yaml bdk: datafeed: @@ -199,52 +206,52 @@ Here's the list of Real Time Events you can subscribe: public class RealTimeEvents { @EventListener - public void onMessageSent(RealTimeEvent event) {} + public void onMessageSent(RealTimeEvent event) {} @EventListener - public void onSharedPost(RealTimeEvent event) {} + public void onSharedPost(RealTimeEvent event) {} @EventListener - public void onInstantMessageCreated(RealTimeEvent event) {} + public void onInstantMessageCreated(RealTimeEvent event) {} @EventListener - public void onRoomCreated(RealTimeEvent event) {} + public void onRoomCreated(RealTimeEvent event) {} @EventListener - public void onRoomUpdated(RealTimeEvent event) {} + public void onRoomUpdated(RealTimeEvent event) {} @EventListener - public void onRoomDeactivated(RealTimeEvent event) {} + public void onRoomDeactivated(RealTimeEvent event) {} @EventListener - public void onRoomReactivated(RealTimeEvent event) {} + public void onRoomReactivated(RealTimeEvent event) {} @EventListener - public void onUserRequestedToJoinRoom(RealTimeEvent event) {} + public void onUserRequestedToJoinRoom(RealTimeEvent event) {} @EventListener - public void onUserJoinedRoom(RealTimeEvent event) {} + public void onUserJoinedRoom(RealTimeEvent event) {} @EventListener - public void onUserLeftRoom(RealTimeEvent event) {} + public void onUserLeftRoom(RealTimeEvent event) {} @EventListener - public void onRoomMemberPromotedToOwner(RealTimeEvent event) {} + public void onRoomMemberPromotedToOwner(RealTimeEvent event) {} @EventListener - public void onRoomMemberDemotedFromOwner(RealTimeEvent event) {} + public void onRoomMemberDemotedFromOwner(RealTimeEvent event) {} @EventListener - public void onConnectionRequested(RealTimeEvent event) {} + public void onConnectionRequested(RealTimeEvent event) {} @EventListener - public void onConnectionAccepted(RealTimeEvent event) {} + public void onConnectionAccepted(RealTimeEvent event) {} @EventListener - public void onMessageSuppressed(RealTimeEvent event) {} + public void onMessageSuppressed(RealTimeEvent event) {} @EventListener - public void onSymphonyElementsAction(RealTimeEvent event) {} + public void onSymphonyElementsAction(RealTimeEvent event) {} } ``` @@ -263,22 +270,22 @@ The Core Starter injects services within the Spring application context: ```java @Service public class CoreServices { - + @Autowired private MessageService messageService; - + @Autowired private StreamService streamService; - + @Autowired private UserService userService; - + @Autowired private DatafeedService datafeedService; - + @Autowired private SessionService sessionService; - + @Autowired private ActivityRegistry activityRegistry; } @@ -295,10 +302,10 @@ bdk: :warning: Disabling the datafeed loop will prevent the use of real time event listeners, of slash commands and activities. ## Slash Command -You can easily register a slash command using the `@Slash` annotation. Note that the `CommandContext` is mandatory to -successfully register your command. If not defined, a `warn` message will appear in your application log. Note also that +You can easily register a slash command using the `@Slash` annotation. Note that the `CommandContext` is mandatory to +successfully register your command. If not defined, a `warn` message will appear in your application log. Note also that only beans with scope **singleton** will be scanned. - + ```java @Component public class SlashHello { @@ -315,10 +322,10 @@ public class SlashHello { } ``` By default, the `@Slash` annotation is configured to require bot mention in order to trigger the command. You can override -this value using `@Slash#mentionBot` annotation parameter. +this value using `@Slash#mentionBot` annotation parameter. You can also use slash commands with arguments. To do so, the field `value` of the `@Slash` annotation must have a valid -format as explained in the [Activity API section](../activity-api.md#Slash-command-pattern-format). +format as explained in the [Activity API section](../activity-api.html#Slash-command-pattern-format). If the slash command pattern is valid, you will have to specify all slash arguments as method parameter with the same name and type. If slash command pattern or method signature is incorrect, a `warn` message will appear in your application log and the slash command will not be registered. Note that the event timestamp is accessible from the `commandContext` using @@ -363,43 +370,18 @@ public class SlashHello { :information_source: Slash commands are not registered to the datahose loop even when enabled. -## Asynchronous slash Command -By default, `@Slash` annotation is configured to be synchronous. If the process takes time, the next incoming commands -will be blocked and enqueued till the process is released. If this is a concern, Slash command can be configured to be -asynchronous by setting the `async` option to the annotation. - -```java -@Slf4j -@Component -public class AsyncActivity { - - @Autowired - private MessageService messageService; - - @Slash(value = "/async", asynchronous = true) - public void async(CommandContext context) throws InterruptedException { - this.messageService.send(context.getStreamId(), - "I will simulate a heavy process that takes time but this should not block next commands"); - - sleep(30000); - - this.messageService.send(context.getStreamId(), "Heavy async process is done"); - } -} -``` - ## Activities -> For more details about activities, please read the [Activity API reference documentation](../activity-api.md) +> For more details about activities, please read the [Activity API reference documentation](../activity-api.html) -Any service or component class that extends [`FormReplyActivity`](https://javadoc.io/doc/org.finos.symphony.bdk/symphony-bdk-core/latest/com/symphony/bdk/core/activity/form/FormReplyActivity.html) -or [`CommandActivity`](https://javadoc.io/doc/org.finos.symphony.bdk/symphony-bdk-core/latest/com/symphony/bdk/core/activity/command/CommandActivity.html) +Any service or component class that extends [`FormReplyActivity`](https://javadoc.io/doc/org.finos.symphony.bdk/symphony-bdk-core/latest/com/symphony/bdk/core/activity/form/FormReplyActivity.html) +or [`CommandActivity`](https://javadoc.io/doc/org.finos.symphony.bdk/symphony-bdk-core/latest/com/symphony/bdk/core/activity/command/CommandActivity.html) will be automatically registered within the [ActivityRegistry](https://javadoc.io/doc/org.finos.symphony.bdk/symphony-bdk-core/latest/com/symphony/bdk/core/activity/ActivityRegistry.html). :information_source: Activities are not registered to the datahose loop even when enabled. ### Example of a `CommandActivity` in Spring Boot -The following example has been described in section [Activity API documentation](../activity-api.md#how-to-create-a-command-activity). -Note here that with Spring Boot you simply have to annotate your `CommandActivity` class with `@Component` to make it +The following example has been described in section [Activity API documentation](../activity-api.html#how-to-create-a-command-activity). +Note here that with Spring Boot you simply have to annotate your `CommandActivity` class with `@Component` to make it automatically registered in the `ActivityRegistry`, ```java @Slf4j @@ -424,7 +406,7 @@ public class HelloCommandActivity extends CommandActivity { ``` ### Example of a `FormReplyActivity` in Spring Boot -The following example demonstrates how to send an Elements form on `@BotMention /gif` slash command. The Elements form +The following example demonstrates how to send an Elements form on `@BotMention /gif` slash command. The Elements form located in `src/main/resources/templates/gif.ftl` contains: ```xml @@ -477,8 +459,8 @@ public class GifFormActivity extends FormReplyActivity { # Integration Test -You can then create the integration test to guarantee the Bot application is working as design, -like you can see in the example below. For more details, please refer to [test module](../test.md). +You can then create the integration test to guarantee the Bot application is working as design, +like you can see in the example below. For more details, please refer to [test module](../test.html). ```java @SymphonyBdkSpringBootTest(properties = {"bot.id=1", "bot.username=my-bot", "bot.display-name=my bot"}) @@ -501,4 +483,4 @@ public class SimpleSpringAppIntegrationTest { ``` ---- -[Home :house:](../index.md) +[Home :house:](../index.html) diff --git a/docs/spring-boot/spring.md b/docs/spring-boot/spring.md new file mode 100644 index 000000000..9ea75b26d --- /dev/null +++ b/docs/spring-boot/spring.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Spring Boot Starters +nav_order: 20 +has_children: true +has_toc: false +--- + +# Spring Boot Starters +The BDK provides 2 Spring Boot starters to quickly scaffold Spring Boot projects: +- [Core Starter](core-starter.html): For Spring-enabled bots +- [App Starter](app-starter.html): For Extension Apps that require a web server and app authentication diff --git a/docs/stream.md b/docs/stream.md index 3c78177c1..e32112747 100644 --- a/docs/stream.md +++ b/docs/stream.md @@ -1,3 +1,9 @@ +--- +layout: default +title: Stream API +nav_order: 9 +--- + # Stream API The Stream Service is a component at the service layer of the BDK which aims to cover the Streams part of the [REST API documentation](https://developers.symphony.com/restapi/reference#messages-v4). diff --git a/docs/tech/architecture.md b/docs/tech/architecture.md index 349686d1f..60da50038 100644 --- a/docs/tech/architecture.md +++ b/docs/tech/architecture.md @@ -1,7 +1,14 @@ +--- +layout: default +title: Architecture +parent: Tech Appendix +nav_order: 1 +--- + # BDK Architecture Presentation -The Symphony BDK for Java is a multi-module library that uses [Gradle](https://gradle.org/) as build system. +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. +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. @@ -9,38 +16,38 @@ The following diagram aims to give an overview of the different layers and modul ### 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) +all necessary BDK features such as: +- [configuration](../configuration.html) +- [authentication](../authentication.html) +- [datafeed](../datafeed.html) +- [services](../message.html) +- [activity API](../activity-api.html) #### 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) +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.html) to generate API clients and models from official Symphony's [Swagger specifications](https://github.com/finos/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. +> :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)) +- `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 +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: +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: +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://docs.developers.symphony.com/building-extension-applications-on-symphony/building-extension-applications-on-symphony) +- `symphony-bdk-app-spring-boot-starter` that is a foundation for [Extension Applications](https://docs.developers.symphony.com/building-extension-applications-on-symphony/building-extension-applications-on-symphony) backend development diff --git a/docs/tech/compatibility-management.md b/docs/tech/compatibility-management.md index d38773be0..a2ec3a872 100644 --- a/docs/tech/compatibility-management.md +++ b/docs/tech/compatibility-management.md @@ -1,3 +1,10 @@ +--- +layout: default +title: Compatibility +parent: Tech Appendix +nav_order: 3 +--- + # BDK compatibility management You can check our existing change management policy for our HTTP API [here](https://docs.developers.symphony.com/admin-guide/api-change-management). @@ -10,17 +17,17 @@ Using features supported by new APIs will require using recent versions of the B |--------------------|------------------| | 20.9 and before | 2.0.0 | -The supported version of SBE and Agent corresponding to the product version of APIs can be found in +The supported version of SBE and Agent corresponding to the product version of APIs can be found in [Agent compatibilities](https://docs.developers.symphony.com/admin-guide/agent-guide/sbe-x-agent-compatibility-matrix). Rationale of our change management policy is to be backward compatible on existing features -(classes, methods or [configuration](../configuration.md) fields) whenever possible. +(classes, methods or [configuration](../configuration.html) fields) whenever possible. ## Deprecations and breaking changes -For keeping the backward compatibility of the BDK, the BDK api classes will be generated from the xx-api-public-deprecated.yaml +For keeping the backward compatibility of the BDK, the BDK api classes will be generated from the xx-api-public-deprecated.yaml file instead of the normal one. By doing this way, the generated APIs which are deprecated will not be completely removed. -They are only annotated with `@Deprecated`. +They are only annotated with `@Deprecated`. Then, the BDK services which are using these deprecated APIs will be annotated with `@Deprecated` as well. Then the bot developers will be warned that these services are now deprecated and will be removed in the future without having any breaking changes. @@ -40,34 +47,34 @@ Deprecations and subsequent class, method or field removal will all be documente ## BDK services -BDK services is a layer in BDK which are the wrappers of all the REST api endpoints provided by SBE and Agent. -These services provide bot developers a more friendly way to interact with SBE and Agent. -Developers now no more need to precisely create a HTTP call to the endpoint which is now under +BDK services is a layer in BDK which are the wrappers of all the REST api endpoints provided by SBE and Agent. +These services provide bot developers a more friendly way to interact with SBE and Agent. +Developers now no more need to precisely create a HTTP call to the endpoint which is now under mission of the BDK services layer. -The BDK services relies on the many APIs classes which are generated automatically by Swagger -OpenAPI from several swagger specs files describing all the endpoints provided by SBE/Agent. +The BDK services relies on the many APIs classes which are generated automatically by Swagger +OpenAPI from several swagger specs files describing all the endpoints provided by SBE/Agent. [Symphony-api-spec](https://github.com/finos/symphony-api-spec) ## Symphony-api-spec -Symphony-api-spec is a project that contains the specifications of all the endpoints exposed -by SBE and Agent. +Symphony-api-spec is a project that contains the specifications of all the endpoints exposed +by SBE and Agent. These specifications are divided into 4 major parts: agent, pod, authenticator, login. -Each part contains 2 files: +Each part contains 2 files: * xx-api-public.yaml : contains the information of the endpoints which are currently active on SBE/Agent. * xx-api-public-deprecated.yaml : a superset of the xx-api-public.yaml which contain the information of all the endpoints which are both active and deprecated on SBE/Agent. -The Api classes in BDK will be generated from these specifications and then be used in BDK services and +The Api classes in BDK will be generated from these specifications and then be used in BDK services and BDK authenticator (a special BDK service). ## BDK compatibility based on the version of Symphony-api-spec -Because the BDK used the Symphony-api-spec for generating the Api classes, then the compatibility between -BDK and SBE/Agent will depend on the version of Symphony-api-spec that the BDK is using and the compatibility between +Because the BDK used the Symphony-api-spec for generating the Api classes, then the compatibility between +BDK and SBE/Agent will depend on the version of Symphony-api-spec that the BDK is using and the compatibility between the specs and the SBE/Agent. -From the official version 2.0.0 of the BDK, we start using the version branch of the Symphony-api-spec +From the official version 2.0.0 of the BDK, we start using the version branch of the Symphony-api-spec (20.9 for the BDK 2.0.0), it means that the version of the BDK will compatible with the product version 20.9.0. diff --git a/docs/tech/production-readiness.md b/docs/tech/production-readiness.md index 04bae06ca..53d588ffd 100644 --- a/docs/tech/production-readiness.md +++ b/docs/tech/production-readiness.md @@ -1,13 +1,20 @@ +--- +layout: default +title: Production Readiness +parent: Tech Appendix +nav_order: 2 +--- + # Production Readiness Production readiness documentation for BDK-based applications. ## Logging The Symphony BDK sets up your logger [MDC](http://logback.qos.ch/manual/mdc.html) (Mapped Diagnostic Context) with a value called `X-Trace-Id` (random alphanumeric string of 6 characters). This value is send as header of every request made to -the Symphony API. This is especially useful for cross-applications debugging, assuming that the `X-Trace-Id` value is +the Symphony API. This is especially useful for cross-applications debugging, assuming that the `X-Trace-Id` value is also present in your application logs. -As you are obviously free to use your preferred logging technology, the next sections will help you to print the +As you are obviously free to use your preferred logging technology, the next sections will help you to print the `X-Trace-Id` using either [logback](http://logback.qos.ch/) or [Log4j2](https://logging.apache.org/log4j/2.x/). ### Logback @@ -28,7 +35,7 @@ For [logback](http://logback.qos.ch/), you will print the `X-Trace-Id` value by ``` ### Log4j2 -For [Log4j2](https://logging.apache.org/log4j/2.x/), you will print the `X-Trace-Id` value by adding `%X{X-Trace-Id}` to +For [Log4j2](https://logging.apache.org/log4j/2.x/), you will print the `X-Trace-Id` value by adding `%X{X-Trace-Id}` to your log pattern: ```xml @@ -46,4 +53,4 @@ your log pattern: ``` ---- -[Home :house:](../index.md) +[Home :house:](../index.html) diff --git a/docs/tech/tech.md b/docs/tech/tech.md new file mode 100644 index 000000000..1ba5bed01 --- /dev/null +++ b/docs/tech/tech.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Tech Appendix +nav_order: 21 +has_children: true +has_toc: false +--- + +# Tech Appendix +- [Architecture](architecture.html) +- [Production Readiness](production-readiness.html) +- [Compatibility Management](compatibility-management.html) diff --git a/docs/test.md b/docs/test.md index f9cb2fd9e..ef2b32b84 100644 --- a/docs/test.md +++ b/docs/test.md @@ -1,115 +1,22 @@ +--- +layout: default +title: Integration Tests +nav_order: 19 +--- + # Symphony BDK Test This guide provides information to Symphony BDK Bot developers about how using Symphony BDK Test to build the integration tests for the Bots. -## Java BDK Bots Integration tests - -To create an integration test for a Java BDK Bot application, developer needs to add annotation `@SymphonyBdkTest` on top -of the test class. This annotation has three properties `botId`, `botName`, and `botDisplayName`, developer can choose -appropriate values per requirement, otherwise the default values are used. - -```java -long botId() default 1L; - -String botName() default "bdk-bot"; - -String botDisplayName() default "BDK Bot"; -``` - -The annotation automatically brings the `Mockito` as well as `SymphonyBdkExtension` Junit extensions in the test, which will -initialise a `SymphonyBdk` mock instance, through `SymphonyBdk`, developer can get all BDK services, please remember all -services are simply **Mockito** mocked objects. Take the simple example below, - -```java - -@SymphonyBdkTest -public class SampleBdkIntegrationTest { - private final V4User initiator = new V4User().displayName("user").userId(2L); - private final V4Stream stream = new V4Stream().streamId("my-room"); - - private SymphonyBdk bdk; - - @Test - @DisplayName("Reply upon received gif category form reply, inject bdk as property") - void gif_form_replyWithMessage() { - - bdk.activities().register(new GifFormActivity(bdk.messages())); - // given - when(bdk.messages().send(anyString(), anyString())).thenReturn(mock(V4Message.class)); - - // when - Map values = new HashMap<>(); - values.put("action", "submit"); - values.put("category", "bdk"); - pushEventToDataFeed(new V4Event().id("id").timestamp(Instant.now().toEpochMilli()) - .initiator(new V4Initiator().user(initiator)) - .payload(new V4Payload().symphonyElementsAction( - new V4SymphonyElementsAction().formId("gif-category-form") - .formMessageId("form-message-id") - .formValues(values) - .stream(stream))) - .type(SymphonyBdkTestUtils.V4EventType.SYMPHONYELEMENTSACTION.name())); - - // then - verify(bdk.messages()).send(eq("my-room"), contains("Gif category is \"bdk\"")); - } -} -``` - -in this example, the goal is to validate the `GifFormActivity`, it is expecting to have a message sent back to the room, -when a `gif-category-form` reply has received. - -**Step 1**. As shown, a `SymphonyBdk` mock instance is inject as test class property. - -**Step 2**. Register the being tested form activity through BDK activity service. - -**Step 3**. Stub the injected mocked bdk messages service, - -**Step 4**. Inject the form reply event through `SymphonyBdkTestUtils.java`, - -**Step 5**. at the end we verify that a replied message has been sent back to the room through bdk messages service. - - -The `SymphonyBdk` instance can also be injected as test method argument, like shown in the example below. - -```java - -@SymphonyBdkTest -public class SampleBdkIntegrationTest { - private final V4User initiator = new V4User().displayName("user").userId(2L); - private final V4Stream stream = new V4Stream().streamId("my-room"); - - @Test - @DisplayName("Reply echo slash command, inject bdk as parameter") - void testEchoSlashCommand(SymphonyBdk bdk) { - final SlashCommand slashCommand = SlashCommand.slash("/echo {argument}", - false, - context -> bdk.messages() - .send(context.getStreamId(), - String.format( - "Received argument: %s", - context.getArguments() - .get("argument"))), - "echo slash command"); - bdk.activities().register(slashCommand); - - // given - when(bdk.messages().send(anyString(), any(Message.class))).thenReturn(mock(V4Message.class)); - - // when - pushMessageToDF(initiator, stream, "/echo arg"); - - // then - verify(bdk.messages()).send(eq("my-room"), contains("Received argument: arg")); - } -``` +> **Note**: This module is still under construction, currently it only supports SpringBoot based Bots, we are going to +> provide the same support for java based Bots very soon. ## SpringBoot based Bots Integration tests -To create an integration test for an SpringBoot based Bot application, developer needs to add the -annotation `@SymphonyBdkSpringBootTest` on top of the test class, when the test is launched, a SpringBoot application -context is going to be loaded, all BDK services are being injected in this application context. +To create an integration test, all developer needs is to add the annotation `@SymphonyBdkSpringBootTest` on top of the +test class, when the test is launched, a SpringBoot application context is going to be loaded, all BDK services are +being injected in this application context. Developer can then `@Autowired` these BDK services beans whenever they are needed in the test, please note that these services beans are simply **Mockito** mocked objects, they have to be stubbed just like the way how we do in a simple @@ -118,7 +25,7 @@ JUnit test. The annotation `@SymphonyBdkSpringBootTest` comes with a properties array attribute, which allows to define the Bot information, such as `bot.id`, `bot.username`, and `bot.display-name`, the additional SpringBoot Bot application properties can also be provided in this array (Another option is to use a YAML configuration file, please see the next -paragraph). By default, this array value is `"bot.id=1", "bot.username=bdk-bot", "bot.display-name=BDK Bot"`. +paragraph). The test annotated with `@SymphonyBdkSpringBootTest` is automatically marked under SpringBoot `integration-test` profile, so developer can @@ -140,11 +47,7 @@ public class SampleSpringAppIntegrationTest { private final V4Stream stream = new V4Stream().streamId("my-room"); @Test - void echo_command_replyWithMessage( - @Autowired - MessageService messageService, - @Autowired - UserV2 botInfo) { + void echo_command_replyWithMessage(@Autowired MessageService messageService, @Autowired UserV2 botInfo) { // (1) given when(messageService.send(anyString(), any(Message.class))).thenReturn(mock(V4Message.class)); @@ -171,8 +74,7 @@ message has received. The `@SymphonyBdkSpringBootTest` annotation is inheritable. Developers may have one parent test class with this annotation, so that the child test classes will inherit the annotation and its properties. -## Symphony Bdk Test Utils - +### Utils The `SymphonyBdkTestUtils.java` is a very handy helper class allowing to inject Symphony events to the DataFeed, so that the registered activities and slash commands should react on these received events. @@ -195,19 +97,19 @@ This util class comes with six methods so far, ```java void test(){ - ... - ... - pushEventToDataFeed(new V4Event() + ... + ... + pushEventToDataFeed(new V4Event() .initiator(new V4Initiator().user(initiator)) .payload(new V4Payload().symphonyElementsAction( - new V4SymphonyElementsAction().formId("gif-category-form") - .formMessageId("form-message-id") - .formValues(values) - .stream(stream))) + new V4SymphonyElementsAction().formId("gif-category-form") + .formMessageId("form-message-id") + .formValues(values) + .stream(stream))) .type(V4EventType.SYMPHONYELEMENTSACTION.name())); - } +} ``` ---- -[Home :house:](./index.md) - +[Home :house:](./index.html) + diff --git a/docs/user.md b/docs/user.md index 51abaa290..a5b99e6c1 100644 --- a/docs/user.md +++ b/docs/user.md @@ -1,3 +1,9 @@ +--- +layout: default +title: User API +nav_order: 10 +--- + # User API The User Service is a component at the service layer of the BDK which covers the User part of the [REST API documentation](https://developers.symphony.com/restapi/reference). More precisely: