Camel K Serverless API Example

This example demonstrates how to write an API based Camel K integration, from the design of the OpenAPI definition to the implementation of the specific endpoints up to the deployment as serverless API in Knative.

In this specific example, the API enables users to store generic objects, such as files, in a backend system, allowing all CRUD operation on them.

The backend is an Amazon AWS S3 bucket that you might provide. In alternative, you'll be given instructions on how to create a simple Minio backend, which uses a S3 compatible protocol.

Before you begin

Read the general instructions in the root README.md file for setting up your environment and the Kubernetes cluster before looking at this example.

Make sure you've read the installation instructions for your specific cluster before starting the example.

You should open this file with Didact if available on your IDE.

Requirements

Validate all Requirements at Once!

Kubectl CLI

The Kubernetes kubectl CLI tool will be used to interact with the Kubernetes cluster.

Check if the Kubectl CLI is installed{.didact}

Status: unknown

Connection to a Kubernetes cluster

You need to connect to a Kubernetes cluster in order to run the example.

Check if you're connected to a Kubernetes cluster{.didact}

Status: unknown

Apache Camel K CLI (“kamel”)

You need the Apache Camel K CLI (“kamel”) in order to access all Camel K features.

Check if the Apache Camel K CLI (“kamel”) is installed{.didact}

Status: unknown

Knative installed on the cluster

The cluster also needs to have Knative installed and working. Refer to the official Knative documentation for information on how to install it in your cluster.

Check if the Knative is installed{.didact}

Status: unknown

Optional Requirements

The following requirements are optional. They don't prevent the execution of the demo, but may make it easier to follow.

VS Code Extension Pack for Apache Camel

The VS Code Extension Pack for Apache Camel provides a collection of useful tools for Apache Camel K developers, such as code completion and integrated lifecycle management. They are recommended for the tutorial, but they are not required.

You can install it from the VS Code Extensions marketplace.

Check if the VS Code Extension Pack for Apache Camel by Red Hat is installed{.didact}

Status: unknown

1. Preparing the namespace

Let's open a terminal and go to the example directory:

cd 02-serverless-api

(^ execute{.didact})

We're going to create a namespace named camel-api for running the example. To create it, execute the following command:

kubectl create namespace camel-api

(^ execute{.didact})

Now we can set the camel-api namespace as default namespace for the following commands:

kubectl config set-context --current --namespace=camel-api

(^ execute{.didact})

You need to install Camel K in the camel-api namespace (or globally in the whole cluster). In many settings (e.g. OpenShift, CRC), it's sufficient to execute the following command to install Camel K:

kamel install

(^ execute{.didact})

NOTE: The kamel install command requires some prerequisites to be successful in some situations, e.g. you need to enable the registry addon on Minikube. Refer to the Camel K install guide for cluster-specific instructions.

To check that Camel K is installed we'll retrieve the IntegrationPlatform object from the namespace:

kubectl get integrationplatform

(^ execute{.didact})

You should find an IntegrationPlatform in status Ready.

You can now proceed to the next section.

2. Configuring the object storage backend

You have two alternative options for setting up the S3 backend that will be used to store the objects via the Camel K API: you can use an existing S3 bucket of your own or you can set up a local S3 compatible object storage.

2.1 [Alternative 1] I don‘t have a S3 bucket: let’s install a Minio backend

The test directory contains an all-in-one configuration file for creating a Minio backend that will provide a S3 compatible protocol for storing the objects.

Open the (test/minio.yaml{.didact}) file to check its content before applying.

To create the minio backend, just apply the provided file:

kubectl apply -f test/minio.yaml

(^ execute{.didact})

That's enough to have a test object storage to use with the API integration.

2.1 [Alternative 2] I have a S3 bucket

If you have a S3 bucket and you want to use it instead of the test backend, you can do it. The only things that you need to provide are a AWS Access Key ID and Secret that you can obtain from the Amazon AWS console.

