Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 201 additions & 20 deletions guides/deployment/microservices.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ This guide describes a way to manage development and deployment via *[monorepos]

2. Add the previously mentioned projects as `git` submodules:

```sh
::: code-group
```sh [Node.js]
git init
git submodule add https://github.com/capire/bookstore
git submodule add https://github.com/capire/reviews
Expand All @@ -47,6 +48,17 @@ This guide describes a way to manage development and deployment via *[monorepos]
git submodule add https://github.com/capire/data-viewer
git submodule update --init
```
```sh [Java]
git init
git submodule add https://github.com/capire/bookstore-java
git submodule add https://github.com/capire/reviews-java
git submodule add https://github.com/capire/orders-java
git submodule add https://github.com/capire/common-java
git submodule add https://github.com/capire/bookshop-java
git submodule add https://github.com/capire/data-viewer-java
git submodule update --init
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When will those be available? Asking to make sure we don't merge this PR before

```
:::

Add a _.gitignore_ file with the following content:
```txt
Expand All @@ -55,20 +67,21 @@ This guide describes a way to manage development and deployment via *[monorepos]
```
> The outcome of this looks and behaves exactly as the monorepo layout in *[cap/samples](https://github.com/capire/samples)*, so we can exercise the subsequent steps in there...


3. Test-drive locally:
```sh

::: code-group
```sh [Node.js]
npm install
```

```sh
cds w bookshop
```

```sh
cds w bookstore
```sh [Java]
npm install
cd bookstore && npm start
```
:::

Each microservice can be started independently. If you start each microservice, one after the other in a different terminal, the connection is already established.
In Node.js, each microservice can be started independently. If you start each microservice, one after the other in a different terminal, the connection is already established.

[Learn more about Automatic Bindings by `cds watch`](../extensibility/composition#bindings-via-cds-watch){.learn-more}

Expand All @@ -77,14 +90,23 @@ This guide describes a way to manage development and deployment via *[monorepos]

The project structure used here is as follows:

```txt
::: code-group
```txt [Node.js]
<PROJECT-ROOT>/
├─ bookstore/
├─ orders/
├─ reviews/
├─ ...
└─ package.json
```
```txt [Java]
<PROJECT-ROOT>/
├─ bookstore-java/
├─ orders-java/
├─ reviews-java/
├─ ...
└─ package.json
```

The individual services (`bookstore`, `reviews`, `orders`) can be one of the following:
* folders, committed directly to the root project
Expand Down Expand Up @@ -208,7 +230,9 @@ This section is about how to deploy all 3+1 projects at once with a common _mta.

![component diagram with synchronous and event communication for orders](./assets/microservices/bookstore.excalidraw.svg)

[@capire/samples](https://github.com/capire/samples#readme) already has an all-in-one deployment implemented. Similar steps are necessary to convert projects with multiple CAP applications into a shared database deployment.
For Node.js, [@capire/samples](https://github.com/capire/samples#readme) already has an all-in-one deployment implemented. Similar steps are necessary to convert projects with multiple CAP applications into a shared database deployment.

<font color=red size=+2>TODO</font> For CAP Java, [@capire/samples-java](https://github.com/capire/samples-java#readme) already has an all-in-one deployment implemented. Similar steps are necessary to convert projects with multiple CAP applications into a shared database deployment.

### Deployment Descriptor

Expand Down Expand Up @@ -258,8 +282,7 @@ build-parameters:
```
:::


::: info `cds build --ws`
::: info `cds build --ws` with Node.js
If the CDS models of every NPM workspace contained in the monorepo should be considered, then instead of creating this `shared-db` folder, you can also use:
```shell
cds build --for hana --production --ws
Expand All @@ -269,8 +292,8 @@ The `--ws` aggregates all models in the NPM workspaces.
In this walkthrough, we only include a subset of the CDS models in the deployment.
:::

::: details Node.js: Configure each app for cloud readiness

::: details Configure each app for cloud readiness
The preceding steps only added configuration to the workspace root.

Additionally add database configuration to each module that we want to deploy - bookstore, orders, and reviews:
Expand All @@ -280,15 +303,21 @@ npm i @cap-js/hana --workspace bookstore
npm i @cap-js/hana --workspace orders
npm i @cap-js/hana --workspace reviews
```

:::

::: details CAP Java: Configure each app for cloud readiness

For each project add the **cds-starter-cloudfoundry** [starter bundle](https://cap.cloud.sap/docs/java/developing-applications/building#starter-bundles).

:::

### Applications

Replace the MTA module for `samples-srv` with versions for each CAP service and adjust `name`, `path`, and `provides[0].name` to match the module name. Also change the `npm-ci` builder to the `npm` builder.

::: code-group
```yaml [mta.yaml]
```yaml [Node.js (mta.yaml)]
modules:
- name: bookstore-srv # [!code focus]
type: nodejs
Expand Down Expand Up @@ -345,9 +374,79 @@ modules:
- name: samples-destination
...
```
```yaml [Java (mta.yaml)]
modules:

- name: bookstore-srv # [!code focus]
type: java
path: bookstore/srv # [!code focus]
parameters:
instances: 1
buildpack: sap_java_buildpack_jakarta
properties:
SPRING_PROFILES_ACTIVE: cloud,sandbox
JBP_CONFIG_COMPONENTS: "jres: ['com.sap.xs.java.buildpack.jre.SAPMachineJRE']"
JBP_CONFIG_SAP_MACHINE_JRE: '{ version: 21.+ }'
build-parameters:
builder: custom
commands:
- mvn clean package -DskipTests=true --batch-mode
provides: # [!code focus]
- name: bookstore-api # [!code focus]
properties:
srv-url: ${default-url}
requires:
- name: samples-db
- name: samples-auth
- name: samples-messaging
- name: samples-destination

- name: orders-srv # [!code focus]
type: java
path: orders/srv # [!code focus]
parameters:
instances: 1
buildpack: sap_java_buildpack_jakarta
build-parameters:
builder: custom
commands:
- mvn clean package -DskipTests=true --batch-mode
build-result: target/*-exec.jar
provides: # [!code focus]
- name: orders-api # [!code focus]
properties:
srv-url: ${default-url}
requires:
- name: samples-db
- name: samples-auth
- name: samples-messaging
- name: samples-destination

- name: reviews-srv # [!code focus]
type: java
path: reviews/srv # [!code focus]
parameters:
instances: 1
buildpack: sap_java_buildpack_jakarta
build-parameters:
builder: custom
commands:
- mvn clean package -DskipTests=true --batch-mode
build-result: target/*-exec.jar
provides: # [!code focus]
- name: reviews-api # [!code focus]
properties:
srv-url: ${default-url}
requires:
- name: samples-db
- name: samples-auth
- name: samples-messaging
- name: samples-destination
...
```
:::

Add build commands for each module to be deployed:
In Node.js, add build commands for each module to be prepared for deployment:

::: code-group
```yaml [mta.yaml]
Expand All @@ -367,7 +466,6 @@ build-parameters:
Note that we use the *--ws-pack* option for some modules. It's important for node modules referencing other repository-local node modules.
:::


### Authentication

Add [security configuration](../security/authorization#xsuaa-configuration) using the command:
Expand Down Expand Up @@ -400,7 +498,7 @@ Add the admin role
```
:::

::: details Configure each app for cloud readiness
::: details Node.js: Configure each app for cloud readiness
Add NPM dependency `@sap/xssec`:

```shell
Expand All @@ -414,6 +512,8 @@ npm i @sap/xssec --workspace reviews

The messaging service is used to organize asynchronous communication between the CAP services.

#### In Node.js

```shell
cds add enterprise-messaging
```
Expand Down Expand Up @@ -499,6 +599,63 @@ Enable messaging for the modules that use it:

:::

#### In CAP Java

Create a new file named event-mesh.json to store the configuration for enterprise messaging. Skip the `emname` and `namespace` properties, as these will be parameterized dynamically in the mta.yaml file:

::: code-group
```json [event-mesh.json]
{
"version": "1.1.0",
"emname": "samples-emname", // [!code --]
"version": "1.1.0",
"namespace": "default/samples/1", // [!code --]
"options": {
"management": true,
"messagingrest": true,
"messaging": true
},
"rules": {
"topicRules": {
"publishFilter": [
"*"
],
"subscribeFilter": [
"*"
]
},
"queueRules": {
"publishFilter": [
"*"
],
"subscribeFilter": [
"*"
]
}
},
"authorities": [
"$ACCEPT_GRANTED_AUTHORITIES"
]
}
```
:::

Add messaging resource in mta.yaml with parametrized `emname` and `namespace` properties:

::: code-group
```yaml [mta.yaml]
resources:
- name: samples-messaging
type: org.cloudfoundry.managed-service
parameters:
service: enterprise-messaging
service-plan: default
path: ./event-mesh.json
config: # [!code ++]
emname: bookstore-${org}-${space} # [!code ++]
namespace: cap/samples/${space} # [!code ++]
```
:::

### Destinations

Expand Down Expand Up @@ -551,17 +708,35 @@ modules:
Use the destinations in the bookstore application:

::: code-group
```yaml [mta.yaml]
```yaml [Node.js (mta.yaml)]
modules:
- name: bookstore-srv
...
properties: # [!code ++]
cds_requires_ReviewsService_credentials: {"destination": "reviews-dest","path": "/reviews"} # [!code ++]
cds_requires_OrdersService_credentials: {"destination": "orders-dest","path": "/odata/v4/orders"} # [!code ++]
```
```yaml [Java (bookstore/srv/src/main/resources/application.yaml)]
cds:
odataV4.endpoint.path: /
messaging.services:
samples-messaging:
kind: enterprise-messaging
remote.services: # [!code ++]
OrdersService: # [!code ++]
type: "odata-v4" # [!code ++]
http: # [!code ++]
suffix: "/odata/v4" # [!code ++]
destination: # [!code ++]
name: "orders-dest" # [!code ++]
ReviewsService: # [!code ++]
type: "odata-v4" # [!code ++]
destination: # [!code ++]
name: "reviews-dest" # [!code ++]
```
:::

::: details Configure each app for cloud readiness
::: details Node.js: Configure each app for cloud readiness

Add `@sap-cloud-sdk/http-client` and `@sap-cloud-sdk/resilience` for each module utilizing the destinations:

Expand All @@ -571,6 +746,12 @@ npm i @sap-cloud-sdk/resilience --workspace bookstore
```
:::

::: details CAP Java: Configure each app for cloud readiness

Add dependency to the **cds-feature-remote-odata** [application plugin](https://cap.cloud.sap/docs/java/developing-applications/building#standard-modules)

:::

### Approuter

Add [approuter configuration](../deployment/to-cf#add-app-router) using the command:
Expand Down
Loading