[[knative-component]]
= Knative Component
:docTitle: Knative
:artifactId: camel-knative
:description: This component allows to interact with Knative.
:since: 3.0
:supportLevel: Preview
:component-header: Both producer and consumer are supported

*Since Camel {since}*

*{component-header}*

The Knative component provides support for interacting with https://knative.dev/[Knative].

Maven users will need to add the following dependency to their `pom.xml`
for this component.

[source,xml]
------------------------------------------------------------
<dependency>
    <groupId>org.apache.camel.k</groupId>
    <artifactId>camel-knative</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel K version -->
</dependency>
------------------------------------------------------------

== URI format

[source]
----
knative:type/name[?options]
----

You can append query options to the URI in the following format:

[source]
------------------------------------------------------------
?option=value&option=value&...
------------------------------------------------------------

== Options

// component options: START
The Knative component supports 18 options, which are listed below.



[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
| *ceOverride* (common) | CloudEvent headers to override |  | Map
| *cloudEventsSpecVersion* (common) | Set the version of the cloudevents spec. The value can be one of: 0.1, 0.2, 0.3, 1.0 | 1.0 | String
| *cloudEventsType* (common) | Set the event-type information of the produced events. | org.apache.camel.event | String
| *configuration* (common) | Set the configuration. |  | KnativeConfiguration
| *consumerFactory* (common) | The protocol consumer factory. |  | KnativeConsumerFactory
| *environment* (common) | The environment |  | KnativeEnvironment
| *environmentPath* (common) | The path ot the environment definition |  | String
| *filters* (common) | Set the filters. |  | Map
| *producerFactory* (common) | The protocol producer factory. |  | KnativeProducerFactory
| *serviceName* (common) | The name of the service to lookup from the KnativeEnvironment. |  | String
| *transportOptions* (common) | Set the transport options. |  | Map
| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
| *replyWithCloudEvent* (consumer) | Transforms the reply into a cloud event that will be processed by the caller. When listening to events from a Knative Broker, if this flag is enabled, replies will be published to the same Broker where the request comes from (beware that if you don't change the type of the received message, you may create a loop and receive your same reply). When this flag is disabled, CloudEvent headers are removed from the reply. | false | boolean
| *reply* (consumer) | If the consumer should construct a full reply to knative request. | true | Boolean
| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing. | false | boolean
| *apiVersion* (advanced) | The version of the k8s resource referenced by the endpoint. |  | String
| *basicPropertyBinding* (advanced) | Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean
| *kind* (advanced) | The type of the k8s resource referenced by the endpoint. |  | String
|===
// component options: END

// endpoint options: START
The Knative endpoint is configured using URI syntax:

----
knative:type/name
----

with the following path and query parameters:

=== Path Parameters (2 parameters):


[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
| *type* | The Knative resource type. The value can be one of: endpoint, channel, event |  | Type
| *name* | The name that identifies the Knative resource |  | String
|===


=== Query Parameters (17 parameters):


[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
| *ceOverride* (common) | CloudEvent headers to override |  | Map
| *cloudEventsSpecVersion* (common) | Set the version of the cloudevents spec. The value can be one of: 0.1, 0.2, 0.3, 1.0 | 1.0 | String
| *cloudEventsType* (common) | Set the event-type information of the produced events. | org.apache.camel.event | String
| *environment* (common) | The environment |  | KnativeEnvironment
| *filters* (common) | Set the filters. |  | Map
| *serviceName* (common) | The name of the service to lookup from the KnativeEnvironment. |  | String
| *transportOptions* (common) | Set the transport options. |  | Map
| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
| *replyWithCloudEvent* (consumer) | Transforms the reply into a cloud event that will be processed by the caller. When listening to events from a Knative Broker, if this flag is enabled, replies will be published to the same Broker where the request comes from (beware that if you don't change the type of the received message, you may create a loop and receive your same reply). When this flag is disabled, CloudEvent headers are removed from the reply. | false | boolean
| *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
| *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. The value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
| *reply* (consumer) | If the consumer should construct a full reply to knative request. | true | Boolean
| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing. | false | boolean
| *apiVersion* (advanced) | The version of the k8s resource referenced by the endpoint. |  | String
| *basicPropertyBinding* (advanced) | Whether the endpoint should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean
| *kind* (advanced) | The type of the k8s resource referenced by the endpoint. |  | String
| *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
|===
// endpoint options: END


== Supported Knative resources

The component support the following Knative resources you can target or exposes using the `type` path parameter:

- **channel** allow producing or consuming events to or from a https://knative.dev/docs/eventing/channels/[**Knative Channel**]
- **endpoint** allow exposing or targeting serverless workloads using https://knative.dev/docs/serving/spec/knative-api-specification-1.0/#service[**Knative Services**]
- **event** allow producing or consuming events to or from a https://knative.dev/docs/eventing/broker[**Knative Broker**]

== Knative Environment

As the Knative component hides the technical details of how to communicate with Knative services to the user (protocols, addresses, etc.), it needs some metadata that describe the Knative environment to set-up the low level transport details. In order to do so, the component needs a so called `Knative Environment` which is essence is a Json document made by a number of `service` elements which looks like the below example:

[source,json]
------------------------------------------------------------
{
    "services": [
        {
             "type": "channel|endpoint|event", <1>
             "name": "", <2>
             "metadata": {
                 "service.url": "http://my-service.svc.cluster.local" <3>
                 "knative.event.type": "", <4>
                 "camel.endpoint.kind": "source|sink", <5>
             }
        }, {
            ...
        }
    ]
}
------------------------------------------------------------
<1> the type of the Knative resource
<2> the name of the resource
<3> the url of the service to invoke (for producer only)
<4> the Knative event type received or produced by the component
<5> the type of the Camel Endpoint associated to this Knative resource (source=consumer, sink=producer)

The `metadata` fields has some additional advanced fields:

[width="100%",cols="1,5,3",options="header"]
|===
| Name | Description | Example
| *filter.*
| The prefix to define filters to be applied to the incoming message headers.
| ```filter.ce.source=my-source```

| *knative.kind*
| The type of the k8s resource referenced by the endpoint.
| ```knative.kind=InMemoryChannel```

| *knative.apiVersion*
| The version of the k8s resource referenced by the endpoint
| ```knative.apiVersion=messaging.knative.dev/v1beta1```

| *knative.reply*
| If the consumer should construct a full reply to knative request.
| ```knative.reply=false```

| *ce.override.*
| The prefix to define CloudEvents values that have to be overridden.
| ```ce.override.ce-type=MyType```

|===

== Knative Transport

As today the component only support `http` as transport as it is the only supported protocol on Knative side but the transport is pluggable by implementing the following interface:

[source,java]
----

public interface KnativeTransport extends Service {
    /**
     * Create a camel {@link org.apache.camel.Producer} in place of the original endpoint for a specific protocol.
     *
     * @param endpoint the endpoint for which the producer should be created
     * @param configuration the general transport configuration
     * @param service the service definition containing information about how make reach the target service.
     * @return
     */
    Producer createProducer(
        Endpoint endpoint,
        KnativeTransportConfiguration configuration,
        KnativeEnvironment.KnativeServiceDefinition service);

    /**
     * Create a camel {@link org.apache.camel.Producer} in place of the original endpoint for a specific protocol.
     *
     * @param endpoint the endpoint for which the consumer should be created.
     * @param configuration the general transport configuration
     * @param service the service definition containing information about how make the route reachable from knative.
     * @return
     */
    Consumer createConsumer(
        Endpoint endpoint,
        KnativeTransportConfiguration configuration,
        KnativeEnvironment.KnativeServiceDefinition service, Processor processor);
}
----

== Examples

[source,java]
----
CamelContext context = new DefaultCamelContext();

KnativeComponent component = context.getComponent("knative", KnativeComponent.class);
component.getConfiguration().setEnvironmentPath("classpath:knative.json"); // <1>

RouteBuilder.addRoutes(context, b -> {
    b.from("knative:endpoint/myEndpoint") // <2>
        .to("log:info");
});
----
<1> set the location of the `Knative Environment` file
<2> expose knative service