Edit the (s3.properties{.didact}) to set the right value for the properties camel.component.aws-s3.access-key and camel.component.aws-s3.secret-key. Those properties will be automatically injected into the Camel aw3-s3 component.

3. Designing the API

An object store REST API is provided in the openapi.yaml{.didact} file.

It contains operations for:

  • Listing the name of the contained objects
  • Creating a new object
  • Getting the content of an object
  • Deleting an object

The file can be edited manually or better using an online editor, such as Apicurio.

4. Running the API integration

The endpoints defined in the API can be implemented in a Camel K integration using a direct:<operationId> endpoint. This has been implemented in the API.java{.didact} file.

To run the integration, you need to link it to the proper configuration, that depends on what configuration you've chosen (either S3 or Minio). Additionally you need to expose the OpenAPI spec. as ConfigMap:

kubectl create configmap my-openapi --from-file=openapi.yaml

4.1 [Alternative 1] Using the test Minio server

As alternative, to connect the integration to the test Minio server deployed before:

kamel run API.java --open-api configmap:my-openapi --property file:test/minio.properties --dev

(^ execute{.didact})

In case you run on Minikube then you can't use http://minio:9000 as your S3 endpoint in minio.properties because the EXTERNAL-IP of your load balancer service would be <pending>. For this to work you can run Minikube service to get the URL for the connection to use:

$> minikube service -n camel-api minio
|-----------|-------|-------------|-----------------------------|
| NAMESPACE | NAME  | TARGET PORT |             URL             |
|-----------|-------|-------------|-----------------------------|
| camel-api | minio |        9000 | http://192.168.105.26:32393 |
|-----------|-------|-------------|-----------------------------|

Given the example above then use the following configuration in minio.properties:

camel.component.aws2-s3.uri-endpoint-override=http://192.168.105.26:32393

4.2 [Alternative 2] Using the S3 service

To connect the integration to the AWS S3 service:

kamel run API.java --open-api configmap:my-openapi --property file:s3.properties --dev

(^ execute{.didact})

5. Using the API

After running the integration API, you should be able to call the API endpoints to check its behavior.

Make sure the integration is running, by checking its status:

kubectl get integrations

(^ execute{.didact})

An integration named api should be present in the list and it should be in status Running. There's also a kamel get command which is an alternative way to list all running integrations.

NOTE: it may take some time, the first time you run the integration, for it to reach the Running state.

After the integraiton has reached the running state, you can get the route corresponding to it via the following command:

URL=$(kubectl get routes.serving.knative.dev api -o jsonpath='{.status.url}')

(^ execute{.didact})

You can print the route to check if it's correct:

echo $URL

(^ execute{.didact})

NOTE: ensure that you've followed all the instructions in the Knative documentation during installation, especially the DNS part is fundamental for being able to contact the API.

You can now play with it! What follows is a list of commands that you can run to use the API and check if it's working.

Get the list of objects:

curl -i $URL/

(^ execute{.didact})

Looking at the pods, you should find a pod corresponding to the API integration:

kubectl get pods

(^ execute{.didact})

If you wait at least one minute without invoking the API, you‘ll find that the pod will disappear. Calling the API again will make the pod appear to serve the request. This is done to save resources and it’s one the main features of Knative Serving.

You can continue with other commands.

Upload an object:

curl -i -X PUT --header "Content-Type: application/octet-stream" --data-binary "@API.java" $URL/example

(^ execute{.didact})

Get the new list of objects:

curl -i $URL/

(^ execute{.didact})

Get the content of a file:

curl -i $URL/example

(^ execute{.didact})

Delete the file:

curl -i -X DELETE $URL/example

(^ execute{.didact})

Get (again) the new list of objects:

curl -i $URL/

(^ execute{.didact})

6. Uninstall

To cleanup everything, execute the following command:

kubectl delete namespace camel-api

(^ execute{.didact})