Hybrid Testing in CAP using environment variables
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.
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 h
ttp://localhost:4004
in VSCode or at a custom URL in BAS (a notification window offers You).
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.
_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 h
ttp://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.
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.
😉
Share this content: