[[overview]]

This section provides you with a detailed overview of the out-of-the-box Spring Cloud Stream Applications.
It assumes familiarity with general Spring Cloud Stream concepts, which you can find in the Spring Cloud Stream https://docs.spring.io/spring-cloud-stream/docs/{scst-core-version}/reference/html/[reference documentation].

These Spring Cloud Stream Applications provide you with out-of-the-box Spring Cloud Stream utility applications that you can run independently or with Spring Cloud Data Flow. They include:

* Connectors (sources, processors, and sinks) for a variety of middleware technologies, including message brokers, storage (relational, non-relational, filesystem).
* Adapters for various network protocols.
* Generic processors that you can customize with https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/expressions.html[Spring Expression Language (SpEL)] or by scripting.

You can find a detailed listing of all the applications and their options in the following sections of this guide.

Most of these applications are based on core elements that are exposed as a `java.util.function` component.
You can learn more about these foundational components and how they are all connected to the applications by reading this https://github.com/spring-cloud/stream-applications/blob/master/README.adoc[README].

== Pre-built Applications

Out-of-the-box applications are Spring Boot applications that include a https://docs.spring.io/spring-cloud-stream/docs/{scst-core-version}/reference/html/spring-cloud-stream.html#spring-cloud-stream-overview-binders[binder implementation] on top of the basic logic of the app (a function for example) -- a fully functional uber-jar.
These https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/getting-started.html#getting-started-first-application-executable-jar[uber-jars] include the minimal code required for standalone execution.
For each function application, the project provides a prebuilt version for Apache Kafka and Rabbit MQ Binders.

[NOTE]
Prebuilt applications are generated according to the https://github.com/spring-cloud/spring-cloud-dataflow-apps-plugin/tree/master/spring-cloud-dataflow-apps-generator-plugin[stream apps generator Maven plugin].

[[classification]]
== Classification

Based on their target application type, they can be either:

* A _source_ that connects to an external resource to poll and receive data that is published to the default "`output`" channel;
* A _processor_ that receives data from an "`input`" channel and processes it, sending the result on the default "`output`" channel;
* A _sink_ that connects to an external resource to send the received data to the default "`input`" channel.

The prebuilt applications follow a naming convention: `<functionality>-<type>-<binder>`. For example, `rabbit-sink-kafka` is a _Rabbit sink_ that uses the Kafka binder that is running with Kafka as the middleware.

=== Maven Access

The core functionality of the applications is available as functions.
See the https://github.com/spring-cloud/stream-applications/tree/master/functions[Java Functions] section in the `stream-applications` repository for more details.
Prebuilt applications are available as Maven artifacts.
You can download the executable jar artifacts from the Spring Maven repositories.
The root directory of the Maven repository that hosts release versions is https://repo.spring.io/release/org/springframework/cloud/stream/app/.
From there, you can navigate to the latest released version of a specific app.
If you want to use functions directly in a custom application, those artifacts are available under the directory structure `org/springframework/cloud/fn`.
You need to use the link:https://repo.spring.io/release/org/springframework/cloud/stream/app[Release], link:https://repo.spring.io/milestone/org/springframework/cloud/stream/app[Milestone] and link:https://repo.spring.io/snapshot/org/springframework/cloud/stream/app[Snapshot] repository locations for Release, Milestone and Snapshot executable jar artifacts respectively.

=== Docker Access

The Docker versions of the applications are available in Docker Hub, at `https://hub.docker.com/r/springcloudstream/`.
Naming and versioning follows the same general conventions as Maven -- for example:

====
[source,bash]
----
docker pull springcloudstream/cassandra-sink-kafka
----
====

The preceding command pulls the latest Docker image of the _Cassandra sink_ with the Kafka binder.

=== Build

You can build everything from the root of the repository.

`./mvnw clean install`

This is a long build and you may want to skip tests:

`./mvnw clean install -DskipTests`

However, this may not be what you are interested in doing since you are probably interested in a single application or a few of them.
In order to build the functions and applications that you are interested in, you need to build them selectively as shown below.

=== Building the root parent

First, we need to build the parent used in various components.

`./mvnw clean install -f stream-applications-build`

==== Building functions

`./mvnw clean install -f functions -DskipTests`

You can also build a single function or group of functions.
For e.g if you are only interested in jdbc-supplier and log-consumer, do the following.

`./mvnw clean install -pl :jdbc-suppler,:log-consumer`

==== Building core for Stream Applications

`./mvnw clean install -f applications/stream-applications-core -DskipTests`

=== Building the applications

Let's assume that you want to build JDBC Source application based on Kafka Binder in Spring Cloud Stream and Log Sink application based on Rabbit binder.
Here is what you need to do.
Assuming you built both functions and stream-applications-core as above.

```
./mvnw clean package -pl :jdbc-source
cd applications/source/jdbc-source/apps/jdbc-source-kafka
./mvnw clean package
```

This will generate the Kafka binder based uber jar in the target folder.

Similarly for the log sink, do the following.

```
./mvnw clean package -pl :log-sink
cd applications/sink/log-sink/apps/log-sink-rabbit
./mvnw clean package
```

==== Building a Docker image
The apps use the https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin[Jib Maven Plugin] to build and publish the Docker image.
If you have made some changes to an app, you may want to build the image and test it locally.

NOTE: If you plan to use the image with minikube, run the following command before building the image:

```
eval $(minikube docker-env)
```

To build the image in your local registry:

```
./mvn clean package jib:dockerBuild
```


To publish the image to a remote registry:

```
jib:build \
    -Djib.to.image=myregistry/myimage:latest \
    -Djib.to.auth.username=$USERNAME \
    -Djib.to.auth.password=$PASSWORD
```

== Patching Pre-built Applications

=== Adding new dependencies

If you are looking to patch the pre-built applications to accommodate the addition of new dependencies, you can use the following example as the reference.
To add `mysql` driver to `jdbc-sink` application:

1. Clone the GitHub repository at https://github.com/spring-cloud/stream-applications
2. Find the module that you want to patch and add the additional dependencies, `jdbc-sink` in this case. For example, you can add the following mysql dependency to the application generator plugin's configuration in the pom.xml:

```
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.37</version>
  </dependency>
```
This is how the complete plugin configuration should look like.
```
 <plugin>
    <groupId>org.springframework.cloud.stream.app.plugin</groupId>
    <artifactId>spring-cloud-stream-app-maven-plugin</artifactId>
    <configuration>
        <generatedApp>
            <name>jdbc</name>
            <type>sink</type>
            <version>${project.version}</version>
            <configClass>org.springframework.cloud.fn.consumer.jdbc.JdbcConsumerConfiguration.class</configClass>
        </generatedApp>
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.37</version>
              </dependency>
            <dependency>
                <groupId>org.springframework.cloud.fn</groupId>
                <artifactId>jdbc-consumer</artifactId>
                <version>${java-functions.version}</version>
            </dependency>
        </dependencies>
    </configuration>
</plugin>
```

Once the above changes are done, you can generate the binder based apps as below from the root of the repository.

```
./mvnw clean install -pl :jdbc-sink
```

This generates the binder based applications in the `apps` folder under `jdbc-sink` folder.
In order to build the app with the binder flavor that you are interested in, you need to do the following step.

```
cd applications/sink/jdbc-sink
cd apps/jdbc-sink-kafka (or Rabbit if you are interested in that)
./mvnw clean package
cd target
```

There you will find the binder based uber jar with your changes.

=== Update existing dependencies or add new resources in the application

Modifying the plugin as above work when there are new dependencies to add to the application.
However, when we need to update any existing dependencies, it is easier to make the maven changes in the generated application itself.
If we have to update the binder dependencies from a new release of Spring Cloud Stream for example, then those versions need to be updated in the generated application.

Here are the steps (again, we are using `jdbc-sink-kafka` as an example).

```
./mvnw clean install -pl :jdbc-sink
cd applications/sink/jdbc-sink/apps/jdbc-sink-kafka
```

Open the generated application's `pom.xml` and update the dependencies.
If there is a new version of Spring Cloud Stream update available that contains the enhancements we are looking for, then it is easier to update the BOM itself.
Find where the bom is declared in `pom.xml` and update the version.

For example, if we have to update Spring Cloud Stream to `Horsham.SR10`, this version must be specified in the BOM declaration as below:

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-dependencies</artifactId>
            <version>Horsham.SR10</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
```

We can also update any individual dependencies directly, but it is preferred to use the above `dependencyManagement` approach if there is a BOM available.
This is because, when using a BOM, maven will properly use and align any transitive dependencies.

If you have to modify the application further, this method of modifying the generated application is again the recommended approach.

For instance, if you want to add security certificate files such as a key store, or a trust store to the application's classpath, then generate the application first and add those resources to the classpath.

Make sure you are in the generated `jdbc-sink-kafka` folder, then do the following:

First, add the resources to the classpath by placing them under `src/main/resources`.

Then rebuild the application.

```
./mvnw clean package
cd target
```

Here you can find the modified application jar file.

== Generating out of the box applications for other binders

By default, we only provide out of the box applications for Apache Kafka and RabbitMQ binders.
There are other binder implementations exist, for which we can generate these same out of the box applications.
For example, if one wants to generate these applications for the https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis[Kinesis binder], or the https://github.com/SolaceProducts/spring-cloud-stream-binder-solace[Solace binder], or https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder[Google gcp pubsub binder] etc. it is possible to do so by following the instructions below.

As a first step, clone the https://github.com/spring-cloud/stream-applications[stream applications] repository.

cd applications/stream-applications-core

We need to edit the pom.xml in this module.
Find the following configuration where it defines the Kafka and RabbitMQ binders for the maven plugin.

```
<kafka>
    <maven>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-stream-binder-kafka</artifactId>
            </dependency>
        </dependencies>
    </maven>
</kafka>
<rabbit>
    <maven>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
            </dependency>
        </dependencies>
    </maven>
</rabbit>
```

Add the binder for which you want to generate new apps for.
For example, if we want to generate applications for the https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis[Kinesis binder], then modify as below.

```
<binders>
    <kafka>
        <maven>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-stream-binder-kafka</artifactId>
                </dependency>
            </dependencies>
        </maven>
    </kafka>
    <rabbit>
        <maven>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
                </dependency>
            </dependencies>
        </maven>
    </rabbit>
    <kinesis>
        <maven>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-stream-binder-kinesis</artifactId>
                    <version>2.0.3.RELEASE</version>
                </dependency>
            </dependencies>
        </maven>
    </kinesis>
</binders>
```

Note that, we need to use the Kinesis binder version here explicitly, while both Kafka and RabbitMQ do not need them.
This is because, those versions come from a dependency management while the Kinesis binder is not available through such mechanisms.
Therefore, we need to explicitly use the binder version.
If we have a BOM available that defines the version, then that can be used instead, just ensure that is declared in the proper BOM section of the maven plugin.

If the binder for which you are generating the applications relies on a different version of Spring Cloud Stream, make sure it is updated in the maven properties.

Now, we can build: `./mvnw clean install -DskipTests`.

If we go to the applications folder and look at the generated applications, we should see the new binder variants there.
For instance, if we follow the configuration above for adding the Kinesis binder, then we should see the Kinesis binder based app in the generated apps.
Let's take `time-source` as an example.

```
cd applications/source/time-souce/apps
```

Here, we should see three different binder based apps projects - `time-source-kafka`, `time-source-rabbit` and `time-source-kineses`.
Similarly, this should happen for all the out of the box application projects.

Keep in mind that, these generated applications further need to be built individually.
For that, go to the generated applications folder and then initiate a maven build.

