[[sources]]
= Sources

WARNING: This document describes features that will be
*available in Camel K 1.2.x* (not released at the time of writing: August 08, 2020)

One of the goals of Camel K is to provide connectors that can be easily installed on any Kubernetes cluster and
used when needed to provide data to internal services or publish data outside, without requiring any in-depth knowledge about Apache Camel from the end-users.

Knative Sources fall into this category, but in general, sources described here can be used with any underlying technology.

NOTE: https://knative.dev/docs/eventing/samples/apache-camel-source/[Knative CamelSources] is a community effort to provide specific sources for Knative.
What we describe in this document is a more general approach that is an alternative to Knative CamelSources and aims to supersede them.

== Sources Design

The following diagram shows how sources are materialized from their elementary building blocks.

image::architecture/camel-k-sources-diagram.png[Next-gen Sources diagram]

=== Kamelets as Abstract Sources

In the context of sources, *Kamelets* play the role of abstract sources that can be materialized once the user provides values for all
mandatory parameters contained in the Kamelet specification.

What follows is a simple Kamelet that can produce periodic events with a specified payload:

[source,yaml]
----
apiVersion: camel.apache.org/v1alpha1
kind: Kamelet
metadata:
  name: timer
spec:
  definition:
    title: "Timer"
    description: "Produces periodic events with a custom payload"
    required:
      - message
    properties:
      payload: # <1>
        title: Payload
        description: The message to generate as payload of each Cloudevent
        type: string
  # continues with the flow declaration
  # ...
----
<1> The definition of the `payload` property

The Kamelet contains the definition of all properties in JSON Schema format. In this example, there's only a single property named `payload`.

A Kamelet does nothing when created on a cluster, but it can be used later to create sources, as explained in the remainder of this document.

=== Integration: binding a Kamelet to a destination

An integration can be used to bind a Kamelet to a destination, providing values for all the Kamelet parameters.

For example, the following integration binds the `timer` Kamelet to the Knative *InMemoryChannel* named `mychannel`:

[source,yaml]
----
apiVersion: camel.apache.org/v1
kind: Integration
metadata:
  name: timer-source
spec:
  flows:
  - from:
      uri: kamelet:timer # <1>
      parameters:
        payload: "Hello World" # <2>
      steps:
      - to: knative:channel/mychannel?apiVersion=messaging.knative.dev/v1beta1&kind=InMemoryChannel # <3>
----
<1> Reference to the Kamelet named `timer`
<2> Value for the `payload` required property (and others, if present)
<3> Destination of the generated events

When binding a Kamelet to a single (fully specified) Knative destination, Camel K does not attempt to do any binding,
instead, it delegates the actual mapping to a Knative *SinkBinding* resource.

The **SinkBinding** intercepts the creation of the Deployment containing the integration specification, to inject the
exact coordinates of the destination (in the example, of the InMemoryChannel named `mychannel`).
This mechanism works also if the integration is materialized into a Knative Serving Service or into a CronJob, not only if a
standard Deployment is used.

The SinkBinding resource is also interpreted at Knative level as a standard source, so the `kn` CLI is able to properly recognize
it. UI tools based on Knative, e.g. the OpenShift console, should also be able to display it as a standard source.
