Develop your App for the Kyma Environment with Java SDK
Kyma is an application runtime that provides you a flexible and easy way to connect, extend, and customize your applications in the cloud-native world of Kubernetes. Find more details in the official documentation.
While the Kyma runtime is improving over time, recent changes unfortunately rendered parts of this document outdated. We are currently re-evaluating and updating the information provided. Please follow the official documentation.
Workaround for On-Premise Connectivity
SAP Cloud SDK Features Supported on Kyma by SAP
Find below the list of features we currently support: Legend: ✅ - supported, ❗- partially supported, ❌ - not supported
- ✅ Consume SAP BTP services like Destination, Connectivity, IAS, XSUAA, and others
- ✅ Multitenancy
- ✅ Resilience & Caching
- ✅ Connect to and consume services from SAP S/4HANA Cloud
- ✅ Connect to and consume services from SAP S/4HANA On-Premise
- ✅ Seamless use of typed clients provided by the SAP Cloud SDK
Getting Started with the SAP Cloud SDK on Kyma
This detailed guide will help get your SAP Cloud SDK Java application up and running in Kyma. You can also use this guide to migrate your existing application to Kyma.
Prerequisites
To follow this guide you will need:
- An SAP BTP Kyma environment instance
- Docker and a publicly reachable Docker repository
- A Spring Boot Application using the SAP Cloud SDK
When deploying applications to Kyma, you are not limited to Spring Boot applications. In fact, you may deploy any application that can be executed within a Docker container. The examples in this document, however, do use a Spring Boot app.
Check out the details below in case you are uncertain about any of the prerequisites.
Kyma Environment
Docker
Application using the SAP Cloud SDK
Containerize the Application
To run on Kyma the application needs to be shipped in a container. For this guide we will be using Docker.
Create a Dockerfile
in the project root directory:
FROM openjdk:8-jdk-slim
ARG JAR_FILE=application/target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
If needed, update the JAR_FILE
to point to your JAR file.
You can find more information on how to containerize Spring Boot applications in this guide (in particular, check the Containerize It section).
Compile and push the image by running:
docker build -t <your-repo>/<your-image-name> .
docker push <your-repo>/<your-image-name>
# alternatively, you may add a tag to your image
docker build -t <your-repo>/<your-image-name>:<your-tag> .
docker push <your-repo>/<your-image-name>:<your-tag>
In case you are facing authorization issues when pushing to your repository refer to the dedicated section under Prerequisites.
Create a Kyma Deployment
-
Create a new YAML file:
deployment.ymlapiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
# Configure the docker image you just pushed to your repository here
- image: <name-of-the-image>
name: my-app
imagePullPolicy: Always
resources:
requests:
memory: '1.5Gi'
cpu: '500m'
limits:
memory: '2Gi'
cpu: '1000m'
# Volume mounts needed for injecting SAP BTP service credentials
volumeMounts:
imagePullSecrets:
# In case your repository requires a login, reference your secret here
- name: <your-secret-for-docker-login>
volumes:
----
apiVersion: v1
kind: Service
metadata:
labels:
app: my-app
name: my-app
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
protocol: TCP
selector:
app: my-app -
Install the configuration via
kubectl apply -f path/to/deployment/file/deployment.yml
. -
Monitor the status of the deployment by running:
kubectl get deployment my-app-deployment
.
Eventually, you should see an output similar to:
kubectl get deployment my-app-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-app-deployment 1/1 1 1 15s
In case something went wrong use kubectl describe
together with deployment
or pod
to get more information about the status of your application.
Access Your Application
To access your application without further configuration you need to find the name of the application pod by listing out all available pods:
kubectl get pods
Now use the name of the application pod and forward the application port to your local machine:
kubectl port-forward [pod-name] [local-port]:[application-port]
In case you started with an SAP Cloud SDK Archetype, you can test the hello
endpoint:
curl localhost:[local-port]/hello
Example
If port-forwarding is not enough for you, you can also get SSH access to your application pods:
kubectl exec --stdin --tty [pod-name] -- /bin/sh
Bind SAP BTP Services to the Application
The SAP Business Technology Platform offers various services that can be used by applications. To access services from a Kyma environment, instances have to be created and bound to the application.
For this guide we'll assume we want to use two services:
- Destination Service
- XSUAA Service
Bind the Destination Service
- Open your Kyma dashboard by clicking the link in your SAP BTP cockpit:
- In the Kyma dashboard, select your Kyma namespace (top right hand side of the screen), navigate to
Service Management > Catalog
, and select theDestination
service.
-
Configure your new service instance by first clicking on the
Add +
button followed by selecting both a name and a plan. -
Finalize the service instance creation by confirming your configuration with a click on the
Create
button.
Alternative: Using Kubernetes Descriptors
Bind the XSUAA Service
- Open your Kyma dashboard (see previous section) and select the
Authorization and Trust Management Service
inService Managament > Catalog
:
- Configure your new service instance by clicking the
Add +
button and selecting both a name and a plan or your new service instance. Complete the process by clicking theCreate
button.
Alternative: Using Kubernetes Descriptors
Known XSUAA Service Incompatibility
We have observed that the property plan
is missing in the XSUAA secret created in the previous section.
This property, however, is required by the SAP Cloud SDK and it's absence causes runtime errors in the application while trying to read this service binding.
To fix this issue you need to edit the secret so that it contains the plan
property.
The easiest way, when you are already using the CLI, is by using the kubectl edit
command:
kubectl edit secrets my-xsuaa-secret
In there, you can now add a plan
property with one of the following base64 encoded values:
plan | base64 encoded value |
---|---|
application | YXBwbGljYXRpb24K |
broker | YnJva2VyCg== |
space | c3BhY2UK |
apiaccess | YXBpYWNjZXNzCg== |
The resulting service binding can now be consumed with the SAP Cloud SDK.
Expose your Application to the Internet
During the next steps, you will configure and deploy an approuter so that only authenticated users can access your application. For that, you will need to create a simple application that uses the @sap/approuter and starts it for this purpose.
-
Based on the approuter application you used, containerize your application and push the image to a docker repository of your choice.
-
Create a new YAML file describing the approuter deployment:
deployment.ymlapiVersion: apps/v1
kind: Deployment
metadata:
name: my-approuter-deployment
labels:
app: my-approuter
spec:
replicas: 1
selector:
matchLabels:
app: my-approuter
template:
metadata:
labels:
app: my-approuter
spec:
imagePullSecrets:
- name: <your-secret-for-docker-login>
containers:
# Configure the docker image of your approuter application here
- image: <name-of-the-image>
imagePullPolicy: Always
name: my-approuter
env:
- name: PORT
value: '5000'
- name: destinations
value: >
[
{
"name": "<name-for-the-backend-app>",
"url": "<URL-to-access-backend-app>",
"forwardAuthToken": true
}
]
- name: TENANT_HOST_PATTERN
value: <URL-pattern-for-outside-cluster-access>
volumeMounts:
- name: my-xsuaa-service-binding-volume
mountPath: '/etc/secrets/sapcp/xsuaa/my-xsuaa-service-binding'
volumes:
- name: my-xsuaa-service-binding-volume
secret:
secretName: my-xsuaa-secret
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
labels:
app: my-approuter
name: my-approuter
spec:
type: NodePort
ports:
- port: 5000
targetPort: 5000
protocol: TCP
nodePort: 31002
selector:
app: my-approuter -
Also adapt the
xs-app.json
file:
{
"welcomeFile": "/web-pages/index.html",
"routes": [
{
"source": "/<path-for-backend-endpoints>/(.*)",
"target": "$1",
"destination": "<name-for-the-backend-app>",
"identityProvider": "<optional-identity-provider-id>",
"csrfProtection": false
}
]
}
-
Follow steps similar to steps 2-3 in Create a Kyma Deployment section to deploy the approuter and check if the deployment is successful.
-
Update the already created XSUAA service instance with few parameters like
xsappname
andoauth2-configuration
. This is required to provide authenticated access to backend application via the approuter.
---
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
name: xsuaa-service
spec:
clusterServiceClassExternalName: xsuaa
clusterServicePlanExternalName: <your-desired-plan>
parameters:
xsappname: <your-backend-app-name>
oauth2-configuration:
allowedproviders:
- <your-idp-key>
redirect-uris:
- <URL-pattern-for-outside-cluster-access>
---
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
name: my-xsuaa-service-binding
spec:
instanceRef:
name: xsuaa-service
secretName: my-xsuaa-secret
-
Update the configuration via
kubectl apply -f xsuaa-service.yaml
. -
Make the approuter accessible outside the cluster by creating an API rule:
apiVersion: gateway.kyma-project.io/v1alpha1
kind: APIRule
metadata:
name: <your-rule-name>
spec:
gateway: kyma-gateway.kyma-system.svc.cluster.local
rules:
- accessStrategies:
- config: {}
handler: noop
methods:
- GET
path: /.*
service:
host: <subaccount-prefix>.<URL-pattern-for-outside-cluster-access>
name: my-approuter
port: 5000
-
Update the configuration via
kubectl apply -f create-api-rule.yml
. -
Finally, access the application by using the host address provided in the API rule created and appending the
path-for-backend-endpoints
given inxs-app.json
along with the an actual end point of your backend application.
You need not necessarily push an Approuter to access your application outside a cluster. You could also go ahead and expose the service for your application directly by creating an APIRule. But, this would mean that access to your application would not be authenticated first.
You can also refer to this additional material available for getting started with SAP Cloud SDK on Kyma: