-
Notifications
You must be signed in to change notification settings - Fork 6
Restructure examples into interactive/app/functions; add PTF examples #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Cole Bailey (colebaileygit)
wants to merge
2
commits into
master
Choose a base branch
from
sync/internal-examples-ftab-57
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Local configuration for running the examples: connection settings + secrets, provided as | ||
| # environment variables. This is the single place to configure a local run; it is loaded by | ||
| # bin/run.sh and bin/jshell.sh, and mirrors the variables a deployment platform injects in production. | ||
| # | ||
| # Setup: | ||
| # cp .env.template .env # then fill in real values (.env is git-ignored) | ||
| # | ||
| # To load it into a plain shell instead of via the scripts: | ||
| # set -a; . ./.env; set +a # (or: export $(grep -v '^#' .env | xargs), or a tool like direnv) | ||
|
|
||
| # --- Connection configuration from .properties resource (safe, non-secret) --- | ||
| # Where to find these values: README "Configure Table API Connection". | ||
| # Exact names, formats, and CLI equivalents: README "Configuration Options". All five are required. | ||
| FLINK_PROPERTIES=./src/main/resources/cloud.properties | ||
|
|
||
|
|
||
| # --- Alternative: specify via envvars directly --- | ||
| # Instead of the five variables above, you can keep them in a properties file and point FLINK_PROPERTIES at | ||
| # it. See README "Via Properties File". | ||
| # CLOUD_PROVIDER= | ||
| # CLOUD_REGION= | ||
| # ORG_ID= | ||
| # ENV_ID= | ||
| # COMPUTE_POOL_ID= | ||
|
|
||
| # --- Secrets (keep these out of any committed file) --- | ||
| # A single global (Cloud) API key covers both Flink access and artifact uploads. | ||
| # See README "Authentication" for all options. | ||
| GLOBAL_API_KEY= | ||
| GLOBAL_API_SECRET= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,3 +6,4 @@ target/ | |
| cloud.properties | ||
| dependency-reduced-pom.xml | ||
| *.env | ||
| .envrc | ||
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # Start a JShell session with the examples on the classpath and the connection | ||
| # config + secrets loaded from .env, so you can explore the Table API live. | ||
| # | ||
| # Usage: | ||
| # ./bin/jshell.sh | ||
| set -euo pipefail | ||
|
|
||
| # Always operate from the project root, regardless of where the script is invoked. | ||
| cd "$(dirname "$0")/.." | ||
|
|
||
| # Load .env (if present) so FLINK_PROPERTIES and the secret variables reach the JVM. | ||
| if [ -f .env ]; then | ||
| set -a | ||
| # shellcheck disable=SC1091 | ||
| . ./.env | ||
| set +a | ||
| fi | ||
|
|
||
| JAR="target/flink-table-api-java-examples-1.0.jar" | ||
| if [ ! -f "$JAR" ]; then | ||
| echo "Building $JAR ..." | ||
| ./mvnw -q clean package -DskipTests | ||
| fi | ||
|
|
||
| exec jshell --class-path "$JAR" --startup ./jshell-init.jsh |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # Run a Table API example locally. | ||
| # | ||
| # Loads connection config + secrets from .env (git-ignored) into the environment | ||
| # so the Confluent plugin picks up FLINK_PROPERTIES and the secret variables, | ||
| # builds the shaded jar if it is missing, then runs the chosen example class. | ||
| # | ||
| # Usage: | ||
| # ./bin/run.sh [ExampleClass] [program args...] | ||
| # | ||
| # Examples: | ||
| # ./bin/run.sh Example_00_HelloWorld | ||
| # ./bin/run.sh ReferenceApp_01_IntegrationAndDeployment --statement-name demo --on-conflict replace | ||
| set -euo pipefail | ||
|
|
||
| # Always operate from the project root, regardless of where the script is invoked. | ||
| cd "$(dirname "$0")/.." | ||
|
|
||
| # Load .env (if present) so FLINK_PROPERTIES and the secret variables reach the JVM. | ||
| if [ -f .env ]; then | ||
| set -a | ||
| # shellcheck disable=SC1091 | ||
| . ./.env | ||
| set +a | ||
| fi | ||
|
|
||
| EXAMPLE="${1:-ReferenceApp_01_IntegrationAndDeployment}" | ||
| [ $# -gt 0 ] && shift | ||
|
|
||
| JAR="target/flink-table-api-java-examples-1.0.jar" | ||
| if [ ! -f "$JAR" ]; then | ||
| echo "Building $JAR ..." | ||
| ./mvnw -q clean package -DskipTests | ||
| fi | ||
|
|
||
| # Examples live in two packages -- interactive/ (run inline and print) and app/ (deployable | ||
| # statements) -- plus TableProgramTemplate at the top level. Resolve the fully-qualified name from | ||
| # the jar so callers pass only the class name. The name is treated as a prefix, so "Example_02" | ||
| # resolves to "Example_02_UnboundedTables". Inner classes (those with a '$') are ignored. | ||
| # '|| true' keeps a no-match (unzip exits 11, grep -v exits 1) from tripping 'set -e' here, so the | ||
| # empty-result check below can report it instead of the script aborting silently. | ||
| MATCHES=$(unzip -l "$JAR" "io/confluent/flink/examples/$EXAMPLE*.class" \ | ||
| "io/confluent/flink/examples/*/$EXAMPLE*.class" 2>/dev/null \ | ||
| | awk '/\.class$/ {print $4}' \ | ||
| | grep -v '\$' \ | ||
| | sed 's#/#.#g; s#\.class$##' \ | ||
| | sort -u || true) | ||
|
|
||
| if [ -z "$MATCHES" ]; then | ||
| echo "Could not find an example class matching '$EXAMPLE' in $JAR" >&2 | ||
| exit 1 | ||
| fi | ||
| if [ "$(printf '%s\n' "$MATCHES" | wc -l)" -gt 1 ]; then | ||
| echo "'$EXAMPLE' is ambiguous; matches:" >&2 | ||
| printf '%s\n' "$MATCHES" | sed 's#.*\.# #' >&2 | ||
| echo "Please use a more specific name." >&2 | ||
| exit 1 | ||
| fi | ||
| CLASS="$MATCHES" | ||
|
|
||
| exec java -cp "$JAR" "$CLASS" "$@" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
src/main/java/io/confluent/flink/examples/app/ReferenceApp_01_IntegrationAndDeployment.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| package io.confluent.flink.examples.app; | ||
|
|
||
| import io.confluent.flink.plugin.ConfluentSettings; | ||
| import io.confluent.flink.plugin.ConfluentTableDescriptor; | ||
| import io.confluent.flink.plugin.ConfluentTools; | ||
|
|
||
| import org.apache.flink.table.api.DataTypes; | ||
| import org.apache.flink.table.api.EnvironmentSettings; | ||
| import org.apache.flink.table.api.Schema; | ||
| import org.apache.flink.table.api.Table; | ||
| import org.apache.flink.table.api.TableEnvironment; | ||
| import org.apache.flink.table.api.TableResult; | ||
|
|
||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| import static org.apache.flink.table.api.Expressions.$; | ||
| import static org.apache.flink.table.api.Expressions.lit; | ||
|
|
||
| /** | ||
| * An example that illustrates how to structure, test, and deploy a table program for production use | ||
| * in a CI/CD pipeline. | ||
| * | ||
| * <p>The example separates two concerns that often end up entangled: | ||
| * | ||
| * <ul> | ||
| * <li>The pipeline logic in {@link VendorsPerBrand} is plain Table API code without any | ||
| * Confluent-specific dependencies. It receives its input table as a parameter instead of | ||
| * resolving it from a catalog. This makes the logic executable on Apache Flink in local unit | ||
| * tests, where the input is mocked with {@code fromValues()} (see {@code | ||
| * ReferenceApp_01_IntegrationAndDeploymentTest}), as well as on Confluent Cloud for Apache | ||
| * Flink, where the input is a Kafka-backed table (see {@code | ||
| * ReferenceApp_01_IntegrationAndDeploymentIT}). | ||
| * <li>The {@link #main(String[])} method is the deployment entrypoint. It wires the pipeline to | ||
| * Confluent Cloud and submits it as a long-running background statement. | ||
| * </ul> | ||
| * | ||
| * <p>The program is configured with {@code ConfluentSettings.newBuilder().applyArgs(args)}: the | ||
| * builder starts from the environment (a {@code FLINK_PROPERTIES} properties file plus environment | ||
| * variables for secrets), and {@link ConfluentSettings.Builder#applyArgs(String[])} layers the | ||
| * per-deployment command-line arguments on top. This also enables the plugin's built-in CI/CD | ||
| * lifecycle actions: when the JAR is run with an action as the first argument ({@code list}, {@code | ||
| * describe}, {@code resume}, {@code stop}, or {@code delete}), the plugin executes the action and | ||
| * exits before the deployment logic runs, so the same JAR both deploys and manages (see {@code | ||
| * .github/workflows-examples/manage.yml}). | ||
| * | ||
| * <p>The application name is set in code as a default and can be overridden per deployment with | ||
| * {@code --application-name}. The statement name is deployment configuration passed via {@code | ||
| * --statement-name}, which the lifecycle actions use to target the right statement for both deploy | ||
| * and management. A program that submits several statements instead names each one in code via | ||
| * {@link ConfluentTools#setStatementName(TableEnvironment, String)}. | ||
| * | ||
| * <p>Re-running the deployment with unchanged code is idempotent. When the pipeline changed, pass | ||
| * {@code --on-conflict replace} to replace the existing statement; see the README's CI/CD section | ||
| * for what that means for stateful pipelines. The README also covers configuration, environment | ||
| * promotion, and the full set of workflow steps. | ||
| * | ||
| * <p>NOTE: This example requires write access to a Kafka cluster, selected with the {@code | ||
| * sql.current-catalog} (environment name) and {@code sql.current-database} (Kafka cluster name) | ||
| * configuration options. | ||
| * | ||
| * <p>ALSO NOTE: The example submits an unbounded background statement. Use the lifecycle actions | ||
| * (see {@code .github/workflows-examples/manage.yml}) or the Web UI to stop and delete the | ||
| * statement afterward to clean up resources. | ||
| */ | ||
| public class ReferenceApp_01_IntegrationAndDeployment { | ||
|
|
||
| private static final Logger LOG = | ||
| LoggerFactory.getLogger(ReferenceApp_01_IntegrationAndDeployment.class); | ||
|
|
||
| // Name of the table that stores the results | ||
| static final String TARGET_TABLE = "VendorsPerBrand"; | ||
|
|
||
| /** | ||
| * The pipeline logic under test: counts the number of vendors per brand. | ||
| * | ||
| * <p>This class must not reference any {@code io.confluent.flink.plugin} classes so that unit | ||
| * tests can run it on Apache Flink without the plugin on the classpath. | ||
| */ | ||
| public static class VendorsPerBrand { | ||
| public static Table buildPipeline(Table products) { | ||
| return products.groupBy($("brand")).select($("brand"), lit(1).count().as("vendors")); | ||
| } | ||
| } | ||
|
|
||
| // The main() method performs the deployment, unless an action argument is present, in which | ||
| // case applyArgs(...) records it and build() below executes that action and exits before the | ||
| // rest of this method runs. | ||
| public static void main(String[] args) { | ||
| // Connection settings come from the environment (a FLINK_PROPERTIES file for safe config | ||
| // plus environment variables for the API key and secret). The application name is defaulted | ||
| // in code here. The per-deployment arguments -- the statement name, the target catalog and | ||
| // database (sql.current-catalog / sql.current-database), any lifecycle action, and an | ||
| // optional --application-name override -- are layered on top with applyArgs. In GitHub | ||
| // Actions the secrets map to repository or environment secrets; see the README. | ||
| EnvironmentSettings settings = | ||
| ConfluentSettings.newBuilder() | ||
| .setApplicationName("vendors-per-brand") | ||
| .applyArgs(args) | ||
| .build(); | ||
| TableEnvironment env = TableEnvironment.create(settings); | ||
|
|
||
| LOG.info("Creating table... {}", TARGET_TABLE); | ||
| // The pipeline owns its output table and creates it on the first deployment. | ||
| env.createTable( | ||
| TARGET_TABLE, | ||
| ConfluentTableDescriptor.forManaged() | ||
| .schema( | ||
| Schema.newBuilder() | ||
| .column("brand", DataTypes.STRING().notNull()) | ||
| .column("vendors", DataTypes.BIGINT()) | ||
| .primaryKey("brand") | ||
| .build()) | ||
| .distributedInto(1) | ||
| .build(), | ||
| true); | ||
|
|
||
| LOG.info("Deploying statement..."); | ||
| // The same pipeline logic that was tested locally and against Confluent Cloud now runs | ||
| // unbounded on the continuously generated rows of the examples catalog. | ||
| ConfluentTools.setStatementName(env, "pipeline"); | ||
| Table products = env.from("`examples`.`marketplace`.`products`"); | ||
|
colebaileygit marked this conversation as resolved.
|
||
| TableResult result = | ||
| VendorsPerBrand.buildPipeline(products).insertInto(TARGET_TABLE).execute(); | ||
|
|
||
| // Print the final submitted name (application prefix included) for use with the lifecycle | ||
| // actions. If no name was configured, the plugin generates one, which is not addressable | ||
| // for later management; CI/CD deployments should always pass --statement-name. | ||
| LOG.info("Statement has been deployed as: {}", ConfluentTools.getStatementName(result)); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what version is this changed?