[[knative-sinks]]
= Knative Sinks

A https://knative.dev/docs/eventing/sinks[Knative Sink] can be referenced in a producer path of the Camel Knative component, e.g.:

[source,java]
----
from('timer:tick')
  .setBody().constant('event')
  .to('knative:event/broker')
----

Or as the value of the `sink` field in a `KameletBinding` resource, e.g.:

[source,yaml]
----
apiVersion: camel.apache.org/v1alpha1
kind: KameletBinding
metadata:
  name: timer-source-binding
spec:
  source:
    ref:
      kind: Kamelet
      apiVersion: camel.apache.org/v1alpha1
      name: timer-source
    properties:
      message: Event
  sink:
    ref:
      kind: Broker
      apiVersion: eventing.knative.dev/v1
      name: broker
    properties:
      type: type
----

In the above examples, the Knative Sink is a https://knative.dev/docs/eventing/broker/[Knative Broker].
However, a Knative Sink can be any Kubernetes resource that's _addressable_, i.e., whose URL can be retrieved by reading its `status.address.url`.

This is what the Camel K operator does to resolve the Sink URLs, so that events can be sent to.
That requires the ServiceAccount that runs the operator to be granted permission to GET these resources, while it configures the integration runtime.

As the set of resources is arbitrary, and cannot be known _a-priori_, these permissions are automatically granted to `camel-k-operator` ServiceAccount, by relying on the Knative Addressable resolver aggregated ClusterRole.

For the above examples, that sink into an `eventing.knative.dev/broker` resource, this is already being configured by Knative, that aggregates the required permissions for its own resources by default.

However, if you integrate custom resources as sinks, the required permissions must be added manually, as documented in the https://knative.dev/docs/eventing/sinks/#using-custom-resources-as-sinks[Knative documentation].

[[knative-sinks-injection]]
== Automatic Injection of K_SINK URL

When using a Camel route with a Knative producer, it may be possible that the the Knative trait will automatically create a SinkBinding to wire the consumer and the Knative producer, given the following example:

[source,java]
----
public class AddToChannel extends RouteBuilder {
    public void configure() throws Exception {
        rest("/")
            .put("/input")
            .to("knative:channel/messages");
    }
}
---

In a Knative enabled environment, there is a `eventing-webhook` pod (in `knative-eventing` namespace), which will set a `K_SINK` environment variable in the Knative source, see https://knative.dev/docs/eventing/custom-event-source/sinkbinding/create-a-sinkbinding/[Knative SinkBinding documentation].

For this injection to work in Camel K Integration, there must be a `bindings.knative.dev/include: true` label in the namespace where the `Integration` is running.
If Knative is installed with default configuration, the https://knative.dev/docs/eventing/custom-event-source/sinkbinding/create-a-sinkbinding/#optional-choose-sinkbinding-namespace-selection-behavior[eventing-webhook] is allowed inspect and inject the `K_SINK` URL in any kubernetes objects in any namespace, by using the `SINK_BINDING_SELECTION_MODE=exclusion`.
If Openshift Serverless is used, https://docs.openshift.com/container-platform/4.10/serverless/develop/serverless-custom-event-sources.html#serverless-sinkbinding-reference-include-label_serverless-custom-event-sources[the default configuration] is `SINK_BINDING_SELECTION_MODE=inclusion`, where each namespace must containts the `bindings.knative.dev/include: true` label. Camel K already takes care of this label when running the integration.
