Hybrid testing in CAP contect means You want to execute your application code inside Your development environment like BAS or VSCode using BTP Cloud Foundry resources. This is a very common activity as CAP developer. You develop a feature making a code change what You want to test before deploying it to the corresponding BTP subaccount or pushing to the git repository. This is useful at the stage the MultiTarget application is deployed to CF already including xsuaa service responsible authentication to CF.

This approach can be used to debug applications in quality or production as well.

The official documentation now explains hybrid testing using the cds bind command. The old way of using environment variables still work however. For fetching service information and credentials into environment variable files like default-env.json You can use this plugin for the Cloud Foundry CLI. You can place this to the project root folder next to the package.json, or into the approuter folder. Note that this not only fetch the VCAP_SERVICES part, but also the VCAP_APPLICATION part as well, what You actually does not need, You can wipe it from the JSON file downloaded.

image-1024x379 Hybrid Testing in CAP using environment variables
image-1 Hybrid Testing in CAP using environment variables

We do not suggest to combine cds bind with environment variables for the same purpose for clarity, and to avoid conflicts and unexpected behaviour.

In further we’ll talk about:

  • Extending xs-security.json to enable hybrid testing from BAS and VSCode
  • Adding simple and stupid unmanaged approuter for testing applications within the app folder
  • adding credentials with basic authentication for remote services in package.json, alternatively in default-env.json: https://cap.cloud.sap/docs/node.js/cds-connect#cds-requires-srv-credentials-1
  • a valid example

Extending xs-security.json

By default login is restricted to BTP, but You can enable to authenticate using BAS and VSCode. Add the following snippet at the end of the xs-security.json file controlling the behaviour of the xsuaa service on BTP. This requires either to (re)deploy the application or manual update of the xsuaa service using the CF command line utility, so that the service running on BTP allows login from your development environment.

{
  ...
  "oauth2-configuration": {
    "redirect-uris": [
      "https://*.applicationstudio.cloud.sap/**",
      "http://localhost:5000/login/callback"
    ]
  }
}

Cloud foundry command line utility command to be executed in the folder where the xs-security.json resides.

cf update-service <xsuaa_service_name> -p <application_name> -c xs-security.json

Now you can execute cds watch in the project root folder, so that the CAP CDS test page is available at http://localhost:4004 in VSCode or at a custom URL in BAS (a notification window offers You).

cds-watch-1024x324 Hybrid Testing in CAP using environment variables

Adding an approuter

Remember we purged the VCAP_APPLICATION from the default-env.json file, to run the application inside the development environment instead of BTP, but still consuming BTP resources/services.

So far so good, but this means the app running in BAS/VSCode or simply using a terminal :) can access BTP, but it does not mean that You’re authenticated to use it.

You App Runing in Hybrid Mode BTP.

To overcome this limitation, we need an application router instance defined and configured by ourself for testing purpose. The application router is a node module delivered by SAP, designed or for SAP Cloud Foundry environment, taking care of user authentication via xsuaa services and routing of requests to the corresponding BTP resources. With the help of approuter we automatically authenticate to BTP instead of authenticating manually along the authentication flow. Fiori Tools users could use alternatively Fiori Tools Proxy, but this is not part of this article.

We need to add an approuter folder, please create it under the root. Copy the default-env.json from the project root into the approuter folder. Add both to the ignore list into the mta.yaml, thus they never gets packed into the mtar file which is deployed to Cloud Foundry.

kep-678x1024 Hybrid Testing in CAP using environment variables
_schema-version: "3.1"
ID: MyApp
version: 0.0.1
modules:
- name: MyApp-srv
  type: nodejs
  path: .
  requires:
  - name: MyApp-db
  - name: uaa_MyApp
    parameters:
      service-key:
        name: uaa_MyApp-key
  - name: jobs
  - name: MyApp-destination-service
  - name: connectivity
  provides:
  - name: srv-api
    properties:
      srv-url: ${default-url}
  parameters:
    buildpack: nodejs_buildpack
    disk-quota: 2048M
    memory: 1024M
  build-parameters:
    builder: npm-ci
    ignore:
    - default-env.json
    - /approuter

Let’s add the approuter module itself, so create first a file package.json with this simple content within the approuter folder:

{
    "dependencies": {
        "@sap/approuter": "^14.3.0"
    },
    "scripts": {
        "start": "node node_modules/@sap/approuter/approuter.js"
    }
}

Then issue command in the same folder in the terminal so that the module gets installed.

npm install

To tell the approuter what to do, we need a configuration file xs-app.json.

{
    "authenticationMethod": "route",
    "routes": [
        {
            "source": "/(.*)$",
            "target": "$1",
            "destination": "custom_router_dest",
            "csrfProtection": false,
            "authenticationType": "xsuaa"
        }
    ]
}

The variable part in this configuration file is the destination name custom_router_dest, which comes from your mta.yaml configuration file. This is actually your applications endpoint root where the incoming requests has to be routed. You can find it under resources/MyApp-destination-service in this example. This is to present the approach with a sample, Your app structure might look different.

resources:
- name: MyApp-db
  type: com.sap.xs.hdi-container
  parameters:
    service: hana
    service-plan: hdi-shared
  properties:
    hdi-service-name: ${service-name}
- name: cross-container-service-1
  type: org.cloudfoundry.existing-service
  parameters:
    service-name: sdi_service
  properties:
    the-service-name: ${service-name}
- name: MyApp-destination-service
  type: org.cloudfoundry.managed-service
  parameters:
    config:
      HTML5Runtime_enabled: true
      init_data:
        instance:
          destinations:
          - Authentication: NoAuthentication
            HTML5.DynamicDestination: true
            HTML5.ForwardAuthToken: true
            HTML5.Timeout: 60000
            Name: custom_router_dest  <----- I AM HERE ;)
            ProxyType: Internet
            Type: HTTP
            URL: ~{srv-api/srv-url}
          - Authentication: NoAuthentication
            Name: ui5
            ProxyType: Internet
            Type: HTTP
            URL: https://ui5.sap.com
          existing_destinations_policy: update
      version: 1.0.0
    service: destination
    service-name: MyApp-destination-service
    service-plan: lite
  requires:
  - name: srv-api

Now you can execute npm start in the approuter root folder, so that the CAP CDS test page is available at http://localhost:5000 in VSCode or at a custom URL in BAS (a notification window offers You). The authentication and routing now works. Look for posts at blogs.sap.com to understand more about the approuter and the corresponding software architecture.

npm-start-approuter-1024x321 Hybrid Testing in CAP using environment variables
cds-server-721x1024 Hybrid Testing in CAP using environment variables

Tips

In case the You close the CDS server test page, there is a way to reopen it despite the notification is gone in the bottom left corner. To do this issue the Ports Preview command and select port 5000 to reopen it.

ports-preview-open-1024x73 Hybrid Testing in CAP using environment variables
ports-preview-1024x235 Hybrid Testing in CAP using environment variables

😉

Share this content: