Contents
Sometimes you want to run a CAP application locally for testing purposes. If that application requires a connection to a remote service on the Cloud Foundry (CF) runtime of SAP Cloud Platform, you can do this by making service binding details available locally to that application. This is done using values in a specially named file default-env.json
.
There are various ways to generate the contents needed for such a file, here's one.
The scenario here is where a CAP application running locally must connect to an instance of an SAP Enterprise Messaging service instance running in the CF runtime of an SAP Cloud Platform trial account. The instance name is emdev
, as described in the Message bus setup document.
It will also require the ability to read destination information defined in the SAP Cloud Platform subaccount, and for that it will also need a connection to instances of the destination service and the XSUAA service.
The general idea being followed here is that service bindings can be generated by creating a simple app in that same CF space, and then binding the service instances to that app.
Subsequently, we can then use the standard cf env
command to request the environment variables for that app, which will include the service binding information. Specifically we're looking for the VCAP_SERVICES
environment variable.
So the approach is to
- deploy a very simple app
- bind the service instances to it
- then request the environment variables
The credentials in this binding context are only relevant as long as the bindings exist, so the app must remain while the credentials are to be used.
There are two ways to follow this approach available here - you can do it manually, step by step, to understand what's happening. But there's also a small experimental script that will perform all the steps for you, even the editing of the output from cf env
, thanks to the venerable stream editor sed
.
First, pick a temporary name for the app - we'll use this throughout these steps. Let's pick mytempapp
for example.
$ appname=mytempapp
First, make sure that there's no directory called mytempapp
, and no existing app already deployed with that name:
$ rmdir $appname
$ cf d -f $appname
Now create a new temporary app directory and deploy the app based upon that:
$ mkdir $appname
$ cf push -c null --no-route --no-start -k 64M -m 32M $appname $appname
At this point you can remove the temporary app directory:
$ rmdir $appname
Next, bind the service instances to the app:
$ cf bind-service $appname emdev
$ cf bind-service $appname destination-lite
$ cf bind-service $appname xsuaa-application
This assumes that you not only already have an instance of the SAP Enterprise Messaging service, with the name
emdev
, but you also have instances of the Destination and XSUAA services too, with specific planslite
andapplication
respectively. If not, create them withcf create-service destination lite destination-lite
andcf create-service xsuaa application xsuaa-application
. Note that the naming convention used here for the instances is<servicename>-<planname>
.
Finally, request the environment information:
$ cf env $appname > default-env.txt
The output of cf env
contains what we need, but also some extraneous information. So open the default-env.txt
file up and edit it to leave just the JSON section containing the VCAP_SERVICES
section, as shown here, i.e. remove everything except what's shown between the START and END cut lines.
Getting env variables for app temp in org 4dc50e9btrial / space dev as [email protected]...
OK
System-Provided:
---START----8<------------------------------------------------------------
{
"VCAP_SERVICES": {
"enterprise-messaging": [
{
"binding_name": null,
"credentials": {
"management": [
{
"oa2": {
"clientid": "sb-clone-xbem-service-broker-aec3bfac91f84d61841ef28efb7fa235-clone!b68527|xbem-service-broker-!b2436",
...
}
]
}
"label": "enterprise-messaging",
"name": "emdev",
"plan": "dev",
"provider": null,
"syslog_drain_url": null,
"tags": [
"enterprise-messaging"
],
"volume_mounts": []
}
]
}
}
---END------8<------------------------------------------------------------
{
"VCAP_APPLICATION": {
"application_id": "d279e412-be5d-48fc-bf40-8d887c77f263",
"application_name": "temp",
...
}
}
No user-defined env variables have been set
Running Environment Variable Groups:
CREDHUB_API: https://credhub.service.cf.internal
No staging env variables have been set
Finally, now you have pure JSON in the file, rename it to default-env.json
and you're done!
We've written a small script that will perform the steps above. The script is default-env-gen
and there's also the stream edit commands in default-env-gen.sed
.
The script expects a single mandatory argument - your choice of a name for the temporary app. It will then proceed to run through the above steps, and produce a default-env.json
file. It will expect an existing instance of the SAP Enterprise Messaging service called emdev
(but you can specify a different instance name as a second argument if you need to); it will also look for and bind existing Destination and XSUAA service instances with the specific names destination-lite
and xsuaa-application
respectively.
Here's a (slightly edited) example invocation:
user: brain $ ./default-env-gen temp1
Deleting app temp1 in org 14ee89fftrial / space dev as [email protected]...
OK
App temp1 does not exist.
Pushing app temp1 to org 14ee89fftrial / space dev as [email protected]...
Getting app info...
Creating app with these attributes...
+ name: temp1
path: /home/user/projects/teched2020-developer-keynote/cap/brain
+ disk quota: 64M
+ memory: 32M
Creating app temp1...
Comparing local files to remote cache...
Packaging files to upload...
Uploading files...
6.35 MiB / 6.35 MiB 100.00% 1s
Waiting for API to complete processing files...
name: temp1
requested state: stopped
routes:
last uploaded:
stack:
buildpacks:
type: web
instances: 0/1
memory usage: 32M
state since cpu memory disk details
#0 down 2021-01-05T13:54:53Z 0.0% 0 of 0 0 of 0
Binding service emdev to app temp1 in org 14ee89fftrial / space dev as [email protected]...
OK
TIP: Use 'cf restage temp1' to ensure your env variable changes take effect
Binding service destination-lite to app temp1 in org 14ee89fftrial / space dev as [email protected]...
OK
TIP: Use 'cf restage temp1' to ensure your env variable changes take effect
Binding service xsuaa-application to app temp1 in org 14ee89fftrial / space dev as [email protected]...
OK
This will have created a fresh default-env.json
file for you, which will look something like this (some content removed for readability):
{
"VCAP_SERVICES": {
"enterprise-messaging": [
{
"binding_name": null,
...
"instance_name": "emdev",
"label": "enterprise-messaging",
"name": "emdev",
"plan": "dev",
"provider": null,
"syslog_drain_url": null,
"tags": [
"enterprise-messaging"
],
"volume_mounts": []
}
]
}
}