-
Notifications
You must be signed in to change notification settings - Fork 138
Microservices: shared-db for java #2142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 14 commits
43934b7
c448fda
13f868e
6f7637e
bbbc2be
55c9ed6
c8a1afe
9953f35
a5a9f88
50b1880
8df033a
a1efe3b
65023b1
0b46dc2
d3a561d
7fed5b4
de4a3a5
d6ac241
6d12d8a
79283a2
b4106ae
19090b0
b305085
5a2fa19
89d9cee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
@@ -47,28 +48,38 @@ 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 | ||
| git submodule add https://github.com/capire/bookshop-java | ||
| git submodule add https://github.com/capire/data-viewer | ||
| git submodule update --init | ||
| ``` | ||
| ::: | ||
|
|
||
| Add a _.gitignore_ file with the following content: | ||
| ```txt | ||
| node_modules | ||
| gen | ||
| ``` | ||
| > 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} | ||
|
|
||
|
|
@@ -77,14 +88,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 | ||
|
|
@@ -208,7 +228,9 @@ This section is about how to deploy all 3+1 projects at once with a common _mta. | |
|
|
||
|  | ||
|
|
||
| [@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. | ||
|
|
||
| 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 | ||
|
|
||
|
|
@@ -258,8 +280,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 | ||
|
|
@@ -269,8 +290,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: | ||
|
|
@@ -280,15 +301,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 | ||
|
|
@@ -345,9 +372,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] | ||
|
|
@@ -367,7 +464,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: | ||
|
|
@@ -400,7 +496,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 | ||
|
|
@@ -414,6 +510,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 | ||
| ``` | ||
|
|
@@ -499,6 +597,62 @@ 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 the mta.yaml file parameterizes these dynamically: | ||
|
||
|
|
||
| ::: code-group | ||
| ```json [event-mesh.json] | ||
| { | ||
| "version": "1.1.0", | ||
| "emname": "samples-emname", // [!code --] | ||
| "namespace": "default/samples/1", // [!code --] | ||
| "options": { | ||
| "management": true, | ||
| "messagingrest": true, | ||
| "messaging": true | ||
| }, | ||
| "rules": { | ||
| "topicRules": { | ||
| "publishFilter": [ | ||
| "*" | ||
| ], | ||
| "subscribeFilter": [ | ||
| "*" | ||
| ] | ||
| }, | ||
| "queueRules": { | ||
| "publishFilter": [ | ||
| "*" | ||
| ], | ||
| "subscribeFilter": [ | ||
| "*" | ||
| ] | ||
| } | ||
| }, | ||
| "authorities": [ | ||
| "$ACCEPT_GRANTED_AUTHORITIES" | ||
| ] | ||
| } | ||
| ``` | ||
| ::: | ||
|
|
||
| Add a messaging resource in mta.yaml with parameterized `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 | ||
|
|
||
|
|
@@ -551,17 +705,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: | ||
|
|
||
|
|
@@ -571,6 +743,31 @@ npm i @sap-cloud-sdk/resilience --workspace bookstore | |
| ``` | ||
| ::: | ||
|
|
||
| ::: details CAP Java: Configure each app for cloud readiness | ||
|
|
||
| To access remote OData services, add a dependency to the *cds-feature-remote-odata* [application plugin](https://cap.cloud.sap/docs/java/developing-applications/building#standard-modules) and provide the latest available version. Additionally, to retrieve destination configurations using the destination service, include a *com.sap.cloud.sdk.cloudplatform* dependency with the *scp-cf* artifact ID, as described in [Cloud SDK Integration](https://cap.cloud.sap/docs/java/cqn-services/remote-services#cloud-sdk-dependencies). | ||
|
|
||
| ::: code-group | ||
| ```xml [bookstore/srv/pom.xml] | ||
| ... | ||
| <dependencies> | ||
| ... | ||
| <dependency> | ||
| <groupId>com.sap.cds</groupId> | ||
| <artifactId>cds-feature-remote-odata</artifactId> | ||
| <scope>runtime</scope> | ||
| <version>4.0.2</version> | ||
| </dependency> | ||
|
|
||
| <dependency> | ||
| <groupId>com.sap.cloud.sdk.cloudplatform</groupId> | ||
| <artifactId>scp-cf</artifactId> | ||
| </dependency> | ||
| ... | ||
| ``` | ||
|
|
||
| ::: | ||
|
|
||
| ### App Router | ||
|
|
||
| Add _App Router_ configuration using the command: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a blank line after step 3 for consistent formatting with other numbered steps in the document.