messages);
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/java/com/backbase/example/model/Message.java b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/java/com/backbase/example/model/Message.java
new file mode 100644
index 0000000..da04568
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/java/com/backbase/example/model/Message.java
@@ -0,0 +1,43 @@
+package com.backbase.example.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import jakarta.annotation.Generated;
+import jakarta.validation.constraints.NotNull;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@Generated("org.jsonschema2pojo")
+@JsonPropertyOrder({
+ "messageId",
+ "message"
+})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Message {
+
+ @JsonProperty("messageId")
+ @NotNull
+ private String messageId;
+
+ @JsonProperty("message")
+ @NotNull
+ private String message;
+
+ public String getMessageId() {
+ return messageId;
+ }
+
+ public void setMessageId(String messageId) {
+ this.messageId = messageId;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/application.yaml b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/application.yaml
new file mode 100644
index 0000000..9b286a6
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/application.yaml
@@ -0,0 +1,27 @@
+server:
+ port: 9915
+
+# API Registry client configuration
+eureka:
+ instance:
+ metadata-map:
+ public: true
+ role: live
+ client:
+ serviceUrl:
+ defaultZone: http://localhost:8080/registry/eureka/
+
+# Configure Internal JWT handler
+sso:
+ jwt:
+ internal:
+ signature:
+ key:
+ type: ENV
+ value: SIG_SECRET_KEY
+
+# Spring health monitoring
+management:
+ health:
+ jms:
+ enabled: false
\ No newline at end of file
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/banner.txt b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/banner.txt
new file mode 100644
index 0000000..3e84197
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/banner.txt
@@ -0,0 +1,9 @@
+ ________ ________ ________ ___ __ ________ ________ ________ _______
+|\ __ \|\ __ \|\ ____\|\ \|\ \ |\ __ \|\ __ \|\ ____\|\ ___ \
+\ \ \|\ /\ \ \|\ \ \ \___|\ \ \/ /|\ \ \|\ /\ \ \|\ \ \ \___|\ \ __/|
+ \ \ __ \ \ __ \ \ \ \ \ ___ \ \ __ \ \ __ \ \_____ \ \ \_|/__
+ \ \ \|\ \ \ \ \ \ \ \____\ \ \\ \ \ \ \|\ \ \ \ \ \|____|\ \ \ \_|\ \
+ \ \_______\ \__\ \__\ \_______\ \__\\ \__\ \_______\ \__\ \__\____\_\ \ \_______\
+ \|_______|\|__|\|__|\|_______|\|__| \|__|\|_______|\|__|\|__|\_________\|_______|
+ \|_________|
+
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/bootstrap.yaml b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/bootstrap.yaml
new file mode 100644
index 0000000..4212129
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/main/resources/bootstrap.yaml
@@ -0,0 +1,3 @@
+spring:
+ application:
+ name: example-integration-service
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/test/java/com/backbase/example/ExampleControllerIT.java b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/test/java/com/backbase/example/ExampleControllerIT.java
new file mode 100644
index 0000000..f4015a3
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-service/src/test/java/com/backbase/example/ExampleControllerIT.java
@@ -0,0 +1,74 @@
+package com.backbase.example;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.backbase.buildingblocks.testutils.TestTokenUtil;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.annotation.DirtiesContext.ClassMode;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultActions;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+
+/**
+ * A wrapper annotation for use with integration tests.
+ *
+ * By default, assumes the integration test modifies the {@link ApplicationContext} associated with the test/s and will
+ * therefore be closed and removed from the context cache at the end of the class.
+ */
+@SpringBootTest(classes = Application.class)
+@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
+@AutoConfigureMockMvc
+@ActiveProfiles("it")
+public class ExampleControllerIT {
+
+ public static final String TEST_JWT =
+ "{\n"
+ + " \"Role\" : [\n"
+ + " \"Manager\",\n"
+ + " \"Project Administrator\"\n"
+ + " ],\n"
+ + " \"inuid\" : \"Jimmy\",\n"
+ + " \"aud\" : \"www.example.com\",\n"
+ + " \"sub\" : \"jrocket@example.com\",\n"
+ + " \"Email\" : \"jrocket@example.com\",\n"
+ + " \"iss\" : \"Online JWT Builder\",\n"
+ + " \"GivenName\" : \"Johnny\",\n"
+ + " \"exp\" : 1516356196,\n"
+ + " \"iat\" : 1484820196,\n"
+ + " \"Surname\" : \"Rocket\"\n"
+ + "}";
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void exampleTest() throws Exception {
+ MockHttpServletRequestBuilder requestBuilder = get("/client-api/v1/all-messages")
+ .header("Authorization", "Bearer "+TestTokenUtil.encode(TEST_JWT));
+
+ ResultActions result = mvc.perform(requestBuilder);
+
+ // Then the request is successful
+ result.andExpect(status().isOk());
+
+ List message = new ObjectMapper()
+ .readValue(result.andReturn().getResponse().getContentAsString(),
+ new TypeReference<>() {
+ });
+
+ assertThat(message).isNotEmpty();
+ assertThat(message.get(0).getMessage()).isNotNull();
+ assertThat(message.get(0).getId()).isNotNull();
+ }
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/README.md b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/README.md
new file mode 100644
index 0000000..5a9c77a
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/README.md
@@ -0,0 +1,25 @@
+# Example Integration Service API Spec
+
+> _Fill out this file with some information about your OpenAPI spec._
+
+To build this spec, use:
+```
+mvn clean install
+```
+
+The spec is also validated as part of the build.
+
+## Community Documentation
+
+Add links to documentation including setup, config, etc.
+
+##Jira Project
+
+Add link to Jira project.
+
+## Confluence Links
+Links to relevant confluence pages (design etc).
+
+## Support
+
+Slack, Email, Jira etc.
\ No newline at end of file
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/pom.xml b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/pom.xml
new file mode 100644
index 0000000..dbc916b
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/pom.xml
@@ -0,0 +1,97 @@
+
+
+ 4.0.0
+
+
+ com.backbase.buildingblocks
+ backbase-openapi-spec-starter-parent
+ 16.0.0
+
+
+ com.backbase.poc
+ example-integration-openapi-spec
+ 1.0.0-SNAPSHOT
+ Backbase :: Example Integration Service API Spec
+
+
+
+ 0.17.5
+
+
+
+
+
+ com.backbase.oss
+ boat-maven-plugin
+ ${boat-maven-plugin.version}
+
+
+ boat-validation
+ generate-sources
+
+ validate
+
+
+ ${project.basedir}/src/main/resources/client-api-v1.yaml
+ true
+
+
+
+
+ boat-bundle
+ generate-sources
+
+ bundle
+
+
+ ${project.basedir}/src/main/resources
+
+ true
+
+
+
+
+ boat-bundle-unversioned
+ generate-sources
+
+ bundle
+
+
+ ${project.basedir}/src/main/resources
+
+ false
+
+
+
+ boat-linting
+ package
+
+ lint
+
+
+ ${project.build.directory}
+
+ true
+ true
+ 219,215,218,115,134,104,105,110,176,M011,151,S007,S005,B013,H001
+
+
+
+ boat-docs
+ package
+
+ generate
+
+
+ ${project.build.directory}/unversioned/client-api-v1.yaml
+
+ html2
+ true
+
+
+
+
+
+
+
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/client-api-v1.yaml b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/client-api-v1.yaml
new file mode 100644
index 0000000..297e773
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/client-api-v1.yaml
@@ -0,0 +1,169 @@
+openapi: 3.0.3
+info:
+ title: Message Service API Spec
+ description: Specs for Message Service API
+ version: 1.0.0
+ x-icon: credit_card
+
+servers:
+ - description: local test
+ url: http://localhost:8080/api/v1
+
+tags:
+ - name: Retail
+
+paths:
+
+ /client-api/v1/messages:
+ description: No description available
+
+ get:
+ summary: Returns available items, optionally filtered by name.
+ description: Returns available items, optionally filtered by name
+ operationId: getMessage
+ parameters:
+ - description: Id of the message record
+ example: a5b0fe7d-c4dd-40a7-bd80-dfc7869327e1
+ in: query
+ name: id
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ content:
+ application/json:
+ example:
+ $ref: examples/body/example-message.json
+ schema:
+ $ref: '#/components/schemas/Message'
+ description: No description available
+ '400':
+ $ref: 'lib/common-types.yaml#/components/responses/400BadRequest'
+ '500':
+ $ref: 'lib/common-types.yaml#/components/responses/500InternalServerError'
+ tags:
+ - message
+
+ delete:
+ summary: Delete message.
+ description: Deletes a message
+ operationId: deleteMessage
+ parameters:
+ - description: Id of the message record
+ example: a5b0fe7d-c4dd-40a7-bd80-dfc7869327e1
+ in: query
+ name: id
+ required: true
+ schema:
+ type: string
+ responses:
+ '204':
+ description: request to delete completed
+ '400':
+ $ref: 'lib/common-types.yaml#/components/responses/400BadRequest'
+ '500':
+ $ref: 'lib/common-types.yaml#/components/responses/500InternalServerError'
+ tags:
+ - message
+
+ post:
+ summary: Adds or updates a message.
+ description: Adds or updates a message
+ operationId: postMessage
+ requestBody:
+ content:
+ application/json:
+ example:
+ $ref: examples/body/example-message.json
+ schema:
+ $ref: '#/components/schemas/Message'
+ description: Adds or updates a message
+ responses:
+ '201':
+ content:
+ application/json:
+ example:
+ $ref: examples/body/example-message-created.json
+ schema:
+ $ref: '#/components/schemas/MessagePostResponseBody'
+ description: request to create item accepted
+ '400':
+ $ref: 'lib/common-types.yaml#/components/responses/400BadRequest'
+ '500':
+ $ref: 'lib/common-types.yaml#/components/responses/500InternalServerError'
+ tags:
+ - message
+
+ put:
+ summary: Adds or updates a message.
+ description: Adds or updates a message
+ operationId: putMessage
+ requestBody:
+ content:
+ application/json:
+ example:
+ $ref: examples/body/example-message.json
+ schema:
+ $ref: '#/components/schemas/Message'
+ description: Adds or updates a message
+ responses:
+ '204':
+ description: request to update item completed
+ '400':
+ $ref: 'lib/common-types.yaml#/components/responses/400BadRequest'
+ '500':
+ $ref: 'lib/common-types.yaml#/components/responses/500InternalServerError'
+ tags:
+ - message
+
+ /client-api/v1/all-messages:
+ summary: messages
+ description: No description available
+ get:
+ summary: Returns all available messages.
+ description: Returns all available messages
+ operationId: getMessages
+ responses:
+ '200':
+ content:
+ application/json:
+ example:
+ $ref: examples/body/example-messages-get.json
+ schema:
+ $ref: '#/components/schemas/MessagesGetResponseBody'
+ description: No description available
+ '400':
+ $ref: 'lib/common-types.yaml#/components/responses/400BadRequest'
+ '500':
+ $ref: 'lib/common-types.yaml#/components/responses/500InternalServerError'
+ tags:
+ - message
+
+components:
+ schemas:
+ ErrorItem:
+ $ref: 'lib/schemas/error-item.yaml'
+ Message:
+ $ref: schemas/body/message.json
+ MessagesGetResponseBody:
+ $ref: schemas/body/messages-get.json
+ MessagePostResponseBody:
+ $ref: schemas/body/message-created.json
+ NotAcceptableError:
+ properties:
+ message:
+ type: string
+ supportedMediaTypes:
+ description: List of supported media types for this endpoint
+ items:
+ type: string
+ type: array
+ type: object
+ UnauthorizedError:
+ properties:
+ message:
+ type: string
+ required:
+ - message
+ type: object
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/docs/api.md b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/docs/api.md
new file mode 100644
index 0000000..3365a26
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/docs/api.md
@@ -0,0 +1,7 @@
+# Example Persistence Service API Spec API Documentation
+
+Currently the Example Persistence Service API Spec API contains the following operations:
+* Create an item or Update an item
+* Get an item by ID
+* Get list of items, optionally filtering by name
+* Delete item
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-message-created.json b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-message-created.json
new file mode 100644
index 0000000..66dc6ed
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-message-created.json
@@ -0,0 +1,3 @@
+{
+ "id": "a5b0fe7d-c4dd-40a7-bd80-dfc7869327e1"
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-message.json b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-message.json
new file mode 100644
index 0000000..03564aa
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-message.json
@@ -0,0 +1,4 @@
+{
+ "id": "a5b0fe7d-c4dd-40a7-bd80-dfc7869327e1",
+ "message": "Hello"
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-messages-get.json b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-messages-get.json
new file mode 100644
index 0000000..bfcbcd8
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/body/example-messages-get.json
@@ -0,0 +1,14 @@
+[
+ {
+ "id": "a5b0fe7d-c4dd-40a7-bd80-dfc7869327e1",
+ "message": "Hello"
+ },
+ {
+ "id": "d593c212-70ad-41a6-a547-d5d9232414cb",
+ "message": "Hola"
+ },
+ {
+ "id": "9635966b-28e9-4479-8121-bb7bc9beeb62",
+ "message": "hej"
+ }
+]
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/errors/example-error.json b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/errors/example-error.json
new file mode 100644
index 0000000..2904b69
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/examples/errors/example-error.json
@@ -0,0 +1,3 @@
+{
+ "message": "Description of error"
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/message-created.json b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/message-created.json
new file mode 100644
index 0000000..0f30393
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/message-created.json
@@ -0,0 +1,8 @@
+{
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ }
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/message.json b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/message.json
new file mode 100644
index 0000000..74fd94d
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/message.json
@@ -0,0 +1,15 @@
+{
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id",
+ "message"
+ ]
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/messages-get.json b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/messages-get.json
new file mode 100644
index 0000000..00778c9
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/body/messages-get.json
@@ -0,0 +1,6 @@
+{
+ "type": "array",
+ "items": {
+ "$ref": "message.json"
+ }
+}
diff --git a/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/errors/error.json b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/errors/error.json
new file mode 100644
index 0000000..5c30948
--- /dev/null
+++ b/service-sdk/18.0.0/create-outbound-integration-service-openapi/example-integration-openapi-spec/src/main/resources/schemas/errors/error.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message"
+ ]
+}
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/README.md b/service-sdk/18.0.0/include-persistence-crud-service-specification/README.md
new file mode 100644
index 0000000..683d59b
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/README.md
@@ -0,0 +1,4 @@
+This project contains code samples documented in the following sections in [Backbase Community](https://community.backbase.com/documentation/ServiceSDK/latest/index):
+
+* [Create a service specification with persistence capabilities](https://community.backbase.com/documentation/ServiceSDK/latest/create_a_persistence_crud_service_specification)
+* [Enable service to service communications](https://community.backbase.com/documentation/ServiceSDK/latest/service_to_service_communication)
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/README.md b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/README.md
new file mode 100644
index 0000000..a9d8810
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/README.md
@@ -0,0 +1,25 @@
+# example-service
+
+_Fill out this file with some information about your Service._
+
+## Dependencies
+
+Requires a running Eureka registry, by default on port 8080.
+
+## Configuration
+
+Service configuration is under `src/main/resources/application.yaml`.
+
+## Running
+
+To run the service in development mode, use:
+- `mvn spring-boot:run`
+
+To run the service from the built binaries, use:
+- `java -jar target/example-service-1.0.0-SNAPSHOT.jar`
+
+## Authorization
+
+Requests to this service are authorized with a Backbase Internal JWT, therefore you must access this service via the Backbase Gateway after authenticating with the authentication service.
+
+For local development, an internal JWT can be created from http://jwt.io, entering ```JWTSecretKeyDontUseInProduction!``` as the secret in the signature to generate a valid signed JWT.
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/pom.xml b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/pom.xml
new file mode 100644
index 0000000..516509b
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/pom.xml
@@ -0,0 +1,155 @@
+
+
+ 4.0.0
+
+
+
+ service-sdk-starter-core
+ com.backbase.buildingblocks
+ 16.0.0
+
+
+
+ com.backbase.example
+ example-crud-service
+ 1.0.0-SNAPSHOT
+ Backbase :: Digital Banking Services :: example-crud-service
+
+
+ 17
+ 0.17.0
+ true
+
+
+
+
+ io.swagger.core.v3
+ swagger-annotations
+
+
+
+ org.openapitools
+ jackson-databind-nullable
+
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+
+ io.springfox
+ springfox-core
+ 3.0.0
+
+
+
+
+ com.backbase.buildingblocks
+ persistence
+
+
+
+ com.backbase.buildingblocks
+ service-sdk-starter-mapping
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+
+ com.h2database
+ h2
+ 1.4.200
+ test
+
+
+
+ com.mysql
+ mysql-connector-j
+ test
+
+
+
+
+ com.backbase.buildingblocks
+ service-sdk-starter-test
+ test
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ unpack
+ generate-sources
+
+ unpack
+
+
+
+
+ com.backbase.message
+ messaging-api
+ 1.0.0-SNAPSHOT
+ api
+ ${project.build.directory}/yaml
+ zip
+ true
+
+
+ **/*.yaml, **/*.json
+
+
+
+
+
+
+ com.backbase.oss
+ boat-maven-plugin
+ ${boat-maven-plugin.version}
+
+
+
+ generate-client-api-code
+
+ generate-spring-boot-embedded
+
+ generate-sources
+
+ ${project.build.directory}/yaml/messaging-api/client-api-v1.0.0.yaml
+ com.backbase.service.example.rest.spec.v1
+ com.backbase.service.example.rest.spec.v1.model
+
+
+
+
+
+
+
+
+
+
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/Application.java b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/Application.java
new file mode 100644
index 0000000..5e8d2f0
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/Application.java
@@ -0,0 +1,20 @@
+package com.backbase.example;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableJpaRepositories
+@EntityScan
+public class Application extends SpringBootServletInitializer {
+
+ public static void main(final String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
\ No newline at end of file
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/ExampleController.java b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/ExampleController.java
new file mode 100644
index 0000000..3a2c7e2
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/ExampleController.java
@@ -0,0 +1,60 @@
+package com.backbase.example;
+
+import com.backbase.example.domain.Greeting;
+import com.backbase.example.mapper.GreetingsMapper;
+import com.backbase.example.service.GreetingsService;
+import com.backbase.service.example.rest.spec.v1.MessageApi;
+import com.backbase.service.example.rest.spec.v1.model.Message;
+import com.backbase.service.example.rest.spec.v1.model.MessagePostResponseBody;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+public class ExampleController implements MessageApi {
+
+ @Autowired
+ private GreetingsService greetingsService;
+
+ @Override
+ public ResponseEntity deleteMessage(String id) {
+ Greeting greeting = greetingsService.getGreetingById(id);
+ greetingsService.deleteGreeting(greeting);
+
+ return ResponseEntity.noContent().build();
+ }
+
+ @Override
+ public ResponseEntity getMessage(String id) {
+ Greeting greeting = greetingsService.getGreetingById(id);
+
+ return ResponseEntity.ok(GreetingsMapper.INSTANCE.greetingToMessage(greeting));
+ }
+
+ @Override
+ public ResponseEntity> getMessages() {
+ List greetings = greetingsService.getGreetings();
+
+ return ResponseEntity.ok(GreetingsMapper.INSTANCE.greetingsToMessages(greetings));
+ }
+
+ @Override
+ public ResponseEntity postMessage(Message message) {
+ Greeting greeting = GreetingsMapper.INSTANCE.messageToGreeting(message);
+ greetingsService.saveGreeting(greeting);
+
+ return ResponseEntity.status(HttpStatus.CREATED).body(new MessagePostResponseBody().id(greeting.getId()));
+ }
+
+ @Override
+ public ResponseEntity putMessage(Message message) {
+ Greeting greeting = greetingsService.getGreetingById(message.getId());
+ greeting.setMessage(message.getMessage());
+ greetingsService.saveGreeting(greeting);
+
+ return ResponseEntity.noContent().build();
+ }
+}
\ No newline at end of file
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/domain/Greeting.java b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/domain/Greeting.java
new file mode 100644
index 0000000..01bc7fd
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/domain/Greeting.java
@@ -0,0 +1,31 @@
+package com.backbase.example.domain;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "greetings")
+public class Greeting {
+
+ @Id
+ @Column(name = "id")
+ private String id;
+
+ @Column(name = "message")
+ private String message;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/mapper/GreetingsMapper.java b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/mapper/GreetingsMapper.java
new file mode 100644
index 0000000..67e7c71
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/mapper/GreetingsMapper.java
@@ -0,0 +1,18 @@
+package com.backbase.example.mapper;
+
+import com.backbase.example.domain.Greeting;
+import com.backbase.service.example.rest.spec.v1.model.Message;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+@Mapper
+public interface GreetingsMapper {
+
+ GreetingsMapper INSTANCE = Mappers.getMapper( GreetingsMapper.class);
+
+ Message greetingToMessage(Greeting greeting);
+ List greetingsToMessages(List greetings);
+ Greeting messageToGreeting(Message message);
+}
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/repository/GreetingsRepository.java b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/repository/GreetingsRepository.java
new file mode 100644
index 0000000..1511c66
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/repository/GreetingsRepository.java
@@ -0,0 +1,14 @@
+package com.backbase.example.repository;
+
+import com.backbase.example.domain.Greeting;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface GreetingsRepository extends CrudRepository {
+
+ @Override
+ List findAll();
+}
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/service/GreetingsService.java b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/service/GreetingsService.java
new file mode 100644
index 0000000..3dc72f7
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/service/GreetingsService.java
@@ -0,0 +1,16 @@
+package com.backbase.example.service;
+
+import com.backbase.example.domain.Greeting;
+
+import java.util.List;
+
+public interface GreetingsService {
+
+ List getGreetings();
+
+ Greeting getGreetingById(String id);
+
+ void saveGreeting(Greeting greeting);
+
+ void deleteGreeting(Greeting greeting);
+}
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/service/GreetingsServiceImpl.java b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/service/GreetingsServiceImpl.java
new file mode 100644
index 0000000..39ebe0a
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/java/com/backbase/example/service/GreetingsServiceImpl.java
@@ -0,0 +1,47 @@
+package com.backbase.example.service;
+
+import com.backbase.example.domain.Greeting;
+import com.backbase.example.repository.GreetingsRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+public class GreetingsServiceImpl implements GreetingsService {
+
+ @Autowired
+ private GreetingsRepository greetingsRepository;
+
+ @Override
+ @Transactional(readOnly = true)
+ @PreAuthorize("permitAll()")
+ public List getGreetings() {
+ return greetingsRepository.findAll();
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ @PreAuthorize("permitAll()")
+ public Greeting getGreetingById(String id) {
+ return greetingsRepository.findById(id).get();
+ }
+
+ @Override
+ @Transactional
+ @PreAuthorize("permitAll()")
+ public void saveGreeting(Greeting greeting) {
+ greetingsRepository.save(greeting);
+ }
+
+ @Override
+ @Transactional
+ @PreAuthorize("permitAll()")
+ public void deleteGreeting(Greeting greeting) {
+ greetingsRepository.delete(greeting);
+ }
+
+
+}
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/application.yaml b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/application.yaml
new file mode 100644
index 0000000..8329b3f
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/application.yaml
@@ -0,0 +1,53 @@
+server:
+ port: 9915
+
+# API Registry client configuration
+eureka:
+ instance:
+ metadata-map:
+ public: true
+ role: live
+ client:
+ serviceUrl:
+ defaultZone: http://localhost:8761/eureka/
+
+# Configure Internal JWT handler
+sso:
+ jwt:
+ internal:
+ signature:
+ key:
+ type: ENV
+ value: SIG_SECRET_KEY
+
+# Spring health monitoring
+management:
+ health:
+ jms:
+ enabled: false
+
+#spring:
+# datasource:
+# url: jdbc:mysql://localhost:3306/greetings
+# username: greetings
+# password: Gr33:t1ngs
+# driver-class-name: com.mysql.cj.jdbc.Driver
+# jpa:
+# database: mysql
+# generate-ddl: false
+spring:
+ h2:
+ console:
+ enabled: true
+ datasource:
+ url: jdbc:h2:mem:greetingsdb
+ jpa:
+ generate-ddl: false
+ liquibase:
+ enabled: true
+ change-log: classpath:/db/changelog.yaml
+
+buildingblocks:
+ security:
+ xss:
+ autoconfig: false
\ No newline at end of file
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/banner.txt b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/banner.txt
new file mode 100644
index 0000000..3e84197
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/banner.txt
@@ -0,0 +1,9 @@
+ ________ ________ ________ ___ __ ________ ________ ________ _______
+|\ __ \|\ __ \|\ ____\|\ \|\ \ |\ __ \|\ __ \|\ ____\|\ ___ \
+\ \ \|\ /\ \ \|\ \ \ \___|\ \ \/ /|\ \ \|\ /\ \ \|\ \ \ \___|\ \ __/|
+ \ \ __ \ \ __ \ \ \ \ \ ___ \ \ __ \ \ __ \ \_____ \ \ \_|/__
+ \ \ \|\ \ \ \ \ \ \ \____\ \ \\ \ \ \ \|\ \ \ \ \ \|____|\ \ \ \_|\ \
+ \ \_______\ \__\ \__\ \_______\ \__\\ \__\ \_______\ \__\ \__\____\_\ \ \_______\
+ \|_______|\|__|\|__|\|_______|\|__| \|__|\|_______|\|__|\|__|\_________\|_______|
+ \|_________|
+
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/bootstrap.yaml b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/bootstrap.yaml
new file mode 100644
index 0000000..3767fe9
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/bootstrap.yaml
@@ -0,0 +1,3 @@
+spring:
+ application:
+ name: example-service
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/db/changelog.yaml b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/db/changelog.yaml
new file mode 100644
index 0000000..1308cf4
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/main/resources/db/changelog.yaml
@@ -0,0 +1,16 @@
+databaseChangeLog:
+- changeSet:
+ id: greetings
+ author: filer
+ changes:
+ - createTable:
+ tableName: GREETINGS
+ columns:
+ - column:
+ constraints:
+ nullable: false
+ name: id
+ type: VARCHAR(36)
+ - column:
+ name: message
+ type: VARCHAR(255)
\ No newline at end of file
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/test/java/com/backbase/example/ExampleControllerIT.java b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/test/java/com/backbase/example/ExampleControllerIT.java
new file mode 100644
index 0000000..a10cf3a
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/test/java/com/backbase/example/ExampleControllerIT.java
@@ -0,0 +1,121 @@
+package com.backbase.example;
+
+
+import com.backbase.service.example.rest.spec.v1.model.Message;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.security.web.csrf.CsrfToken;
+import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.ResultActions;
+import org.springframework.http.MediaType;
+import java.util.UUID;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+
+/**
+ * A wrapper annotation for use with integration tests.
+ *
+ * By default, assumes the integration test modifies the
+ * {@link ApplicationContext} associated with the test/s and will therefore be
+ * closed and removed from the context cache at the end of the class.
+ */
+@SpringBootTest(classes = Application.class)
+@AutoConfigureMockMvc
+@ActiveProfiles("it")
+public class ExampleControllerIT {
+
+ String TOKEN_ATTR_NAME = "org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN";
+
+ public static final String TEST_JWT =
+ "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsIm5hZiI6MTUwNjUyNzQzMSwiY25leHAiOnRydWUsImdycCI6" +
+ "WyJhZG1pbihBRE1JTikiXSwiYW5sb2MiOnRydWUsImFuZXhwIjp0cnVlLCJlbmJsIjp0cnVlLCJleHAiOjE1MDY1" +
+ "MjU5MzEsImlhdCI6MTUwNjUyNTYzMSwicm9sIjpbIlJPTEVfQUNUVUFUT1IiLCJST0xFX0FETUlOIiwiUk9MRV9nc" +
+ "m91cF9hZG1pbihBRE1JTikiXSwianRpIjoiMjQ1MDBkNDQtNDRiZS00MTI1LTg4MjctOWY1NDAwOTc4NmEzIn0.5qZ" +
+ "nncyJpWJ8GqklJK6RmyHUUPddNOh52al65_C4T9o";
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void exampleTest() throws Exception {
+ String greetingsId = givenAGreetingExists();
+ whenWeGetTheMessageByIdThenTheMessageExists(greetingsId);
+ WhenWeGetAllMessagesThenAListOfMessagesIsReturned();
+ }
+
+ private void WhenWeGetAllMessagesThenAListOfMessagesIsReturned() throws Exception {
+ //When: Request for all messages
+ MockHttpServletRequestBuilder getAllMessagesRequestBuilder = get("/client-api/v1/all-messages")
+ .header("Authorization", TEST_JWT);
+
+ ResultActions getAllMessagesResult = mvc.perform(getAllMessagesRequestBuilder).andDo(print());
+
+ // Then the request is successful with a list of messages
+ getAllMessagesResult.andExpect(status().isOk());
+
+ List listOfMessages = new ObjectMapper().readValue(getAllMessagesResult.andReturn().getResponse().getContentAsString(),
+ new TypeReference<>() {});
+
+ assertThat(listOfMessages).isNotEmpty();
+ }
+
+ private void whenWeGetTheMessageByIdThenTheMessageExists(String greetingsId) throws Exception {
+ //When: we get that message
+ MockHttpServletRequestBuilder getMessageRequestBuilder = get("/client-api/v1/messages?id=" + greetingsId)
+ .header("Authorization", TEST_JWT);
+
+ ResultActions result = mvc.perform(getMessageRequestBuilder).andDo(print());
+
+ result = result.andExpect(status().isOk());
+
+ MvcResult response = result.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
+
+ String responseBody = response.getResponse().getContentAsString();
+
+ //Then: the message exists
+ assertThat(responseBody).contains("Hello World").as("ID in response should match ID in request");
+ }
+
+ private String givenAGreetingExists() throws Exception {
+ //Given: a message exists
+ String id = UUID.randomUUID().toString();
+ Message message = new Message();
+ message.setMessage("Hello World is it me your looking for?");
+ message.setId(id);
+
+ String messageAsString = new ObjectMapper().writeValueAsString(message);
+
+ HttpSessionCsrfTokenRepository httpSessionCsrfTokenRepository = new HttpSessionCsrfTokenRepository();
+ CsrfToken csrfToken = httpSessionCsrfTokenRepository.generateToken(new MockHttpServletRequest());
+
+ MockHttpServletRequestBuilder postRequestBuilder = post("/client-api/v1/messages")
+ .header("Authorization", TEST_JWT)
+ .sessionAttr(TOKEN_ATTR_NAME, csrfToken)
+ .param(csrfToken.getParameterName(), csrfToken.getToken())
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(messageAsString);
+
+ ResultActions postResult = mvc.perform(postRequestBuilder).andDo(print());
+
+ postResult.andExpect(status().isCreated());
+
+ Message messagePostResponseBody = new ObjectMapper().readValue(postResult.andReturn().getResponse().getContentAsString(),
+ new TypeReference<>() {});
+ return messagePostResponseBody.getId();
+ }
+}
diff --git a/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/test/resources/application.yaml b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/test/resources/application.yaml
new file mode 100644
index 0000000..6e18db3
--- /dev/null
+++ b/service-sdk/18.0.0/include-persistence-crud-service-specification/example-crud-service/src/test/resources/application.yaml
@@ -0,0 +1,12 @@
+eureka:
+ client:
+ enabled: false
+
+logging:
+ level:
+ ROOT: DEBUG
+
+spring:
+ liquibase:
+ enabled: true
+ change-log: classpath:/db/changelog.yaml
diff --git a/service-sdk/18.0.0/pom.xml b/service-sdk/18.0.0/pom.xml
new file mode 100644
index 0000000..20dedfa
--- /dev/null
+++ b/service-sdk/18.0.0/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ com.backbase.buildingblocks
+ documentation-code-samples
+ 16.0.0
+ pom
+
+
+
+ Backbase Artifact Builds Repository
+ artifacts.backbase.com-builds
+ https://artifacts.backbase.com/staging
+
+
+
+
+ add-persistence-to-service/example-persistence-service
+ create-core-service/example-core-service
+ create-openapi-client/banking-service
+ create-openapi-spec-project/messaging-api
+ create-openapi-spec-project/messaging-service
+ create-outbound-integration-service-openapi/example-integration-openapi-spec
+ create-outbound-integration-service-openapi/example-integration-openapi-service
+ include-persistence-crud-service-specification/example-crud-service
+ service-to-service-communication/example-service-to-service
+
+
+
diff --git a/service-sdk/18.0.0/service-to-service-communication/README.md b/service-sdk/18.0.0/service-to-service-communication/README.md
new file mode 100644
index 0000000..43fefbf
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/README.md
@@ -0,0 +1,3 @@
+This project contains code samples documented in the following section in [Backbase Community](https://community.backbase.com/documentation/ServiceSDK/latest/index):
+
+* [Enable service to service communication](https://community.backbase.com/documentation/ServiceSDK/latest/service_to_service_communication)
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/README.md b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/README.md
new file mode 100644
index 0000000..fe9c1e3
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/README.md
@@ -0,0 +1,25 @@
+# example-service
+
+_Fill out this file with some information about your Service._
+
+## Dependencies
+
+Requires a running Eureka registry, by default on port 8080.
+
+## Configuration
+
+Service configuration is under `src/main/resources/application.yaml`.
+
+## Running
+
+To run the service in development mode, use:
+- `mvn spring-boot:run`
+
+To run the service from the built binaries, use:
+- `java -jar target/example-service-to-service-1.0.0-SNAPSHOT.jar`
+
+## Authorization
+
+Requests to this service are authorized with a Backbase Internal JWT, therefore you must access this service via the Backbase Edge after authenticating with Identity service.
+
+For local development, an internal JWT can be created from http://jwt.io, entering ```JWTSecretKeyDontUseInProduction!``` as the secret in the signature to generate a valid signed JWT.
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/pom.xml b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/pom.xml
new file mode 100644
index 0000000..2cd4e23
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/pom.xml
@@ -0,0 +1,186 @@
+
+
+ 4.0.0
+
+
+
+ service-sdk-starter-core
+ com.backbase.buildingblocks
+ 16.0.0
+
+
+
+ com.backbase.example
+ example-service-to-service
+ 1.0.0-SNAPSHOT
+ Backbase :: Digital Banking Services :: example-service-to-service
+
+
+ 17
+ 3.0.2
+ 0.17.5
+ true
+
+
+
+
+ io.swagger.core.v3
+ swagger-annotations
+
+
+ org.openapitools
+ jackson-databind-nullable
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+ io.springfox
+ springfox-core
+ 3.0.0
+
+
+ com.google.code.findbugs
+ jsr305
+ ${jsr305.version}
+
+
+
+
+
+ com.backbase.buildingblocks
+ auth-security
+
+
+ com.backbase.buildingblocks
+ building-blocks-common
+
+
+ com.backbase.buildingblocks
+ communication
+
+
+
+
+
+ com.backbase.buildingblocks
+ persistence
+
+
+
+ com.backbase.buildingblocks
+ service-sdk-starter-mapping
+
+
+ com.backbase.buildingblocks
+ api
+
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+
+ com.h2database
+ h2
+ 1.4.200
+ test
+
+
+
+ com.mysql
+ mysql-connector-j
+ test
+
+
+
+
+ com.backbase.buildingblocks
+ service-sdk-starter-test
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ unpack
+ generate-sources
+
+ unpack
+
+
+
+
+ com.backbase.message
+ messaging-api
+ 1.0.0-SNAPSHOT
+ api
+ ${project.build.directory}/yaml
+ zip
+ true
+
+
+ com.backbase.poc
+ example-integration-openapi-spec
+ 1.0.0-SNAPSHOT
+ ${project.build.directory}/yaml/example-integration-openapi-spec
+ jar
+ true
+
+
+ **/*.yaml, **/*.json
+
+
+
+
+
+
+ com.backbase.oss
+ boat-maven-plugin
+ ${boat-maven-plugin.version}
+
+
+ generate-client-api-code
+
+ generate-spring-boot-embedded
+
+ generate-sources
+
+ ${project.build.directory}/yaml/messaging-api/client-api-v1.0.0.yaml
+ com.backbase.service.example.rest.spec.v1
+ com.backbase.service.example.rest.spec.v1.model
+
+
+
+
+ generate-integration-client
+
+ generate-rest-template-embedded
+
+ generate-sources
+
+ ${project.build.directory}/yaml/example-integration-openapi-spec/client-api-v1.yaml
+ com.backbase.integration.example.client.v1
+ com.backbase.integration.example.client.v1.model
+ restTemplateBeanName=interServiceRestTemplate
+
+
+
+
+
+
+
+
+
+
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/Application.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/Application.java
new file mode 100644
index 0000000..5e8d2f0
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/Application.java
@@ -0,0 +1,20 @@
+package com.backbase.example;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+@EnableJpaRepositories
+@EntityScan
+public class Application extends SpringBootServletInitializer {
+
+ public static void main(final String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
\ No newline at end of file
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/controller/ExampleController.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/controller/ExampleController.java
new file mode 100644
index 0000000..3744e0a
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/controller/ExampleController.java
@@ -0,0 +1,71 @@
+package com.backbase.example.controller;
+
+import com.backbase.example.domain.Greeting;
+import com.backbase.example.mapper.GreetingsMapper;
+import com.backbase.example.service.GreetingsService;
+import com.backbase.service.example.rest.spec.v1.MessageApi;
+import com.backbase.service.example.rest.spec.v1.model.Message;
+import com.backbase.service.example.rest.spec.v1.model.MessagePostResponseBody;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+public class ExampleController implements MessageApi {
+
+ @Autowired
+ private GreetingsService greetingsService;
+
+ @Override
+ public ResponseEntity deleteMessage(String id) {
+ Greeting greeting = greetingsService.getGreetingById(id);
+ greetingsService.deleteGreeting(greeting);
+
+ return ResponseEntity.noContent().build();
+ }
+
+ @Override
+ public ResponseEntity getMessage(String id) {
+ Greeting greeting = greetingsService.getGreetingById(id);
+
+ return ResponseEntity.ok(GreetingsMapper.INSTANCE.greetingToMessage(greeting));
+ }
+
+ @Override
+ public ResponseEntity postMessage(Message message) {
+ Greeting greeting = GreetingsMapper.INSTANCE.messageToGreeting(message);
+ greetingsService.saveGreeting(greeting);
+
+ return ResponseEntity.status(HttpStatus.CREATED).body(new MessagePostResponseBody().id(greeting.getId()));
+ }
+
+ @Override
+ public ResponseEntity putMessage(Message message) {
+ Greeting greeting = greetingsService.getGreetingById(message.getId());
+ greeting.setMessage(message.getMessage());
+ greetingsService.saveGreeting(greeting);
+
+ return ResponseEntity.noContent().build();
+ }
+
+ @Override
+ public ResponseEntity> getMessages() {
+ List greetings = greetingsService.getGreetings();
+
+ /**
+ *
+ * Example: We could do the following
+ *
+ *
+ * List externalGreetings = greetingsService.getExternalGreetings();
+ * greetings.addAll(externalGreetings);
+ *
+ *
+ * which will make a downstream call to an integration service and merge results with persisted greetings
+ */
+ return ResponseEntity.ok(GreetingsMapper.INSTANCE.greetingsToMessages(greetings));
+ }
+}
\ No newline at end of file
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/domain/Greeting.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/domain/Greeting.java
new file mode 100644
index 0000000..01bc7fd
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/domain/Greeting.java
@@ -0,0 +1,31 @@
+package com.backbase.example.domain;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name = "greetings")
+public class Greeting {
+
+ @Id
+ @Column(name = "id")
+ private String id;
+
+ @Column(name = "message")
+ private String message;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/mapper/GreetingsMapper.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/mapper/GreetingsMapper.java
new file mode 100644
index 0000000..4ca35da
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/mapper/GreetingsMapper.java
@@ -0,0 +1,19 @@
+package com.backbase.example.mapper;
+
+import com.backbase.example.domain.Greeting;
+import com.backbase.service.example.rest.spec.v1.model.Message;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+@Mapper
+public interface GreetingsMapper {
+
+ GreetingsMapper INSTANCE = Mappers.getMapper( GreetingsMapper.class);
+
+ Message greetingToMessage(Greeting greeting);
+ List greetingsToMessages(List greetings);
+ Greeting messageToGreeting(Message message);
+ List integrationMessageToGreeting(List integrationMessages);
+}
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/repository/GreetingsRepository.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/repository/GreetingsRepository.java
new file mode 100644
index 0000000..1511c66
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/repository/GreetingsRepository.java
@@ -0,0 +1,14 @@
+package com.backbase.example.repository;
+
+import com.backbase.example.domain.Greeting;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface GreetingsRepository extends CrudRepository {
+
+ @Override
+ List findAll();
+}
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/GreetingsService.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/GreetingsService.java
new file mode 100644
index 0000000..e214782
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/GreetingsService.java
@@ -0,0 +1,18 @@
+package com.backbase.example.service;
+
+import com.backbase.example.domain.Greeting;
+
+import java.util.List;
+
+public interface GreetingsService {
+
+ List getGreetings();
+ // tag::getExternalGreetings[]
+ List getExternalGreetings();
+ // end::getExternalGreetings[]
+ Greeting getGreetingById(String id);
+
+ void saveGreeting(Greeting greeting);
+
+ void deleteGreeting(Greeting greeting);
+}
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/GreetingsServiceImpl.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/GreetingsServiceImpl.java
new file mode 100644
index 0000000..2b57565
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/GreetingsServiceImpl.java
@@ -0,0 +1,57 @@
+package com.backbase.example.service;
+
+import com.backbase.example.domain.Greeting;
+import com.backbase.example.mapper.GreetingsMapper;
+import com.backbase.example.repository.GreetingsRepository;
+import com.backbase.integration.example.client.v1.MessageApi;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+public class GreetingsServiceImpl implements GreetingsService {
+
+ @Autowired
+ private GreetingsRepository greetingsRepository;
+
+ @Autowired
+ private MessageApi exampleIntegrationApiClient;
+
+ @Override
+ @Transactional(readOnly = true)
+ @PreAuthorize("permitAll()")
+ public List getGreetings() {
+ return greetingsRepository.findAll();
+ }
+
+ // tag::getExternalGreetings[]
+ @Override
+ @Transactional(readOnly = true)
+ @PreAuthorize("permitAll()")
+ public List getExternalGreetings() {
+ return GreetingsMapper.INSTANCE.integrationMessageToGreeting(exampleIntegrationApiClient.getMessages());
+ }
+ // end::getExternalGreetings[]
+
+ @Override
+ @Transactional(readOnly = true)
+ @PreAuthorize("permitAll()")
+ public Greeting getGreetingById(String id) {
+ return greetingsRepository.findById(id).get();
+ }
+
+ @Override
+ @PreAuthorize("permitAll()")
+ public void saveGreeting(Greeting greeting) {
+ greetingsRepository.save(greeting);
+ }
+
+ @Override
+ @PreAuthorize("permitAll()")
+ public void deleteGreeting(Greeting greeting) {
+ greetingsRepository.delete(greeting);
+ }
+}
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/IntegrationApiClientConfig.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/IntegrationApiClientConfig.java
new file mode 100644
index 0000000..84c1811
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/java/com/backbase/example/service/IntegrationApiClientConfig.java
@@ -0,0 +1,25 @@
+package com.backbase.example.service;
+
+import com.backbase.buildingblocks.communication.client.ApiClientConfig;
+import com.backbase.integration.example.client.ApiClient;
+import com.backbase.integration.example.client.v1.MessageApi;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class IntegrationApiClientConfig extends ApiClientConfig {
+
+ public IntegrationApiClientConfig() {
+ super("example-integration-service");
+ }
+
+ @Bean
+ public MessageApi exampleIntegrationApiClient() {
+ return new MessageApi(createaApiClient());
+ }
+
+ private ApiClient createaApiClient() {
+ return new ApiClient(getRestTemplate())
+ .setBasePath(createBasePath());
+ }
+}
\ No newline at end of file
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/application.yaml b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/application.yaml
new file mode 100644
index 0000000..d644517
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/application.yaml
@@ -0,0 +1,57 @@
+server:
+ port: 9915
+
+# API Registry client configuration
+eureka:
+ instance:
+ metadata-map:
+ public: true
+ role: live
+ client:
+ serviceUrl:
+ defaultZone: http://localhost:8761/eureka/
+
+# Configure Internal JWT handler
+sso:
+ jwt:
+ internal:
+ signature:
+ key:
+ type: ENV
+ value: SIG_SECRET_KEY
+
+# Spring health monitoring
+management:
+ health:
+ jms:
+ enabled: false
+
+#spring:
+# datasource:
+# url: jdbc:mysql://localhost:3306/greetings
+# username: greetings
+# password: Gr33:t1ngs
+# driver-class-name: com.mysql.cj.jdbc.Driver
+# jpa:
+# database: mysql
+# generate-ddl: false
+spring:
+ h2:
+ console:
+ enabled: true
+ datasource:
+ url: jdbc:h2:mem:greetingsdb;Mode=Oracle
+ sql:
+ init:
+ platform: h2
+ continue-on-error: true
+ jpa:
+ generate-ddl: false
+ liquibase:
+ enabled: true
+ change-log: classpath:db/changelog.yaml
+
+buildingblocks:
+ security:
+ xss:
+ autoconfig: false
\ No newline at end of file
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/banner.txt b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/banner.txt
new file mode 100644
index 0000000..3e84197
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/banner.txt
@@ -0,0 +1,9 @@
+ ________ ________ ________ ___ __ ________ ________ ________ _______
+|\ __ \|\ __ \|\ ____\|\ \|\ \ |\ __ \|\ __ \|\ ____\|\ ___ \
+\ \ \|\ /\ \ \|\ \ \ \___|\ \ \/ /|\ \ \|\ /\ \ \|\ \ \ \___|\ \ __/|
+ \ \ __ \ \ __ \ \ \ \ \ ___ \ \ __ \ \ __ \ \_____ \ \ \_|/__
+ \ \ \|\ \ \ \ \ \ \ \____\ \ \\ \ \ \ \|\ \ \ \ \ \|____|\ \ \ \_|\ \
+ \ \_______\ \__\ \__\ \_______\ \__\\ \__\ \_______\ \__\ \__\____\_\ \ \_______\
+ \|_______|\|__|\|__|\|_______|\|__| \|__|\|_______|\|__|\|__|\_________\|_______|
+ \|_________|
+
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/bootstrap.yaml b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/bootstrap.yaml
new file mode 100644
index 0000000..3767fe9
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/bootstrap.yaml
@@ -0,0 +1,3 @@
+spring:
+ application:
+ name: example-service
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/db/changelog.yaml b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/db/changelog.yaml
new file mode 100644
index 0000000..ed6f6eb
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/main/resources/db/changelog.yaml
@@ -0,0 +1,16 @@
+databaseChangeLog:
+- changeSet:
+ id: greetings
+ author: filer
+ changes:
+ - createTable:
+ tableName: greetings
+ columns:
+ - column:
+ constraints:
+ nullable: false
+ name: id
+ type: VARCHAR(36)
+ - column:
+ name: message
+ type: VARCHAR(255)
\ No newline at end of file
diff --git a/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/test/java/com/backbase/example/ExampleControllerIT.java b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/test/java/com/backbase/example/ExampleControllerIT.java
new file mode 100644
index 0000000..2aafd6e
--- /dev/null
+++ b/service-sdk/18.0.0/service-to-service-communication/example-service-to-service/src/test/java/com/backbase/example/ExampleControllerIT.java
@@ -0,0 +1,122 @@
+package com.backbase.example;
+
+
+import com.backbase.service.example.rest.spec.v1.model.Message;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.ApplicationContext;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.security.web.csrf.CsrfToken;
+import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.ResultActions;
+import org.springframework.http.MediaType;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+
+/**
+ * A wrapper annotation for use with integration tests.
+ *
+ * By default, assumes the integration test modifies the
+ * {@link ApplicationContext} associated with the test/s and will therefore be
+ * closed and removed from the context cache at the end of the class.
+ */
+@SpringBootTest(classes = Application.class)
+@AutoConfigureMockMvc
+@ActiveProfiles("it")
+public class ExampleControllerIT {
+
+ String TOKEN_ATTR_NAME = "org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN";
+
+ public static final String TEST_JWT =
+ "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsIm5hZiI6MTUwNjUyNzQzMSwiY25leHAiOnRydWUsImdycCI6" +
+ "WyJhZG1pbihBRE1JTikiXSwiYW5sb2MiOnRydWUsImFuZXhwIjp0cnVlLCJlbmJsIjp0cnVlLCJleHAiOjE1MDY1" +
+ "MjU5MzEsImlhdCI6MTUwNjUyNTYzMSwicm9sIjpbIlJPTEVfQUNUVUFUT1IiLCJST0xFX0FETUlOIiwiUk9MRV9nc" +
+ "m91cF9hZG1pbihBRE1JTikiXSwianRpIjoiMjQ1MDBkNDQtNDRiZS00MTI1LTg4MjctOWY1NDAwOTc4NmEzIn0.5qZ" +
+ "nncyJpWJ8GqklJK6RmyHUUPddNOh52al65_C4T9o";
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void exampleTest() throws Exception {
+ String greetingsId = givenAGreetingExists();
+ whenWeGetTheMessageByIdThenTheMessageExists(greetingsId);
+ WhenWeGetAllMessagesThenAListOfMessagesIsReturned();
+ }
+
+ private void WhenWeGetAllMessagesThenAListOfMessagesIsReturned() throws Exception {
+ //When: Request for all messages
+ MockHttpServletRequestBuilder getAllMessagesRequestBuilder = get("/client-api/v1/all-messages")
+ .header("Authorization", TEST_JWT);
+
+ ResultActions getAllMessagesResult = mvc.perform(getAllMessagesRequestBuilder).andDo(print());
+
+ // Then the request is successful with a list of messages
+ getAllMessagesResult.andExpect(status().isOk());
+
+ List listOfMessages = new ObjectMapper().readValue(getAllMessagesResult.andReturn().getResponse().getContentAsString(),
+ new TypeReference<>() {});
+
+ assertThat(listOfMessages).isNotEmpty();
+ }
+
+ private void whenWeGetTheMessageByIdThenTheMessageExists(String greetingsId) throws Exception {
+ //When: we get that message
+ MockHttpServletRequestBuilder getMessageRequestBuilder = get("/client-api/v1/messages?id=" + greetingsId)
+ .header("Authorization", TEST_JWT);
+
+ ResultActions result = mvc.perform(getMessageRequestBuilder).andDo(print());
+
+ result = result.andExpect(status().isOk());
+
+ MvcResult response = result.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
+
+ String responseBody = response.getResponse().getContentAsString();
+
+ //Then: the message exists
+ assertThat(responseBody).contains("Hello World").as("ID in response should match ID in request");
+ }
+
+ private String givenAGreetingExists() throws Exception {
+ //Given: a message exists
+ String id = UUID.randomUUID().toString();
+ Message message = new Message();
+ message.setMessage("Hello World is it me your looking for?");
+ message.setId(id);
+
+ String messageAsString = new ObjectMapper().writeValueAsString(message);
+
+ HttpSessionCsrfTokenRepository httpSessionCsrfTokenRepository = new HttpSessionCsrfTokenRepository();
+ CsrfToken csrfToken = httpSessionCsrfTokenRepository.generateToken(new MockHttpServletRequest());
+
+ MockHttpServletRequestBuilder postRequestBuilder = post("/client-api/v1/messages")
+ .header("Authorization", TEST_JWT)
+ .sessionAttr(TOKEN_ATTR_NAME, csrfToken)
+ .param(csrfToken.getParameterName(), csrfToken.getToken())
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(messageAsString);
+
+ ResultActions postResult = mvc.perform(postRequestBuilder).andDo(print());
+
+ postResult.andExpect(status().isCreated());
+
+ Message messagePostResponseBody = new ObjectMapper().readValue(postResult.andReturn().getResponse().getContentAsString(),
+ new TypeReference<>() {});
+ return messagePostResponseBody.getId();
+ }
+}